Using javax.xml.soap to access OTRS SOAP service without WSDL
For most of us who are frequently using WSDL to generate stub classes for accessing webservices, dealing with SOAP services without WSDL is painful. OTRS (Open source Ticket Request System) is one of them. One attempt by OpenNMS team has been quite successful on integrating OTRS by writing its own webservice as an OTRS plugin. However, this is not satisfactory in my opinion. We need a better way of doing it.
I have tried to find out the pattern of the SOAP messages being exchanged by the rpc-example.pl with my local installation of OTRS. Here is the process of the investigation and this attempt has successfully execute RPC on the OTRS and I have been able to retrieve the result.
First, I create a sample perl script to make a simple request to retrieve Ticket by TicketID. Here is the script:
Observing the output of the debug message, I found the SOAP request has the following pattern:
Note: I have modified the element name to make it easier to understand what the content supposed to be
Having looked at the pattern, I then wrote a sample Java code to access it. Here is my attempt:
Now, I believe someone should try to write a general purpose method/utility to call OTRS method using Java. I hope this would help anyone who encountered similar problem.
I have tried to find out the pattern of the SOAP messages being exchanged by the rpc-example.pl with my local installation of OTRS. Here is the process of the investigation and this attempt has successfully execute RPC on the OTRS and I have been able to retrieve the result.
First, I create a sample perl script to make a simple request to retrieve Ticket by TicketID. Here is the script:
#!/usr/bin/perl -w use SOAP::Lite ( 'autodispatch', proxy => 'http://localhost/otrs/rpc.pl', trace => 'all'); my $User = 'some_user'; my $Pw = 'some_pass'; my $RPC = Core->new(); my %Ticket = $RPC->Dispatch($User,$Pw,'TicketObject','TicketGet', TicketID=>1); print "$Ticket{TicketNumber}\n";Note: I set 'trace' property to 'all' to enable printing out every possible debugging message for SOAP::Lite API
Observing the output of the debug message, I found the SOAP request has the following pattern:
<SOAP:Envelope xmlns ... dst..dst> <soap:Body> <Dispatch xmlns="/Core"> <Username xsi:type="xsd:string">some_user</Username> <Password xsi:type="xsd:string">some_pass</Password> <Object xsi:type="xsd:string">TicketObject or other object </Object> <Method xsi:type="xsd:string">TicketGet or other method</Method> <Param1_Name xsi:type="xsd:string">fill in the param name</Param1_Name> <Param1_Value xsi:type="xsd:string/int">fill in the param value</Param1_Value> ... ... other params </Dispatch> </soap:Body> </SOAP:Envelope>
Note: I have modified the element name to make it easier to understand what the content supposed to be
Having looked at the pattern, I then wrote a sample Java code to access it. Here is my attempt:
import java.net.URL; import javax.xml.namespace.QName; import javax.xml.soap.MessageFactory; import javax.xml.soap.SOAPBody; import javax.xml.soap.SOAPBodyElement; import javax.xml.soap.SOAPConnection; import javax.xml.soap.SOAPConnectionFactory; import javax.xml.soap.SOAPEnvelope; import javax.xml.soap.SOAPMessage; import javax.xml.soap.SOAPPart; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; /** * * @author masjoko */ public class Main { /** * @param args the command line arguments */ public static void main(String[] args) throws Exception { // Create the connection SOAPConnectionFactory scf = SOAPConnectionFactory.newInstance(); SOAPConnection conn = scf.createConnection(); // Create message MessageFactory mf = MessageFactory.newInstance(); SOAPMessage msg = mf.createMessage(); // Object for message parts SOAPPart sp = msg.getSOAPPart(); SOAPEnvelope env = sp.getEnvelope(); env.addNamespaceDeclaration("xsd","http://www.w3.org/2001/XMLSchema"); env.addNamespaceDeclaration("xsi","http://www.w3.org/2001/XMLSchema-instance"); env.addNamespaceDeclaration("enc","http://schemas.xmlsoap.org/soap/encoding/"); env.addNamespaceDeclaration("env","http://schemas.xmlsoap.org/soap/envelop/"); env.setEncodingStyle("http://schemas.xmlsoap.org/soap/encoding/"); SOAPBody body = env.getBody(); SOAPBodyElement dispatch = body.addBodyElement(new QName("/Core","Dispatch")); dispatch.addChildElement("Username").addTextNode("some_user").setAttribute("xsi:type", "xsd:string"); dispatch.addChildElement("Password").addTextNode("some_pass").setAttribute("xsi:type", "xsd:string"); dispatch.addChildElement("Object").addTextNode("TicketObject").setAttribute("xsi:type", "xsd:string"); dispatch.addChildElement("Method").addTextNode("TicketGet").setAttribute("xsi:type", "xsd:string"); dispatch.addChildElement("Param1_Name").addTextNode("TicketID").setAttribute("xsi:type", "xsd:string"); dispatch.addChildElement("Param1_Value").addTextNode("1").setAttribute("xsi:type", "xsd:int"); URL url = new URL("http://localhost/otrs/rpc.pl"); SOAPMessage resp = conn.call(msg, url); Document doc = resp.getSOAPPart().getEnvelope().getBody().extractContentAsDocument(); Element el = doc.getDocumentElement(); NodeList nl = el.getChildNodes(); for (int i = 0 ; i<(nl.getLength()/2); i++) { System.out.println(nl.item(i*2).getTextContent().trim()+":"+nl.item(i*2+1).getTextContent().trim()); } } }The following output was shown:
Age:91060917 PriorityID:3 ServiceID: TicketFreeText11: TicketFreeTime4: TicketFreeTime1: TicketFreeText6: StateID:6 TicketFreeTime5: EscalationTime:0 TicketFreeTime6: TicketFreeKey9: OwnerID:1 Owner:root@localhost TicketFreeText7: TicketFreeKey11: Created:2007-03-08 16:26:39 TicketFreeText4: QueueID:4 TicketFreeText2: TicketFreeKey6: TicketID:1 TicketFreeKey5: TicketFreeText12: UnlockTimeout:1264399466 EscalationResponseTime:0 TicketFreeTime3: TicketFreeText3: CustomerUserID: TicketFreeText8: TicketFreeText9: Type:default TicketFreeKey7: Responsible:root@localhost TicketFreeText10: ResponsibleID:1 TicketFreeKey16: TicketFreeKey3: RealTillTimeNotUsed:1264485840 GroupID:1 TicketFreeKey13: CustomerID: TicketFreeKey1: TypeID:1 Priority:3 normal TicketFreeKey12: TicketFreeKey10: TicketFreeKey8: UntilTime:78924 TicketFreeText1: EscalationUpdateTime:0 TicketFreeTime2: Queue:Misc TicketFreeText13: State:pending reminder Title:Welcome to OTRS! TicketFreeText5: TicketFreeText15: TicketFreeText14: StateType:pending reminder EscalationSolutionTime:0 LockID:1 TicketFreeKey2: TicketNumber:1010001 TicketFreeKey14: Lock:unlock CreateTimeUnix:1173345999 TicketFreeKey4: SLAID: TicketFreeKey15: TicketFreeText16:
Now, I believe someone should try to write a general purpose method/utility to call OTRS method using Java. I hope this would help anyone who encountered similar problem.
Comments
I used this example to get data from OTRS tickets.
When i use ArticleAttachment method to get Article's HTML body stored in FileSystem it shows me some error.
Can you guide for this??
I want to get an array of tickets:
"dispatch.addChildElement("Param1_Name").addTextNode("TicketID").setAttribute("xsi:type", "xsd:string");
dispatch.addChildElement("Param1_Value").addTextNode("1, 2, 3").setAttribute("xsi:type", "xsd:int");"
But unfortunately it seems that I only get the first ticket back.
Can anyone help me?
Thanks.
Thanks
Jose