Thursday, July 12, 2007

HP Open View Service Desk web-api maybe long, but isn't Long

If the title of this blog is confusing, you may also find this blog confusing not because the content is confusing, but because you won't be able to understand what the developers that designed web-api were thinking. HP Open View Service Desk (OVSD) web-api is a set of java api's that have little to do with the web as far as I can tell. It is an api for OVSD that is implemented in Java and jarred. No big deal there, just a strange name. OVSD has a concept of OID and ID for some records like Service Calls. ID is what the unique id that is shown in the UI that end users use. OID is the unique ID that is used in Oracle for relationships. My big conundrum is what were the developers thinking when they created two methods to open (find and load) and service call. The two methods are called openServicecall(). It is overloaded to accept a Long or a long. Long is an object in Java, and long is a primitive in Java. Very different things. One might think that the developers were nice and just provided the ability to pass either an object or primitive. This would make sense, but is not what they did. They made long mean ID and Long mean OID. Only place to get that is in the documentation. Below is the correct snippet for opening a service call by ID (the end user value). ApiSDSession session = null; try { session = ApiSDSession.openSession(server, username, password); IServicecallHome scHome = session.getServicecallHome(); long id = 123456; // NOTE: long MUST be used, NOT Long IServicecall serviceCall = scHome.openServicecall(id); } catch (Exception ex) { // handle exception here } finally { session.closeConnection(); } I hope this saves someone hours of frustration.

23 comments:

mir said...

This post doesn't save my "someone hours of frustration" but make my code simpler.

Thanks.

mir said...

Hi.

Do you have some docs about OVSD web-api? I can't create ApprovalVote and have no idea how to solve problem.

Brent V said...

I just have the docs that come with HP OpenView Service Desk CD. Sorry, I have never used the ApprovalVote. What is the problem you are having exactly. Please provide sample code and error message.

mir said...

These docs I have too. They are very scant.

Let's look my code.
This code throws exception like (in russian) "You have no permissions to input this data: vote" in last line:
IServicecallHome scHome = session.getServicecallHome();
IServicecall sc = scHome.openNewServicecall();

IApprovalVoteHome voteHome = session.getApprovalVoteHome();
IApprovalVote vote = voteHome.openNewApprovalVote();

So I can't just create a vote!
But if to swap creation of servicecall and vote, code doesn't throw exception:
IApprovalVoteHome voteHome = session.getApprovalVoteHome();
IApprovalVote vote = voteHome.openNewApprovalVote();

IServicecallHome scHome = session.getServicecallHome();
IServicecall sc = scHome.openNewServicecall();

But throws exception then I try to add vote to Approval:
sc.getApproval().addApprovalVote(vote);


While writing this post I find solution!! Full code:
IApprovalVoteHome voteHome = session.getApprovalVoteHome();
IApprovalVote vote = voteHome.openNewApprovalVote();

IServicecallHome scHome = session.getServicecallHome();
IServicecall sc = scHome.openNewServicecall();

vote.setApprover(person);
vote.setApproved(true);
vote.setReason("ok");

sc.setApprovalInitiator(person);

sc.setConfigurationItem(session.getConfigurationItemHome().openConfigurationItem(new Long(...L)));
sc.setCaller(person);
sc.getAssignment().setAssigneePerson(person);
sc.getAssignment().transfer();

sc.setDescription("descr.");

sc.save();

vote.setApproval(sc);
vote.save();

Wow! It last!
Thanks :)

Brent V said...

I am glad you figured it out. Good job! I had a similar experience on one of the other properties I was trying set. It seems that OVSD has in some cases two methods (one on each object) to "connect" to objects and only one of them works. It is also worth mentioning that UI business rules setup in OVSD can cause exceptions also. Depending on how complex your UI business rules are the order that you set the values can impact if you get an exception also. Very frustrating from a developers standpoint. HP would probably say it is designed that way, I call if buggy. ;)

mir said...

Yes, some OVSD api design solutions... not obvious (at the least) and sometimes like bugs.

I never understand why in this case was used so ugly method to add Vote to Approval.

Abdul said...

Could some please share with me the api and a sample code to create a service call in OVSD.

Brent V said...

Hi Abdul,

It is not possible to give you code that will work on your system because HP OpenView allows administrators to define UI and DB rules that affect what fields are required, business rules, etc. However, the here is some basic code that will hopefully get you started. The easiest way is to just run this and see what exceptions are thrown it is pretty easy to tell what to do from that.

IServicecallHome scHome = session.getServicecallHome();
IServicecall sc = scHome.openNewServicecall();
sc.setDescription("description here");
sc.save();

rjs said...

Hi,

I am using the web-api, and trying to get the full path of the Category of a CI. E.g. For a Business PC CI I want to retreive the full Category path: Hardware/System/Business PC

First I thought there would be such a method in the api, but I could not find any.

So I tried to derive the path from the CIs ICICategory parent:

/**
* Gets the full path given the ciCategory
* @param ciCategory
* @return the Category string if found, null otherwhise.
*/
private String getFullCICategorypath(ICICategory ciCategory){
String reply = ciCategory.getText();
IKernelCodeHierarchical parentCode = ciCategory.getParentCode();
// IKernelCodeHierarchicalWhere iKernelCodeHierarchicalWhere = new IKernelCodeHierarchicalWhere();
ICICategoryWhere catWhere = catHome.createCICategoryWhere();
catWhere.addCriteriumOnParentCode(parentCode);
ICICategory parentCategory1 = catHome.findCICategory(catWhere)[0];

ICICategory[] findCICategory = catHome.findCICategory(catWhere);

log.debug("Found the following categories for category " + ciCategory.getText());
for (ICICategory category : findCICategory) {
log.debug(category.getText());
}

if(parentCategory1==null){
log.debug("ciCategory "+ ciCategory.getText() + " has no more parents. Level 1.");
return reply;
}

//Repeat until no more parents are found (Could use recursion here, but since we know the tree has max 4 levels we just keep checking until no more parents)
//second level
catWhere = catHome.createCICategoryWhere();
catWhere.addCriteriumOnParentCode(parentCategory1.getParentCode());
ICICategory parentCategory2 = catHome.findCICategory(catWhere)[0];
if(parentCategory2==null){
log.debug("ciCategory "+ ciCategory.getText() + " has no more parents. Level 2.");
return null;
}else{
reply = parentCategory2.getText() + "/" + reply;
}
//third level
catWhere = catHome.createCICategoryWhere();
catWhere.addCriteriumOnParentCode(parentCategory2.getParentCode());
ICICategory parentCategory3 = catHome.findCICategory(catWhere)[0];
if(parentCategory3==null){
log.debug("ciCategory "+ ciCategory.getText() + " has no more parents. Level 3.");
return reply;
}else{
reply = parentCategory3.getText() + "/" + reply;
}




log.debug("ciCategory " + ciCategory.getText() +" has parentCode " + reply);

return reply;

}


But the catWhere.addCriteriumOnParentCode(parentCode);
seems to retreieve the siblings not the parents.

Any tips is highly appreciated.

Brent V said...

Hi rjs,

I must say I am surprised as well that the parent is actually the sibling. I remember there being some weirdness (sorry don't remember the actual issues(s)) with getting the path to the CI. I do recall doing something similar to what you did though. I suspect there is a bug somewhere in your code. Just an unfounded guess though. :)

Thanks for dropping by.

Brent

mir said...

Hi rjs,

But the catWhere.addCriteriumOnParentCode(parentCode);
seems to retreieve the siblings not the parents.


It's ablosutely Ok. Because this method adds a criterium on the property "ParentNode" of the nodes. So the query will return the children of the parentCode.


Regards,
Dmitry.

Anonymous said...

Hi,

You can use this method to make the full Category path.

public static String getFullPathCategory(ICICategory category){
String cat = null;

IKernelCodeHierarchical parent = category.getParentCode();
for(int i=0; i<6;i++){

if(parent!=null){
if(cat!=null)
cat = parent.getText() + " \\ " + cat;
else
cat = parent.getText();

parent = parent.getParentCode();
}
}
System.out.println("Path:"+ cat);
return cat;
}

rjs said...

Thanks for your replies, and a good solution.

I am currently trying to get the name and value of all the attributes for a CI. I was hoping that the IConfigurationItem would have a getter for this, e.g. getAllAttributes(),but it does not. I would avoid calling each individual getter for each attribute as there are MANY.

Is it possible to do this via the IAttributesPerStatusHome?

I am considering reflection to call the getters, but I would rather not.

Any ideas on have to achieve is highly appreciated.

Regards
Runar

Brent V said...

Hi rjs,

I don't have much experience with Configuration Items (CI). If you find a good solution, please post your finds.

Thanks,

Brent

Brent V said...

Hi rjs,

The session in HP OpenView api is not very good in my opinion. In earlier version it was very buggy. There is no way to renew a session that I am aware of. I believe that it can timeout at most anytime, which can be frustrating.

I suggest verifying that you are closing the session after every use. I also recommend you use a named license instead of a regular license that is not guaranteed a connection. It does make a difference in reliability. And finally, make sure your HP OpenView server is running the latest possible version of the api, and make sure you are using the same one for your report. You can check the version as I describe here.

I hope that helps.

Brent

rjs said...

Hi Brent V,

thanks for your reply. Regarding the session stability, I find the connection quite good. It is only when I try to get all the incidents or service calls of a CI and do this for allot of CIs the api closes the connection and returns the timeout message. This message from the api is not precise, as I suspect it has something to do with max-rows and Query size. Have you any similar experiences? Thanks again for your feedback.

Brent V said...

Hi rjs,

I don't have any specific experience with CI's with regard to the api, but other people I know have not had trouble with CI's. However, I don't think we were trying to get service calls or incidents from a CI. Sorry I couldn't be of more assistance.

Please post back, if you figure something out.

Regards,

Brent

Thiago said...

Do you guys have any idea how to create a service call and assign a category to it?
For instance:
...
IServicecall s = scHome.openNewServiceCall();
s.setCategory(category_arg);

where category_arg is a IServiceCallCategory.

What really matters is how do I get a IServiceCallCategory from web-api.jar?

Thanks in advance.

Brent V said...

Thiago,

I would look at ICategoryHome and more specifically, I would look at IServiceCallCategoryHome. Whenever you need to find stuff there is usually a xxxHome class that give you the ability to do searches.

I hope that helps.

Brent

Thiago said...

Brent,

That was a really good suggestion. Thank you.

The following code retrieves all service call categories:

IServiceCallCategoryHome iservcallcathome = session.getServiceCallCategoryHome();
IServiceCallCategory[] iservcallcat = iservcallcathome.findAllServiceCallCategory();

for( int i=0; i < iservcallcat.length; i++ )
System.out.println( iservcallcat[i].getText() );

It's almost the same code to get the classification ( IClassificationSer ).

Now the question is: how to validate or get the Configuration Item field? Does anybody have any hint?

pashtet said...

How to get extended attributes of ConfigurationItem. Such as "model" etc.

Thanks

Anonymous said...

Please help me where i can get reference how to develop on HP OpenView with Java. thanks.

mabs said...

I have to open an existing incident. I'm getting problem in establishing a session using ApiSDSession. However found a class "Session" in "Web API Programmer’s Guide" that connects with server successfully. Unfortunately the method details are not available for "Session" class. Any way to find out the documentation? Is the "Session" class a good substitute for "ApiSDSession"?