Download - How to Build a Java client for SugarCRM
Antonio Musarra's Blog Document Revision:1.0 The ideal solution for a problem Blog: http://www.dontesta.it
LinkedIn: http://it.linkedin.com/in/amusarra Google+: https://plus.google.com/+AntonioMusarra Mail: [email protected]
14/01/14 1 This document is issued with license Creative Commons Attribution-‐NonCommercial-‐ShareAlike
How to Build a Java client for SugarCRM
In this article I will show how to make/build/implement a Java due to access to the informations recorded on the CRM system, I will show also how to implement a simple Java application capable to use that client in order to execute some basic operations such as: login, contact creation, data retrieval. SugarCRM system (SugarCRM Inc., 2004) exposes to external systems some interface services for data access that support SOAP and REST protocols (SugarCRM Inc., 2010). SugarCRM version taken as reference here is Community Edition 6.1 (SugarCRM Inc., 2010).
The protocol considered here is SOAP, there are many ways to create a SOAP Java client able to communicate with a web service, maybe the simplest way is to use the mature Apache Axis framework (The Apache Software Foundation, 2011).
Apache Axis is an open source framework implementing a SOAP Engine, useful to create, publish and consume Java-‐based web services (moreover it supports C/C++ too). Apache Axis will help to create the Service SOAP Stub + Data Type starting from the WSDL document provided by SugarCRM. These are the steps I will follow to reach our goal:
• Generate the Java Stub with Apache Axis; • Compile the Java Stub as a Java library (jar); • Create the Java SugarCRMSOAPClient project.
1. Generate the Java Client Before proceeding with the client generation, we need to successfully
complete the following steps: • Download Apache Axis from
http://ws.apache.org/axis/java/releases.html . We need to download version 1.4;
• Configure Apache Axis framework.
The configuration of Apache Axis consist of the registration in your environment (both Windows and Unix / Linux) the following environment variables:
• AXIS_HOME: the installation directory (e.g.: /opt/axis, c:\axis) • AXIS_LIB: the library directory (e.g.: $AXIS_HOME/lib) • AXISCLASSPATH: Java class path (e.g.:
$AXIS_LIB/axis.jar:$AXIS_LIB/commons-‐loggins.jar)
Antonio Musarra's Blog Document Revision:1.0 The ideal solution for a problem Blog: http://www.dontesta.it
LinkedIn: http://it.linkedin.com/in/amusarra Google+: https://plus.google.com/+AntonioMusarra Mail: [email protected]
14/01/14 2 This document is issued with license Creative Commons Attribution-‐NonCommercial-‐ShareAlike
In order to achieve Apache Axis correctly working, we need to verify the
JAVA_HOME environment variable setting; this one represents the installation directory of our Java Virtual Machine.
In the Unix/Linux environment (similarly to Windows systems) we need to configure as follows:
$ export AXIS_HOME="/opt/axis-1_4" $ export AXIS_LIB="$AXIS_HOME/lib" $ export JAVA_HOME="/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home" $ AXISCLASSPATH=$AXIS_LIB/axis-ant.jar:$AXIS_LIB/axis.jar:$AXIS_LIB/commons-discovery-0.2.jar:$AXIS_LIB/commons-logging-1.0.4.jar:$AXIS_LIB/jaxrpc.jar:$AXIS_LIB/log4j-1.2.8.jar:$AXIS_LIB/saaj.jar:$AXIS_LIB/wsdl4j-1.5.1.jar:$AXIS_LIB/mail-1.4.1.jar:$AXIS_LIB/activation.jar $ export AXISCLASSPATH="$AXIS_HOME":"$JAVA_HOME/lib/tools.jar":"$AXISCLASSPATH":"$CLASSPATH" Listing 1 Export environment variables.
In the previous listing I reported all the export (commands are valid for Unix/Linux systems) needed for the environment variables. On that listing, the JAVA_HOME export and the two add-‐on libraries necessary for the binary data transfer are red-‐highlighted (not necessary if it’s available on your environment yet). It is possible to download these two libraries directly from the official site (Oracle) or the online service FindJar (http://www.findjar.com).
• activation.jar: Java Beans Activation Framework (http://www.oracle.com/technetwork/java/jaf11-‐139815.html);
• mail-‐1.4.1.jar: Java Mail API (http://www.oracle.com/technetwork/java/javamail/index.html)
1.1 Java Stub generation Now I will show you how to use the Apache Axis tools to generate Stub +
Data Type. Starting from the SugarCRM WSDL, using the WSDL2Java tool support, I will create the client including:
• Stub • Data Type • Locator • Port Type
Without deeping into details, all the previous elements are the result of the
analysis based on specifications of the WSDL document, so we need to know the exact location of the WSDL document, considering that the location can be remote (URI) or local (file system). For instance I assume that the WSDL document is located at the following address: http://sugarcrm-‐fe-‐1.local/crm-‐6.1/service/v2/soap.php?wsdl.
Antonio Musarra's Blog Document Revision:1.0 The ideal solution for a problem Blog: http://www.dontesta.it
LinkedIn: http://it.linkedin.com/in/amusarra Google+: https://plus.google.com/+AntonioMusarra Mail: [email protected]
14/01/14 3 This document is issued with license Creative Commons Attribution-‐NonCommercial-‐ShareAlike
You could execute a quick reachability test of the WSDL document indicating your address (the SugarCRM instance) on your internet browser or using tools like curl or wget. $ java -cp $AXISCLASSPATH org.apache.axis.wsdl.WSDL2Java –v -B http://sugarcrm-fe-1.local/crm-6.1/service/v2/soap.php?wsdl Listing 2 Tool WSDL2Java execution
WSDL2Java tool verbosely executed (see Listing 2), creates all the necessary elements to speak with the SugarCRM SOAP interface. All the generated classes (starting from the directory from which the tool is executed) are available inside the directory com/sugarcrm/www/sugarcrm/. In my case, the directory ~/Documents/Articoli/MyBlog/SugarCRM/JavaClient/src is my working-‐dir, that is, the directory from which the tool has been executed and where SOAP client sources and binaries will be located. Parsing XML file: http://sugarcrm-fe-1.local/crm-6.1/service/v2/soap.php?wsdl Retrieving schema at 'http://schemas.xmlsoap.org/soap/encoding/', relative to 'http://sugarcrm-fe-1.local/crm-6.1/service/v2/soap.php?wsdl'. Retrieving schema at 'http://schemas.xmlsoap.org/soap/encoding/', relative to 'http://sugarcrm-fe-1.local/crm-6.1/service/v2/soap.php?wsdl'. {http://schemas.xmlsoap.org/soap/encoding/}Struct already exists Generating com/sugarcrm/www/sugarcrm/Return_search_result.java Generating com/sugarcrm/www/sugarcrm/Link_field.java Generating com/sugarcrm/www/sugarcrm/New_return_document_revision.java Generating com/sugarcrm/www/sugarcrm/New_return_note_attachment.java Generating com/sugarcrm/www/sugarcrm/Link_name_to_fields_array.java Generating com/sugarcrm/www/sugarcrm/New_note_attachment.java Generating com/sugarcrm/www/sugarcrm/Document_revision.java Generating com/sugarcrm/www/sugarcrm/Module_list.java Generating com/sugarcrm/www/sugarcrm/User_auth.java Generating com/sugarcrm/www/sugarcrm/Get_entry_result_version2.java Generating com/sugarcrm/www/sugarcrm/Entry_value.java Generating com/sugarcrm/www/sugarcrm/New_set_entry_result.java Generating com/sugarcrm/www/sugarcrm/Get_entry_list_result_version2.java Generating com/sugarcrm/www/sugarcrm/New_set_entries_result.java Generating com/sugarcrm/www/sugarcrm/New_set_relationship_list_result.java Generating com/sugarcrm/www/sugarcrm/New_module_fields.java Generating com/sugarcrm/www/sugarcrm/Field.java Generating com/sugarcrm/www/sugarcrm/Get_entries_count_result.java Generating com/sugarcrm/www/sugarcrm/Link_name_value.java Generating com/sugarcrm/www/sugarcrm/Name_value.java Generating com/sugarcrm/www/sugarcrm/Get_server_info_result.java Generating com/sugarcrm/www/sugarcrm/Sugarsoap.java Generating com/sugarcrm/www/sugarcrm/SugarsoapLocator.java Generating com/sugarcrm/www/sugarcrm/SugarsoapPortType.java Generating com/sugarcrm/www/sugarcrm/SugarsoapBindingStub.java Generating ./build.xml Listing 3 Tool WSDL2Java output
Listing 3 reports the output generated by WSDL2Java tool, operations been executed are clearly shown. I intentionally specified option -‐B on the command line, this option is responsible for the Ant Buildfile (buld.xml) creation, that we will use afterwards to compile the client and to generate the Jar.
Antonio Musarra's Blog Document Revision:1.0 The ideal solution for a problem Blog: http://www.dontesta.it
LinkedIn: http://it.linkedin.com/in/amusarra Google+: https://plus.google.com/+AntonioMusarra Mail: [email protected]
14/01/14 4 This document is issued with license Creative Commons Attribution-‐NonCommercial-‐ShareAlike
The tool supports other configuration options that could be useful in other situations, for further details I recommend to consult the Apache Axis official documentation.
1.2 Client SOAP compilation Now we will show how to compile the SOAP client using both Ant tool (The
Apache Software Foundation, 2011) and the classic method. <?xml version=”1.0”?> <project basedir=”.” Default=”jar”> <property name=”src” location=”.”/> <property name=”build.classes” location=”classes”/> <path id=”classpath”> <pathelement location=”/opt/axis-1_4”/> <pathelement location=”/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home/lib/tools.jar”/> <pathelement location=”/opt/axis-1_4/lib/activation.jar”/> <pathelement location=”/opt/axis-1_4/lib/axis-ant.jar”/> <pathelement location=”/opt/axis-1_4/lib/axis.jar”/> <pathelement location=”/opt/axis-1_4/lib/commons-discovery-0.2.jar”/> <pathelement location=”/opt/axis-1_4/lib/commons-logging-1.0.4.jar”/> <pathelement location=”/opt/axis-1_4/lib/jaxrpc.jar”/> <pathelement location=”/opt/axis-1_4/lib/log4j-1.2.8.jar”/> <pathelement location=”/opt/axis-1_4/lib/mail-1.4.1.jar”/> <pathelement location=”/opt/axis-1_4/lib/saaj.jar”/> <pathelement location=”/opt/axis-1_4/lib/wsdl4j-1.5.1.jar”/> </path> <target name=”compile”> <mkdir dir=”${build.classes}”/> <javac destdir=”${build.classes}” debug=”on”> <classpath refid=”classpath” /> <src path=”${src}”/> </javac> </target> <target name=”jar” depends=”compile”> <copy todir=”${build.classes}”> <fileset dir=”.” Casesensitive=”yes” > <include name=”**/*.wsdd”/> </fileset> </copy> <jar jarfile=”sugarcrm-soap-client-bin-1.0.0.jar” basedir=”${build.classes}” > <include name=”**” /> <manifest> <section name=”org/apache/ws4j2ee”> <attribute name=”Implementation-Title” value=”Apache Axis”/> <attribute name=”Implementation-Vendor” value=”Apache Web Services”/> </section> </manifest> </jar> <delete dir=”${build.classes}”/> </target> </project> Listing 4 Ant Buldfile generated by WSDL2Java tool.
Listing 4 shows the content of build.xml file generated by WSDL2Java tool, I highlighted the only change made to the file, jar name, from soap.jar to sugarcrm-‐soap-‐client-‐bin-‐1.0.0.jar.
Antonio Musarra's Blog Document Revision:1.0 The ideal solution for a problem Blog: http://www.dontesta.it
LinkedIn: http://it.linkedin.com/in/amusarra Google+: https://plus.google.com/+AntonioMusarra Mail: [email protected]
14/01/14 5 This document is issued with license Creative Commons Attribution-‐NonCommercial-‐ShareAlike
SOAP client compilation is really simple, it’s enough to execute command ant , Listing 5 shows the corresponding output (just a couple of lines omitted for space reason). Buildfile: ~/Documents/Articoli/MyBlog/SugarCRM/JavaClient/src/build.xml compile: [mkdir] Created dir: ~/Documents/Articoli/MyBlog/SugarCRM/JavaClient/src/classes javac] Compiling 25 source files … jar: [jar] Building jar: ~/Documents/Articoli/MyBlog/SugarCRM/JavaClient/src/sugarcrm-soap-client-1.0.0.jar [delete] Deleting directory ~/Documents/Articoli/MyBlog/SugarCRM/JavaClient/src/classes BUILD SUCCESSFUL Listing 5 ant.command output
Ant tool is not installed on your machine? No problem, I’ll show you how to compile Java source at the same time and generate the Jar library of our SOAP client using the classical way. Listing 6 shows the command sequence needed to get the sugarcrm-‐soap-‐client-‐bin-‐1.0.0.jar library. $ mkdir ~/Documents/Articoli/MyBlog/SugarCRM/JavaClient/src/classes $ javac –cp $AXISCLASSPATH –d ~/Documents/Articoli/MyBlog/SugarCRM/JavaClient/src/classes com/sugarcrm/www/sugarcrm/*.java $ cd ~/Documents/Articoli/MyBlog/SugarCRM/JavaClient/src/classes $ jar cvf sugarcrm-soap-client-1.0.0.jar com/ Listing 6 Java source compilation and jar creation.
2. Creation of Java SugarCRMSOAPClient project Now I will show how to create and correctly configure the Java project
named SugarCRMSOAPClient. Exploiting the SOAP library previously created, our goal is to write some Java code that will execute the following operations on a SugarCRM generic instance:
• Login; • Creation of a new contact; • Read access to the new contact.
The IDE environment to create our Java project is Eclipse Helios 3.6,
however you can use your favourite IDE as well. The following steps show how to create and configure the Java project.
Antonio Musarra's Blog Document Revision:1.0 The ideal solution for a problem Blog: http://www.dontesta.it
LinkedIn: http://it.linkedin.com/in/amusarra Google+: https://plus.google.com/+AntonioMusarra Mail: [email protected]
14/01/14 6 This document is issued with license Creative Commons Attribution-‐NonCommercial-‐ShareAlike
Figure 1 Step 1 – New Java project creation.
Figure 2 Step 2 – Basic Java project configuration.
Unless you have special needs, I recommend to let the default settings for the Java project creation.
Antonio Musarra's Blog Document Revision:1.0 The ideal solution for a problem Blog: http://www.dontesta.it
LinkedIn: http://it.linkedin.com/in/amusarra Google+: https://plus.google.com/+AntonioMusarra Mail: [email protected]
14/01/14 7 This document is issued with license Creative Commons Attribution-‐NonCommercial-‐ShareAlike
Figure 3 Step 3 – Java building configuration.
This step of the project creation comes with the path configuration for the source code, the binaries and the add-‐on libraries. Relating to Figure 3 configuration, I recommend to let it unchanged, we need instead to configure the project, that is, the libraries. The dependencies that are to be added to the project are:
• All the Apache Axis jar files, those included in $ANT_LIB; • The library implementing the SOAP SugarCRM Client previously created
(sugarcrm-‐soap-‐client-‐bin-‐1.0.0.jar).
Antonio Musarra's Blog Document Revision:1.0 The ideal solution for a problem Blog: http://www.dontesta.it
LinkedIn: http://it.linkedin.com/in/amusarra Google+: https://plus.google.com/+AntonioMusarra Mail: [email protected]
14/01/14 8 This document is issued with license Creative Commons Attribution-‐NonCommercial-‐ShareAlike
In order to add dependencies to the project, just click on the “Libraries” section of the window shown in Figure 3. Figure 4 shows the window with all the imported dependencies.
Figure 4 Step 4 -‐ SugarCRM SOAP Client + Axis library import.
Once the dependencies import process is finished, you may click OK button
and the project creation is finally complete. After SugarCRMSOAPClient project creation, it is possible to view the whole project structure with Package Explorer, Figure 5 shows the com.sugarcrm.www.sugarcrm project expansion, in other words, the SOAP library that will be used to connect to SugarCRM.
Antonio Musarra's Blog Document Revision:1.0 The ideal solution for a problem Blog: http://www.dontesta.it
LinkedIn: http://it.linkedin.com/in/amusarra Google+: https://plus.google.com/+AntonioMusarra Mail: [email protected]
14/01/14 9 This document is issued with license Creative Commons Attribution-‐NonCommercial-‐ShareAlike
Figure 5 Package Explorer after project creation.
2.1 Client coding Now we are finally ready to write the Java code that the previously created
SOAP client will use in order to execute the desired actions. The steps to accomplish are:
• SugarCRMSOAPClient class creation (using static method main); • Configuration setting for constants to be used; • End Point URL and Service creation; • Stub Java creation; • Login on SugarCRM execution; • Creation of a new Contact on SugarCRM; • Read access of the new Contact; • Logout from SugarCRM.
Listing 7 shows the declaration of all the constants to be used. You just need to substitute the values of END_POINT_URL, USER_NAME e USER_PASSWORD with yours (of your SugarCRM instance). public class SugarCRMSoapClient { private static final String END_POINT_URL = "http://crm-6.1/service/v2/soap.php?wsdl"; private static final String USER_NAME = "will"; private static final String USER_PASSWORD = "will"; private static final String APPLICATION_NAME = Class.class.getName(); private static final Integer TIMEOUT = 6000; public static void main(String[] args) throws Exception { …. } } Listing 7 Constants declaration.
Antonio Musarra's Blog Document Revision:1.0 The ideal solution for a problem Blog: http://www.dontesta.it
LinkedIn: http://it.linkedin.com/in/amusarra Google+: https://plus.google.com/+AntonioMusarra Mail: [email protected]
14/01/14 10 This document is issued with license Creative Commons Attribution-‐NonCommercial-‐ShareAlike
// Create a URL end point for the client URL wsdlUrl = null; if (END_POINT_URL.isEmpty()) { wsdlUrl = new URL(new SugarsoapLocator().getsugarsoapPortAddress() + "?wsdl"); } else { wsdlUrl = new URL(END_POINT_URL); } System.out.println("URL endpoint created successfully!"); // Create Service for test configuration ServiceFactory serviceFactory = ServiceFactory.newInstance(); Service service = serviceFactory.createService(wsdlUrl, new SugarsoapLocator().getServiceName()); System.out.println("Service created successfully"); Listing 8 End point URL and Service SugarSOAP configuration.
Operations indicated in Listing 8 could launch some exceptions; this code section might be enclosed inside a try…catch block (omitted for space reason). The exceptions that might be launched are: MalformedURLException and ServiceException. // Trying to create a stub SugarsoapBindingStub binding = new SugarsoapBindingStub(wsdlUrl, service); binding.setTimeout(TIMEOUT); System.out.println("Stub created successfully!"); Listing 9 Stub creation.
Listing 9 shows the stub creation. The object constructor needs the end point of the service and of the service object (javax.xml.rpc.Service) previously created. The stub includes all the operations needed to interface with SugarCRM web services. Also this code section might be enclosed inside a try…catch block, stub object creation and the stub operations call might launch the AxisFault exception. /** * Try to login on SugarCRM * * 1) Prepare a MD5 hash password * 2) Prepare a User Auth object * 3) Execute login */ // 1. Prepare a MD5 hash password MessageDigest messageDiget = MessageDigest.getInstance("MD5"); messageDiget.update(USER_PASSWORD.getBytes()); // 2. Prepare a User Auth object User_auth userAuthInfo = new User_auth(); userAuthInfo.setUser_name(USER_NAME); userAuthInfo.setPassword((new BigInteger(1, messageDiget.digest())).toString(16)); try { // 3. Execute login Entry_value loginResult = binding.login(userAuthInfo, APPLICATION_NAME, null); System.out.println("Login Successfully for " + USER_NAME);
Antonio Musarra's Blog Document Revision:1.0 The ideal solution for a problem Blog: http://www.dontesta.it
LinkedIn: http://it.linkedin.com/in/amusarra Google+: https://plus.google.com/+AntonioMusarra Mail: [email protected]
14/01/14 11 This document is issued with license Creative Commons Attribution-‐NonCommercial-‐ShareAlike
System.out.println("Your session Id: " + loginResult.getId()); sessionID = loginResult.getId(); } catch (RemoteException ex) { System.out.println("Login failed. Message: " + ex.getMessage()); ex.printStackTrace(); } Listing 10 SugarCRM Login process execution.
All is ready to execute the login on SugarCRM. The login operation needs three parameters, but only the first parameter is fundamental, we can omit the last two. The first parameter to prepare is the User_auth object including username and (the MD5 hash) password. The login operation returns the user session id, and this value will be used for the next operations I’ll show. /** * Create a new Contact * * 1) Setting a new entry * 2) Setting up parameters for set_entry call * 3) Creating a name value list array from a hash map. This is not necessary * just more elegant way to initialize and add name values to an array */ HashMap<String, String> nameValueMap = new HashMap<String, String>(); nameValueMap.put("first_name", "Antonio"); nameValueMap.put("last_name", "Musarra"); nameValueMap.put("title", "IT Senior Consultant"); nameValueMap.put("description","Contatto creato dal Client SOAP Java"); nameValueMap.put("email1", "[email protected]"); // Creating a new Name_value array and adding each map entry as 'name' and 'value' Name_value nameValueListSetEntry[] = new Name_value[nameValueMap.size()]; int i = 0; for (Entry<String, String> entry : nameValueMap.entrySet()) { Name_value nameValue = new Name_value(); nameValue.setName(entry.getKey()); nameValue.setValue(entry.getValue()); nameValueListSetEntry[i] = nameValue; i++; } // Trying to set a new entry New_set_entry_result setEntryResponse = null; try { setEntryResponse = binding.set_entry(sessionID, "Contacts", nameValueListSetEntry); } catch (RemoteException e) { System.out.println("Set entry failed. Message: " + e.getMessage()); e.printStackTrace(); } System.out.println("Set entry was successful! Contacts Id: " + setEntryResponse.getId()); Listing 11 New contact creation.
Once the login operation is successfully executed, we move creating a new contact. set_entry operation permits to insert a new record on SugarCRM and works taking as input variables: the user session id, the module name (Contacts, in this case) and a Name_value array object defining the names and the values for the contact to create (see Listing 11).
Antonio Musarra's Blog Document Revision:1.0 The ideal solution for a problem Blog: http://www.dontesta.it
LinkedIn: http://it.linkedin.com/in/amusarra Google+: https://plus.google.com/+AntonioMusarra Mail: [email protected]
14/01/14 12 This document is issued with license Creative Commons Attribution-‐NonCommercial-‐ShareAlike
set_entry operation returns the inserted SugarBean id, and this value will be used for the contact data retrieval using get_entry operation.
get_entry operation requires as input variables: the user session, the module name (Contacts, in this case), the SugarBean id, an array including the fields we like to have back, and, at last, an array to relate the returned fields to specific names (optional). The operation returns an entry_list including a Name_value object array containing the contact informations.
Listing 12 shows the code responsible for the contact (previously inserted set_entry operation) retrieval. /** * Getting an Contacts Entry (the one we just set) */ Link_name_to_fields_array[] link_name_to_fields_array = null; String[] select_fields = null; Get_entry_result_version2 getEntryResponse = null; // Trying to get entry try { getEntryResponse = binding.get_entry(sessionID,"Contacts", setEntryResponse.getId(), select_fields , link_name_to_fields_array); } catch (RemoteException e) { System.out.println("Get entry failed. Message: " + e.getMessage()); e.printStackTrace(); } System.out.println("Get entry was successful! Response: "); // Getting the fields for entry we got. Entry_value[] entryList = getEntryResponse.getEntry_list(); for (int k=0; k < entryList.length; k++){ Entry_value entry = entryList[k]; Name_value[] entryNameValueList = entry.getName_value_list(); for (int j=0; j< entryNameValueList.length; j++){ Name_value entryNameValue = entryNameValueList[j]; //Outputting only non empty fields if (!entryNameValue.getValue().isEmpty()){ System.out.println("Attribute Name: '" + entryNameValue.getName() + "' Attribute Value: '" + entryNameValue.getValue() + "'"); } } } Listing 12 Data retrieval for the Contact inserted on SugarCRM.
Antonio Musarra's Blog Document Revision:1.0 The ideal solution for a problem Blog: http://www.dontesta.it
LinkedIn: http://it.linkedin.com/in/amusarra Google+: https://plus.google.com/+AntonioMusarra Mail: [email protected]
14/01/14 13 This document is issued with license Creative Commons Attribution-‐NonCommercial-‐ShareAlike
/** * Logout */ try { binding.logout(sessionID); System.out.println("Logout Successfully for " + USER_NAME); sessionID = null; } catch (RemoteException ex) { System.out.println("Login failed. Message: " + ex.getMessage()); ex.printStackTrace(); } Listing 13 SugarCRM Logout operation.
Having successfully executed all the operations, it’s always desirable (even if not mandatory) to execute the logout action from Sugar, as shown in Listing 13.
Listing 14 and Listing 15 show the output generated executing the implemented Java application.
Listing 14 reports an issue in the service creation due to SugarCRM WSDL document unreachability.
Listing 15 shows the expected situation: login, contact creation, contact retrieval and logout.
Figure 6 shows the SugarCRM contact form created by Java application through the SOAP client.
URL endpoint created successfully! Service creation failed. Message: Error processing WSDL document: java.io.IOException: WSDL2Java emitter timed out (this often means the WSDL at the specified URL is inaccessible)! javax.xml.rpc.ServiceException: Error processing WSDL document: java.io.IOException: WSDL2Java emitter timed out (this often means the WSDL at the specified URL is inaccessible)! at org.apache.axis.client.Service.initService(Service.java:250) at org.apache.axis.client.Service.<init>(Service.java:165) at org.apache.axis.client.ServiceFactory.createService(ServiceFactory.java:198) at it.lab.shirus.sugarcrm.client.soap.SugarCRMSoapClient.main(SugarCRMSoapClient.java:65) Listing 14 Error raised during the service creation.
URL endpoint created successfully! {http://schemas.xmlsoap.org/soap/encoding/}Struct already exists Service created successfully Service Name:{http://www.sugarcrm.com/sugarcrm}sugarsoap Service WSDL:http://sugarcrm-fe-1.local/crm-6.1/service/v2/soap.php?wsdl Stub created successfully! Login Successfully for will Your session Id: a8e97vgnvfhrtcq3hb5midmp32 Set entry was successful! Contacts Id: 69ff87e9-758d-30f5-0acd-4d2e3fa5b513 Get entry was successful! Response: Attribute Name: 'modified_by_name' Attribute Value: 'Will Westin' Attribute Name: 'created_by_name' Attribute Value: 'Will Westin' Attribute Name: 'id' Attribute Value: '69ff87e9-758d-30f5-0acd-4d2e3fa5b513' Attribute Name: 'date_entered' Attribute Value: '2011-01-12 23:55:29'
Antonio Musarra's Blog Document Revision:1.0 The ideal solution for a problem Blog: http://www.dontesta.it
LinkedIn: http://it.linkedin.com/in/amusarra Google+: https://plus.google.com/+AntonioMusarra Mail: [email protected]
14/01/14 14 This document is issued with license Creative Commons Attribution-‐NonCommercial-‐ShareAlike
Attribute Name: 'date_modified' Attribute Value: '2011-01-12 23:55:29' Attribute Name: 'modified_user_id' Attribute Value: 'seed_will_id' Attribute Name: 'created_by' Attribute Value: 'seed_will_id' Attribute Name: 'description' Attribute Value: 'Contatto creato dal Client SOAP Java' Attribute Name: 'deleted' Attribute Value: '0' Attribute Name: 'first_name' Attribute Value: 'Antonio' Attribute Name: 'last_name' Attribute Value: 'Musarra' Attribute Name: 'title' Attribute Value: 'IT Senior Consultant' Attribute Name: 'do_not_call' Attribute Value: '0' Attribute Name: 'email1' Attribute Value: '[email protected]' Logout Successfully for will Listing 15 SugarCRMSOAPClient client execution.
Figure 6 View of the contact created with the SOAP client.
Accessing to SugarCRM web services API documentation can help to better understand the Java code samples showed up to now. I’m sure that reporting part of the Data Model (XSD) schema as it is published by SugarCRM interface will help to better clarify the whole scenario.
Figure 7 User_auth class model.
Antonio Musarra's Blog Document Revision:1.0 The ideal solution for a problem Blog: http://www.dontesta.it
LinkedIn: http://it.linkedin.com/in/amusarra Google+: https://plus.google.com/+AntonioMusarra Mail: [email protected]
14/01/14 15 This document is issued with license Creative Commons Attribution-‐NonCommercial-‐ShareAlike
Figure 8 Entry_value class model.
Figure 9 Name_Value_List class model.
Figure 10 Name_Value class model.
Figure 11 New_Set_Entry_List class model.
Antonio Musarra's Blog Document Revision:1.0 The ideal solution for a problem Blog: http://www.dontesta.it
LinkedIn: http://it.linkedin.com/in/amusarra Google+: https://plus.google.com/+AntonioMusarra Mail: [email protected]
14/01/14 16 This document is issued with license Creative Commons Attribution-‐NonCommercial-‐ShareAlike
Figure 12 Get_Entry_List_Result_Version2 class model.
Figure 13 Entry_List class model.
Available SugarCRM documentation relating to Data Model exposed from the interface is not very clear or is completely missing. As I think it’s helpful to have the Data Model high level documentation, I extracted the XSD schema from the WSDL document and make it available on my blog:
http://musarra.files.wordpress.com/2011/04/sugacrm-‐6-‐1ce-‐xsd.pdf
At same time, I created a public repository (GitHub Inc., 2011) including all I produced the in this article. Repository address is:
https://github.com/amusarra/SugarCRMJavaSOAPClient and includes the
following items:
• JavaApplication: includes the Eclipse Java project of the application that connects to SugarCRM using the SOAP client;
• SOAPClient: includes (source and binary code) the SOAP client generated withe the Apache Axis framework;
• SugaCRM-‐6.1CE-‐WSDL.wsdl: the WSDL document relating to SugarCRM 6.1 Community Edition;
Antonio Musarra's Blog Document Revision:1.0 The ideal solution for a problem Blog: http://www.dontesta.it
LinkedIn: http://it.linkedin.com/in/amusarra Google+: https://plus.google.com/+AntonioMusarra Mail: [email protected]
14/01/14 17 This document is issued with license Creative Commons Attribution-‐NonCommercial-‐ShareAlike
• SugaCRM-‐6.1CE-‐XSD.xsd: the XSD document extracted from the SugarCRM WSDL document;
• SugaCRM-‐6.1CE-‐XSD.pdf: the data model documentation used by SugarCRM interface.
Figure 14 View of the repository (git) SugarCRMJavaSOAPClient.
3. Conclusions In this article I tried to shed some light on how to configure and implement
a SOAP Java client based on Apache Axis framework. The more careful of you will have noticed the decoupling maintained between the Java SOAP and the Java application that, for inner business logics, uses the client to interface with SugarCRM: this is a best practice.
Recurring to some basic code samples (login, set_entry e get_entry) demonstrated how it is simple to interface with SugarCRM web services, making it simpler to the ones of you really interested the construction of the Java client for SugarCRM Web Services.
Every kind of question or comment related to the subjects in the article are really well encouraged and can be posted here:
http://musarra.wordpress.com/2011/04/04/costruire-‐un-‐client-‐java-‐per-‐sugarcrm
Antonio Musarra's Blog Document Revision:1.0 The ideal solution for a problem Blog: http://www.dontesta.it
LinkedIn: http://it.linkedin.com/in/amusarra Google+: https://plus.google.com/+AntonioMusarra Mail: [email protected]
14/01/14 18 This document is issued with license Creative Commons Attribution-‐NonCommercial-‐ShareAlike
Bibliography GitHub Inc. (2011). Git Reference. Tratto da GitHub Social Coding: http://gitref.org/ SugarCRM Inc. (2010). Sugar Community Edition Documentation. Tratto da Sugar Community Edition Documentation: http://www.sugarcrm.com/crm/support/documentation/SugarCommunityEdition/6.1/-‐docs-‐Developer_Guides-‐Sugar_Developer_Guide_6.1.0-‐Chapter%202%20Application%20Framework.html#9000244 SugarCRM Inc. (2010). Sugar Community Edition Documentation. Tratto da Sugar Community Edition Documentation | SugarCRM -‐ Commercial Open Source CRM: http://www.sugarcrm.com/crm/support/documentation/SugarCommunityEdition SugarCRM Inc. (2004). SugarCRM -‐ Commercial Open Source CRM. Tratto da SugarCRM -‐ Commercial Open Source CRM: http://www.sugarcrm.com/crm/ The Apache Software Foundation. (2011). Apache Ant. Tratto da The Apache Ant Project: http://ant.apache.org/ The Apache Software Foundation. (2005). Web Service -‐ Axis. Tratto da Apache <Web Services \> Project: http://axis.apache.org/axis/