Monday, June 30, 2008

101st Posting

Well, I did it! I have written 100 entries in my blog so far. I never thought I would get so many. I guess I can look forward to 200 someday. Yeah!!!!!!

Friday, June 27, 2008

A safe way to save entities in HP OpenView Service Desk (OVSD) web-api

If you have have worked with HP OpenView Service Desk (OVSD) web-api, you may have noticed sometimes it throws an exception that says "There are no changes to save." when you call the save() method on entities such as Servicecall, Workorder, Change, etc. This is annoying and fairly useless thing to know if you ask me. This should not be an exception in my opinion if you call save too often, especially since the api doesn't support transactions. Instead of repeating the same try catch blocks everywhere in my code, it became obvious to me that the safest thing to do is to just write a very simple method to call instead of the standard save() method on an entity. What the method below does is allows you to pass virtually any type of entity from HPOV web-api objects that have a save() method or more specifically inherit from IApiEntity object (this is at least all the major ones). Now instead of ... myServiceCallObject.save(); just call the method and pass it the object you want to save. SaveEntity(myServiceCallObject); This is clean and reduces unexpected bugs caused by this "exception" :) private void SaveEntity(IApiEntity entity) throws Exception { try{ entity.save(); } catch (Exception ex) { if (!ex.getMessage().equalsIgnoreCase("There are no changes to save.")) { throw ex; } } }

HP OpenView Service Desk Web-api saves when you don't expect it to.

To be fair, I have not looked in the documentation of the HP OpenView web-api docs, but I can't believe that records can be saved without called .save() method on an object. How you ask, here is an example in pseudo-code.
IWorkorder myNewWorkOrder = WorkOrderHome().openNewWorkorder(); IServicecall myExistingServiceCall = ServiceCallHome().openServicecall(1234l); // no work order will exist and will not be related to the service call before the call to the next line myExistingServiceCall.addWorkorder(myNewWorkOrder); // after the above call, the work order exists, and IS related to the service call. I could not believe it, but this is true. A word of caution if you mean to not save in all cases.

Thursday, June 26, 2008

HP OpenView template field returns null from Web-api

I tried to come up with a title for this that made sense, but it is just a weird problem really. I thought there was a bug in HP OpenView, but I am now confident it is a configuration issue. Here is the behavior I saw that will help explain what the issue is. I have a work order (though this issue is not specific to work orders I suspect) template. I have set the assigned to workgroup to a workgroup that happens to be inactive. Obviously I would not do this on purpose. Actually someone made the workgroup inactive and didn't know that the template was using it and should be updated. The issue is that when you create a work order using this template it shows the value of the assigned to workgroup field as blank (in the HP OpenView Service Desk Client) or null (in the case of the Java web-api. If you know that inactive workgroups show as blank or null then there is no problem. However, it is VERY frustrating when in the template you see a workgroup set, and in the UI and web-api call you see blank or null respectively. It just doesn't make sense without knowing this quirk. So, I hope this helps others. One other caveat to this is that IF the assigned to person is specified in the template then (at least with our business rules, I don't know if this is default behavior) the assigned to workgroup is changed to the workgroup of the assigned to person assuming that the workgroup is inactive. This was the main confusing part. We removed the assigned to person, and started getting validation errors that said the assigned to workgroup was null. So, while they seem unrelated, they are related in particular circumstances.
Good luck to all.

Monday, June 23, 2008

Screen Capture Tool

I often need to take screen shots of particular regions of the screen. For example maybe the content of a web page, but I don't want the browser window to be showing in the image. Sometimes, I want the entire window, sometimes I don't. I found a nice screen capture utility called Cropper that when you launch it it goes to your system tray. You can invoke it with a hotkey. In fact you can set up different hotkeys for the different kind of capture you want to do. For example you can have one for full screen capture, and another that captures a custom area you select. There are not ads. In fact it is Open Source and written in C#. You can download it from CodePlex (http://www.codeplex.com/cropper). You can send the output to the four basic image formats, the printer, or clipboard. I particularly like clipboard since I am usually pasting it in an email or MS Word document.If you are a programmer, you can even extend it using by writing your own plug-ins. The only downside I see is that it takes about 8MB or RAM, and about 19 of virtual memory. In this day an age of MS .NET programs that is about average from what I can tell.

Sunday, June 8, 2008

Sharing iPhoto Library between users

I recently started using Mac OS X again. I haven't used it since it first came out. I really like what I am seeing so far. However, I quickly found out that iPhoto is set up by default to have individual Libraries for iPhoto. This is not what I want. I want for me to be able to update the iPhoto Library and my wife to be able to update the same iPhoto Library when she logs into the computer. The reason is simple. We use iPhoto for the entire family. We don't keep individual copies. That seems insane to me.

You can always try this method, but I don't like it. You can hold down the option key when you click iPhoto on the Dock. This will have iPhoto ask you to Create a new Library or Choose an Existing Library. You should be able to create it in /Users/Shared/Pictures/iPhoto Library, and then for the other user point it to the same location instead of creating a new one. I have not tested this, but I expect it would work.

The thing is, I still wanted all things to appear to iPhoto and other applications that I am using my own iPhoto Library and see it in the /Users/Shared/user1/Pictures/iPhoto Library directory. I don't know if there is a good reason, but it seems like there will be less trouble in the future.

To accomplish this we can take advantage of what is called a symbolic link. It is different than the Alias feature in OS X.

Create a symbolic link each Pictures directory that points to the iPhoto Library for the Shared user.

Here is a sample of what you will need to do, probably from the root account

mkdir /Users/Shared/Pictures/iPhoto\ Library


sudo ln -s /Users/Shared/Pictures/iPhoto\ Library/ /Users/user1/Pictures/iPhoto\ Library


sudo ln -s /Users/Shared/Pictures/iPhoto\ Library/ /Users/user2/Pictures/iPhoto\ Library


NOTE: The example above has a space in the directory name. When using the shell, a back slash is need before the space to escape it. Much like many programming languages.

After that you will need to make sure user1 and user2 have Read / Write permissions on the /Users/Shared/Pictures/iPhoto Library directory. Otherwise, you will get permission or file locked error.

I'm sure there is a command to do this, but the UI makes it easy by getting info in Finder on the /Users/Shared/Pictures/iPhoto Library directory.

I would love feedback on this solution. I fiddled with the syntax to get it to work, and I think I got what I actually did written accurately here.