Incoming web services
Basics
This article deals with the option for external systems to communicate with CURSOR-CRM (also with EVI and TINA) via web service.
Establishing the connection
WSDL
The system offers three WSDLs.
WSDL for the initiation and continuation of BPM processes
Sample: httsp://<SERVER>:X8443/<VERSION>-ejb/ProcessWebService?wsdl
Example: https://localhost:18443/soap/ProcessWebService?wsdl
You can find examples for the XML syntax for the messages to be sent to CRM in the BPM documentation (section Web Service).
WSDL for other functions
Sample: https://<SERVER>:X8443/soap/CrmWebService?wsdl
Example: https://localhost:18443/soap/CrmWebService?wsdl
Login
Every web service invocation needs its own login (HTTP basic access), which means that the data rights for CURSOR-CRM/EVI may vary.
For this purpose, user token and password (plain text) must be transferred.
In effect, only an existing CRM user can log on. We recommend creating an own user for the process.
Technology
Web services are provided via SessionBeans. A SessionBean is declared via the EJB specification as a service endpoint. The public methods of the SessionBean are approved for use in the web service in accordance with the EJB 3.1 specification.
Configuration in CURSOR-CRM/EVI
The SessionBeans WebServiceControllerBean
(old version) and CrmWebServiceBean
(new version) were created in order to centralize web service provision. All web services are provided via these classes. The WSDL definition is generated via the JBoss application server and provided at URL https://<SERVER>:X8443/soap/WebServiceController?wsdl
or https://<SERVER>:X8443/soap/CrmWebService?wsdl
.
Every web service invocation needs its own login (HTTP basic access), which means that the data rights for CURSOR-CRM/EVI may vary. The user token (all caps) and password (as HashValue) from the database must be provided.
Listing: WebServiceController.wsdl for the configuration of method string importEntities(String)
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="WebServiceController" targetNamespace="http://de.cursor.jevi.server.web/" xmlns:tns="http://de.cursor.jevi.server.web/" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<types/>
<message name="importEntities">
<part name="xmlEntity" type="xsd:string"/>
</message>
<message name="importEntitiesResponse">
<part name="result" type="xsd:string"/>
</message>
<portType name="WebServiceControllerService">
<operation name="importEntities" parameterOrder="xmlEntity">
<input message="tns: importEntities"/>
<output message="tns:importEntitiesResponse"/>
</operation>
</portType>
<binding name="WebServiceControllerServiceBinding" type="tns:WebServiceControllerService">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
<operation name="importEntities">
<soap:operation soapAction=""/>
<input>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded" namespace="http://de.cursor.jevi.server.web/"/>
</input>
<output>
<soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" use="encoded" namespace="http://de.cursor.jevi.server.web/"/>
</output>
</operation>
</binding>
<service name="WebServiceController">
<port name="WebServiceControllerServicePort" binding="tns:WebServiceControllerServiceBinding">
<soap:address location="REPLACE_WITH_ACTUAL_URL"/>
</port>
</service>
</definitions>
Web service call logging
Incoming and outgoing data to and from the web services provided can be exported in JBoss via the log file WebServices.log.
The log level must be set to INFO (or DEBUG) for "de.cursor.jevi.server.web.webservice".
cursor-standalone.xml
<logger category="de.cursor.jevi.server.web.webservice" use-parent-handlers="false">
<level name="INFO"/>
<handlers>
<handler name="WEBSERVICE"/>
</handlers>
</logger>
This can also be done via the CLI interface:
Console
> bin/jboss-logging.bat webservice true
All input and output can be checked after activation.
Invocation - input
2014-11-20 08:16:24,581 INFO [de.cursor.jevi.common.web.webservice.interceptor.WebServiceInLogggingInterceptor] ============= SOAP Message ==============
2014-11-20 08:16:24,581 INFO [de.cursor.jevi.common.web.webservice.interceptor.WebServiceInLogggingInterceptor] Inbound Message
----------------------------
ID: 1
Address: https://SERVER:18443/soap/ProcessWebService
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml;charset=UTF-8
Headers: {accept-encoding=[gzip,deflate], Authorization=[Basic ABCDEFG=], connection=[Keep-Alive], Content-Length=[2497], content-type=[text/xml;charset=UTF-8], host=[SERVER:18443], SOAPAction=["startProcess"], user-agent=[Apache-HttpClient/4.1.1 (java 1.5)]}
Payload: <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://web.process.cursor.de/" xmlns:var="http://variable.process.common.jevi.cursor.de/">
<soapenv:Header/>
<soapenv:Body>
...
</soapenv:Envelope>
--------------------------------------
Return - output
2014-11-20 08:24:06,679 INFO [de.cursor.jevi.common.web.webservice.interceptor.WebServiceOutLoggingInterceptor] ============= SOAP Response ==============
2014-11-20 08:24:06,679 INFO [de.cursor.jevi.common.web.webservice.interceptor.WebServiceOutLoggingInterceptor] Outbound Message
----------------------------
ID: 1
Encoding: UTF-8
Content-Type: multipart/related; type="application/xop+xml"; boundary="uuid:ae412396-af94-4ffc-95f1-31154c29a097"; start="<root.message@cxf.apache.org>"; start-info="text/xml"
Headers: {}
Payload: --uuid:ae412396-af94-4ffc-95f1-31154c29a097
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml";
Content-Transfer-Encoding: binary
Content-ID: <root.message@cxf.apache.org>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns3:startProcessResponse xmlns:ns3="http://web.process.cursor.de/" xmlns:ns2="http://variable.process.common.jevi.cursor.de/">
<ns2:processWebResult>
...
</soap:Body></soap:Envelope>
--uuid:ae412396-af94-4ffc-95f1-31154c29a097--
--------------------------------------
Web services in CURSOR-CRM/EVI
WebServiceController
search
Method name | search |
---|---|
Input parameter | xmlSearch of type string (XML search import) |
Output Parameter | String (XML import plugin) |
WSDL | WebServiceController?wsdl |
Description | A search must be forwarded to the web service as a complete XML description for execution. Each input and output field must be defined. Each field ('condition') contains a function for limiting the parameters, whereby the data type must be stated correctly. Encoding and DocType can be skipped. |
Listing: Business partner search with limitation of the short name begins with CURSORListing: Business partner search with limitation of the short name begins with CURSOR
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE CreateComplexSearch PUBLIC "ComplexSearchCreator.dtd" "ComplexSearchCreator.dtd">
<CreateComplexSearch>
<ExtendedSearch PK="" PlainKey="" Description="" QuickSearch="false" IgnoreCase="true">
<Query>
<SubQuery operator="de.cursor.jevi.common.search.Operator$AndOperator" relationName="" entityName="Customer" subQueryInSearchResult="true" useExists="false" useOuterJoin="false" optionalQuery="false" breakQuery="false" hint="">
<Condition searchResultField="true" listKey="false" defaultSearchValue="false">
<AttributeName>MatchCode.Customer</AttributeName>
<Function functionClassName="de.cursor.jevi.common.search.function.LikeFunction" numberOfParameters="1">
<Parameter parameterClassName="java.lang.String" parameterValue="CURSOR" />
</Function>
</Condition>
<Condition searchResultField="true" listKey="false" defaultSearchValue="false">
<AttributeName>CustomerNo1.Customer</AttributeName>
<Function functionClassName="de.cursor.jevi.common.search.function.NoConditionFunction" numberOfParameters="0">
<FunctionProperty functionPropertyName="TableName" functionPropertyDataType="java.lang.String" functionPropertyValue="" />
</Function>
</Condition>
<Condition ...>
...
</Condition>
</SubQuery>
</Query>
</ExtendedSearch>
</CreateComplexSearch>
As you will hardly be able to generate this XML structure manually, it will be very helpful to first create the search in CURSOR-CRM/EVI and to then export it to XML (see illustration below). So that parameters can be added to the search later, they should be marked in the search with visible default values that can be replaced with text later in the XML (e.g. replace CURSOR with ADAC).
Figure: Exporting the business partner search to XML
The search returns all AttributeContainers as an XML result. The same structure as for the CURSOR-CRM/EVI XML export plugin is used and can therefore be exported again. Should the results contain the primary key, then it will be marked as identifyingField=true
.
Listing: Result of the business partner search, suitable for XML export.
<?xml version="1.0" encoding="ISO-8859-1"?>
<Entries>
<Entry entity="Customer" createIfNotFound="false">
<Field name="Pk.Customer" identifyingField="true" value="ged-personpk1#customer1" />
<Field name="Name1.Customer" value="CURSOR Software AG" />
<Field name="CustTypeKey.Customer" value="?" />
<Field name="PersontypeKey.Customer" value="U" />
<Field name="CustomerNo1.Customer" value="1" />
<Field name="MatchCode.Customer" value="CURSOR GIESSEN" />
</Entry>
<Entry entity="Customer" createIfNotFound="false">
<Field name="Pk.Customer" identifyingField="true" value="ged-personpk1#customer2" />
<Field name="MatchCode.Customer" value="CURSOR ENTWICKLUNG" />
<Field name="Name1.Customer" value="CURSOR Software AG" />
<Field name="CustTypeKey.Customer" value="?" />
<Field name="PersontypeKey.Customer" value="U" />
<Field name="CustomerNo1.Customer" value="1" />
</Entry>
</Entries>
searchXML
Method name | searchXML |
---|---|
Input parameter | xmlSearch of type string (XML search import) |
Output Parameter | String (XML structure, which can always be used for second generation XML import) |
WSDL | WebServiceController?wsdl |
Description | This web service is a continuation of the previous "search" web services. The XML definition of a search is forwarded to the service "SearchXML" (example: see above) and the result returned is an XML structure, which can be forwarded to the second generation XML import interface (importXML, see below). |
searchXMLWithParams
Method name | searchXMLWithParams |
---|---|
Input parameter | Search name, input parameter |
Output Parameter | String (XML structure, which can always be used for second generation XML import) |
WSDL | WebServiceController?wsdl |
Description | A search name, followed by any number of input parameters, is forwarded for "earchXMLWithParameters". All parameter templates within the stated search are replaced in sequence (from the top down) by the forwarded parameters. A structure for the XML import is returned. |
The search methods searchXML
and searchXMLWithParams
always deliver the XML import structure in a default configuration. All entries have the options CREATE / NO_SEARCH enabled. The relevant datasets will therefore be created again if this exact structure is sent to the import.
The structure should only be used as a basic framework and must be adapted for other operations in accordance with the documentation of the XML import interface. Specifically the attributes action and found must be adapted. When searching for a dataset (e.g. during an update or an assignment), some of the Field entries must be specified as identifyingField.
XML import v.1.0
CURSOR Software AG recommends using the methods searchXML
and importXML
.
Method name | importXML |
---|---|
Input parameter | xmlEntries of type string |
Output Parameter | String (log output) |
WSDL | WebServiceController?wsdl |
Description | All information on the XML structure and the options for XML import can be found in the chapter XML import interface of the second generation. |
Listing: Creating a new activity with contact person lookup
<Entry entity="Activity" action="CREATE" found="ZERO">
<Field name="Subject.Activity" identifyingField="true">
<FieldValue>
<stringValue>Bestätigung</stringValue>
</FieldValue>
</Field>
<Field name="DelegatedBy.Activity" identifyingField="false">
<FieldValue>
<stringValue>BNE</stringValue>
</FieldValue>
</Field>
<Field name="DelegatedTo.Activity">
<FieldValue>
<stringValue>BNE</stringValue>
</FieldValue>
</Field>
<Field name="ActStatusKey.Activity">
<FieldValue>
<stringValue>O</stringValue>
</FieldValue>
</Field>
<Field name="ActTypeKey.Activity">
<FieldValue>
<stringValue>TELEIN</stringValue>
</FieldValue>
</Field>
<Field name="StartDate.Activity">
<FieldValue>
<dateTimeValue>2008-04-20T17:00:00</dateTimeValue>
</FieldValue>
</Field>
<Field name="EndDate.Activity">
<FieldValue>
<dateTimeValue>2008-04-27T17:00:00</dateTimeValue>
</FieldValue>
</Field>
<EntityLookupField name="DefaultContactPerson.Activity">
<Field name="FirstName.ContactPerson" identifyingField="true">
<FieldValue>
<stringValue>Cornelia</stringValue>
</FieldValue>
</Field>
<Field name="LastName.ContactPerson" identifyingField="true">
<FieldValue>
<stringValue>Altenhain</stringValue>
</FieldValue>
</Field>
<Field name="CustomerKey.ContactPerson" identifyingField="true">
<FieldValue>
<stringValue>CURSOR GIESSEN</stringValue>
</FieldValue>
</Field>
</EntityLookupField>
</Entry>
Entity import (XML import v. 0.5)
Method name | importEntities |
---|---|
Input parameter | xmlEntity of type string (XML import plugin) |
Output Parameter | String (log output) |
WSDL | WebServiceController?wsdl |
Description | The import of entities supports new creations, data changes and links with dependent entities. Each entity is defined in the entry tag. Multiple entry tags can be added where several datasets are to be processed in parallel. The option createIfNotFound can be activated for each entry to control new creations. Each entity contains special fields, which must be unique or are mandatory to state. These options can be viewed in the field attributes of the individual fields. The unique fields are used internally to load a dataset and to change its data. Some fields have a special format:
|
Listing: An import using the example of activities and an associated contract
<?xml version="1.0" encoding="ISO-8859-1"?>
<Entries testRun="false">
<Entry entity="Activity" createIfNotFound="true">
<Field name="Subject.Activity" value="Präsentation" />
<Field name="Text.Activity" value="Sehr geehrte Damen und Herren" />
<Field name="ActtypeKey.Activity" value="ERINNERUNG" />
</Entry>
<Entry entity="Activity" createIfNotFound="true">
<Field name="Subject.Activity" value="Angebot versendet" />
<Field name="Text.Activity value="Anbei das Angebot bzgl. der Webservice-Schnittstelle" />
<Field name="ActtypeKey.Activity" value="MAILAUS" />
<Entry entity="Contract" createIfNotFound="false" >
<Field name="ContNo.Contract" identifyingField="true" value="00001003" />
<Field name="ProducttypeKey.Contract" identifyingField="true" value="TELE" />
<Field name="ContTitle.Contract" value="XXXX" />
</Entry>
</Entries>
Entity import and transformation (XML import v. 0.5)
Method name | importAndTransformEntities |
---|---|
Input parameter |
|
Output Parameter | String (log output) |
WSDL | WebServiceController?wsdl |
Description | Any XML structure can be forwarded to the method to ensure that the caller of the web service is not bound by the structure of the XML import plugin. That allows a web service invocation without the need for special adaptations in the invoking program. An XSLT script ensures correct forwarding. This script must be created separately for each format. The target format is once again the import XML format for the The parameter |
INSERT
INTO PropertyMapper
VALUES('WebserviceXSLT-Pk', 'WebserviceXSLT-ID', null,
'<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="1.0"xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="xml" encoding="UTF-8"/> ... </xsl:stylesheet>',
'SYSTEM', '', 1, GETDATE(), 'TECH_USER', GETDATE(), 'TECH_USER', null, null, null);
This menu item describes the inclusion of external web services within CURSOR-CRM so that these can be addressed in e.g. mask scripts.
CrmWebService
importXML
Method name | importXML |
---|---|
Input parameter | Object of type |
Output Parameter | Object of type |
WSDL | CrmWebService?wsdl |
Description | This service is equivalent to All information on the XML structure and the options for XML import can be found in the chapter XML import interface of the second generation. |
Request - importXML
def parameters = proxy.create("de.cursor.jevi.server.web.ImportXML")
def entries = proxy.create("de.cursor.jevi.server.web.Entries")
parameters.setEntries(entries)
def entry = proxy.create("de.cursor.jevi.server.web.Entry")
entry.setAction(proxy.create("de.cursor.jevi.server.web.Action").CREATE)
entry.setFound(proxy.create("de.cursor.jevi.server.web.Found").ZERO)
entry.setEntity("Customer")
entries.getEntry().add(entry)
def fieldPk = proxy.create("de.cursor.jevi.server.web.Field")
fieldPk.setName("Pk.Customer")
fieldPk.setIdentifyingField(true)
def fieldvaluePk = proxy.create("de.cursor.jevi.server.web.ValidFieldValue")
fieldvaluePk.setStringValue("123")
fieldPk.setFieldValue(fieldvaluePk)
entry.getField().add(fieldPk)
def field1 = proxy.create("de.cursor.jevi.server.web.Field")
field1.setName("MatchCode.Customer")
field1.setIdentifyingField(false)
def fieldvalue1 = proxy.create("de.cursor.jevi.server.web.ValidFieldValue")
fieldvalue1.setStringValue("CUSTOMER MATCHCODE")
field1.setFieldValue(fieldvalue1)
entry.getField().add(field1)
def field2 = proxy.create("de.cursor.jevi.server.web.Field")
field2.setName("CustomerNo1.Customer")
field2.setIdentifyingField(false)
def fieldvalue2 = proxy.create("de.cursor.jevi.server.web.ValidFieldValue")
fieldvalue2.setStringValue("001")
field2.setFieldValue(fieldvalue2)
entry.getField().add(field2)
def field3 = proxy.create("de.cursor.jevi.server.web.Field")
field3.setName("CustomerNo2.Customer")
field3.setIdentifyingField(false)
def fieldvalue3 = proxy.create("de.cursor.jevi.server.web.ValidFieldValue")
fieldvalue3.setStringValue("001")
field3.setFieldValue(fieldvalue3)
entry.getField().add(field3)
def field4 = proxy.create("de.cursor.jevi.server.web.Field")
field4.setName("Name1.Customer")
field4.setIdentifyingField(false)
def fieldvalue4 = proxy.create("de.cursor.jevi.server.web.ValidFieldValue")
fieldvalue4.setStringValue("Customer")
field4.setFieldValue(fieldvalue4)
entry.getField().add(field4)
def field5 = proxy.create("de.cursor.jevi.server.web.Field")
field5.setName("Name2.Customer")
field5.setIdentifyingField(false)
def fieldvalue5 = proxy.create("de.cursor.jevi.server.web.ValidFieldValue")
fieldvalue5.setStringValue("Inc.")
field5.setFieldValue(fieldvalue5)
entry.getField().add(field5)
def field8 = proxy.create("de.cursor.jevi.server.web.Field")
field8.setName("Website.Customer")
field8.setIdentifyingField(false)
def fieldvalue8 = proxy.create("de.cursor.jevi.server.web.ValidFieldValue")
fieldvalue8.setStringValue("http://www.example.org")
field8.setFieldValue(fieldvalue8)
entry.getField().add(field8)
def field22 = proxy.create("de.cursor.jevi.server.web.Field")
field22.setName("CustTypeKey.Customer")
field22.setIdentifyingField(false)
field22.setClearUnknown(true)
def fieldvalue22 = proxy.create("de.cursor.jevi.server.web.ValidFieldValue")
fieldvalue22.setStringValue("INTERESSENT")
field22.setFieldValue(fieldvalue22)
entry.getField().add(field22)
def config = proxy.create("de.cursor.jevi.server.web.Config")
config.setTransactionTime(300)
config.setTestRun(false)
entries.setConfig(config)
def result = proxy.importXML(parameters)
Response - importXML
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns3:importXMLResponse xmlns:ns2="http://job.xml.common.jevi.cursor.de/" xmlns:ns3="http://web.server.jevi.cursor.de/" xmlns:ns4="http://de.cursor.jevi.common.globalvariables/" xmlns:ns5="http://de.cursor.jevi.common.customizing/" xmlns:ns6="http://binding.search.common.jevi.cursor.de/" xmlns:ns7="http://de.cursor.jevi.common.keys/" xmlns:ns8="http://variable.process.common.jevi.cursor.de/">
<return success="true">
<Config transactionTime="300" testRun="false"/>
<Entry action="CREATE" found="ZERO" entity="Customer">
<CompletionType>SUCCESS</CompletionType>
<ModificationType>NO_MODIFICATION</ModificationType>
<PrimaryKeys>
<Pk value="123"/>
</PrimaryKeys>
<Field name="Pk.Customer" identifyingField="true">
<FieldValue>
<stringValue>123</stringValue>
</FieldValue>
</Field>
</Entry>
</return>
</ns3:importXMLResponse>
</soap:Body>
</soap:Envelope>
searchXML
Method name | searchXML |
---|---|
Input parameter | Object of type |
Output Parameter | Object of type |
WSDL | CrmWebService?wsdl |
Description | This service is equivalent to |
Request searchXML
def parameters = proxy.create("de.cursor.jevi.server.web.SearchXML")
def search = proxy.create("de.cursor.jevi.server.web.SearchXML\$Search")
parameters.search = search
def extendedSearch = proxy.create("de.cursor.jevi.common.search.binding.ExtendedSearch")
search.extendedSearch.add(extendedSearch)
extendedSearch.setPK("")
extendedSearch.setPlainKey("GeneratedDefaultSearchForActivity")
extendedSearch.setDescription("")
extendedSearch.setQuickSearch(false)
extendedSearch.setIgnoreCase(true)
def query = proxy.create("de.cursor.jevi.common.search.binding.Query")
extendedSearch.query.add(query)
def subQuery = proxy.create("de.cursor.jevi.common.search.binding.SubQuery")
query.setSubQuery(subQuery)
subQuery.setOperator("de.cursor.jevi.common.search.Operator\$AndOperator")
subQuery.setEntityName("Activity")
subQuery.setSubQueryInSearchResult(true)
subQuery.setRelationName("")
def condition = proxy.create("de.cursor.jevi.common.search.binding.Condition")
subQuery.getConditionOrSubQuery().add(condition)
condition.setAttributeName("Subject.Activity")
condition.setSearchResultField(true)
def function = proxy.create("de.cursor.jevi.common.search.binding.Function")
condition.setFunction(function)
function.setFunctionClassName("de.cursor.jevi.common.search.function.LikeFunction")
function.setNumberOfParameters(1)
def functionParameter = proxy.create("de.cursor.jevi.common.search.binding.Parameter")
function.getParameterOrParameterLookupVO().add(functionParameter)
functionParameter.setParameterValue("v")
functionParameter.setParameterClassName("java.lang.String")
def result = proxy.searchXML(parameters)
Response - searchXML
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns3:searchXMLResponse xmlns:ns2="http://job.xml.common.jevi.cursor.de/" xmlns:ns3="http://web.server.jevi.cursor.de/" xmlns:ns4="http://de.cursor.jevi.common.globalvariables/" xmlns:ns5="http://de.cursor.jevi.common.customizing/" xmlns:ns6="http://binding.search.common.jevi.cursor.de/" xmlns:ns7="http://de.cursor.jevi.common.keys/" xmlns:ns8="http://variable.process.common.jevi.cursor.de/">
<return success="false">
<Config transactionTime="300" version="1.0" testRun="false"/>
<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
<FieldValue>
<stringValue>Vertragsverlaengerung</stringValue>
</FieldValue>
</Field>
</Entry>
<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
<FieldValue>
<stringValue>Vertragsverlaengerung</stringValue>
</FieldValue>
</Field>
</Entry>
<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
<FieldValue>
<stringValue>Vertragsverlaengerung angenommen</stringValue>
</FieldValue>
</Field>
</Entry>
</return>
</ns3:searchXMLResponse>
</soap:Body>
</soap:Envelope>
searchXMLWithParams
Method name | searchXMLWithParams |
---|---|
Input parameter | Object of type |
Output Parameter | Object of type |
WSDL | CrmWebService?wsdl |
Description | This service is equivalent to searchXMLWithParams from |
Request - searchXMLWithParams
def parameters = proxy.create("de.cursor.jevi.server.web.SearchXMLWithParams")
parameters.searchName = "ActivitiesWithParams"
parameters.getParams().add("v") // Template "Subject.Activity"
parameters.getParams().add("A") // Template "ActStatusKey.Activity
def result = proxy.searchXMLWithParams(parameters)
Response - searchXMLWithParams
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns3:searchXMLWithParamsResponse xmlns:ns2="http://job.xml.common.jevi.cursor.de/" xmlns:ns3="http://web.server.jevi.cursor.de/" xmlns:ns4="http://de.cursor.jevi.common.globalvariables/" xmlns:ns5="http://de.cursor.jevi.common.customizing/" xmlns:ns6="http://binding.search.common.jevi.cursor.de/" xmlns:ns7="http://de.cursor.jevi.common.keys/" xmlns:ns8="http://variable.process.common.jevi.cursor.de/">
<return success="false">
<Config transactionTime="300" version="1.0" testRun="false"/>
<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
<FieldValue>
<stringValue>Vertragsverlaengerung</stringValue>
</FieldValue>
</Field>
<Field name="ActStatusKey.Activity" fieldType="PK" identifyingField="false">
<FieldValue>
<stringValue>S_ACTSTATUS-A</stringValue>
</FieldValue>
</Field>
</Entry>
<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
<FieldValue>
<stringValue>Vertragsverlaengerung angenommen</stringValue>
</FieldValue>
</Field>
<Field name="ActStatusKey.Activity" fieldType="PK" identifyingField="false">
<FieldValue>
<stringValue>S_ACTSTATUS-A</stringValue>
</FieldValue>
</Field>
</Entry>
</return>
</ns3:searchXMLWithParamsResponse>
</soap:Body>
</soap:Envelope>
searchXMLOrderBy
Method name | searchXMLOrderBy |
---|---|
Input parameter | Object of type |
Output Parameter | Object of type |
WSDL | CrmWebService?wsdl |
Description | This service is an extension of |
Request - searchXMLOrderBy
def parameters = proxy.create("de.cursor.jevi.server.web.SearchXMLOrderBy")
def search = proxy.create("de.cursor.jevi.server.web.SearchXMLOrderBy\$Search")
parameters.search = search
def extendedSearch = proxy.create("de.cursor.jevi.common.search.binding.ExtendedSearch")
search.extendedSearch.add(extendedSearch)
extendedSearch.setPK("")
extendedSearch.setPlainKey("GeneratedDefaultSearchForActivity")
extendedSearch.setDescription("")
extendedSearch.setQuickSearch(false)
extendedSearch.setIgnoreCase(true)
def query = proxy.create("de.cursor.jevi.common.search.binding.Query")
extendedSearch.query.add(query)
def subQuery = proxy.create("de.cursor.jevi.common.search.binding.SubQuery")
query.setSubQuery(subQuery)
subQuery.setOperator("de.cursor.jevi.common.search.Operator\$AndOperator")
subQuery.setEntityName("Activity")
subQuery.setSubQueryInSearchResult(true)
subQuery.setRelationName("")
def condition = proxy.create("de.cursor.jevi.common.search.binding.Condition")
subQuery.getConditionOrSubQuery().add(condition)
condition.setAttributeName("Subject.Activity")
condition.setSearchResultField(true)
def function = proxy.create("de.cursor.jevi.common.search.binding.Function")
condition.function = function
function.setFunctionClassName("de.cursor.jevi.common.search.function.LikeFunction")
function.setNumberOfParameters(1)
def functionParameter = proxy.create("de.cursor.jevi.common.search.binding.Parameter")
function.getParameterOrParameterLookupVO().add(functionParameter)
functionParameter.setParameterValue("a")
functionParameter.setParameterClassName("java.lang.String")
def searchOrder = proxy.create("de.cursor.jevi.server.web.SearchOrder")
parameters.searchOrder = searchOrder
def searchOrderEntry = proxy.create("de.cursor.jevi.server.web.SearchOrderEntry")
searchOrder.searchOrderEntry.add(searchOrderEntry)
searchOrderEntry.attributeName = "Subject.Activity"
searchOrderEntry.order = proxy.create("de.cursor.jevi.server.web.OrderType").ASCENDING
searchOrderEntry.searchSortOrder = proxy.create("de.cursor.jevi.server.web.OrderType").ASCENDING
def result = proxy.searchXMLOrderBy(parameters)
Response - searchXMLOrderBy
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns3:searchXMLOrderByResponse xmlns:ns2="http://job.xml.common.jevi.cursor.de/" xmlns:ns3="http://web.server.jevi.cursor.de/" xmlns:ns4="http://de.cursor.jevi.common.globalvariables/" xmlns:ns5="http://de.cursor.jevi.common.customizing/" xmlns:ns6="http://binding.search.common.jevi.cursor.de/" xmlns:ns7="http://de.cursor.jevi.common.keys/" xmlns:ns8="http://variable.process.common.jevi.cursor.de/">
<return success="false">
<Config transactionTime="300" version="1.0" testRun="false"/>
<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
<FieldValue>
<stringValue>Anfrage #123 Aktivität zu Täpper bei Somentec</stringValue>
</FieldValue>
</Field>
</Entry>
<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
<FieldValue>
<stringValue>Anfrage #123 Aktivität zu Täpper bei Somentec</stringValue>
</FieldValue>
</Field>
</Entry>
<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
<FieldValue>
<stringValue>Anfrage #133 Aktivität zu Täpper bei ENTEGA</stringValue>
</FieldValue>
</Field>
</Entry>
<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
<FieldValue>
<stringValue>Anfrage #133 Aktivität zu Täpper bei TäPPER HANS</stringValue>
</FieldValue>
</Field>
</Entry>
<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
<FieldValue>
<stringValue>Angebot</stringValue>
</FieldValue>
</Field>
</Entry>
<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
<FieldValue>
<stringValue>Angebotsversand</stringValue>
</FieldValue>
</Field>
</Entry>
<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
<FieldValue>
<stringValue>Antwort von Meyer mit Link zum VL</stringValue>
</FieldValue>
</Field>
</Entry>
</return>
</ns3:searchXMLOrderByResponse>
</soap:Body>
</soap:Envelope>
searchXMLWithParamsOrderBy
Method name | searchXMLWithParamsOrderBy |
---|---|
Input parameter | Object of type |
Output Parameter | Object of type |
WSDL | CrmWebService?wsdl |
Description | This service is an extension of |
Request - searchXMLWithParamsOrderBy
def parameters = proxy.create("de.cursor.jevi.server.web.SearchXMLWithParamsOrderBy")
parameters.searchName = "ActivitiesWithParams"
parameters.getParams().add("v") // Template "Subject.Activity"
parameters.getParams().add("A") // Template "ActStatusKey.Activity"
def searchOrder = proxy.create("de.cursor.jevi.server.web.SearchOrder")
parameters.searchOrder = searchOrder
def searchOrderEntry = proxy.create("de.cursor.jevi.server.web.SearchOrderEntry")
searchOrder.searchOrderEntry.add(searchOrderEntry)
searchOrderEntry.attributeName = "Subject.Activity"
searchOrderEntry.order = proxy.create("de.cursor.jevi.server.web.OrderType").ASCENDING
searchOrderEntry.searchSortOrder = proxy.create("de.cursor.jevi.server.web.OrderType").ASCENDING
def result = proxy.searchXMLWithParamsOrderBy(parameters)
Response - searchXMLWithParamsOrderBy
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns3:searchXMLWithParamsOrderByResponse xmlns:ns2="http://job.xml.common.jevi.cursor.de/" xmlns:ns3="http://web.server.jevi.cursor.de/" xmlns:ns4="http://de.cursor.jevi.common.globalvariables/" xmlns:ns5="http://de.cursor.jevi.common.customizing/" xmlns:ns6="http://binding.search.common.jevi.cursor.de/" xmlns:ns7="http://de.cursor.jevi.common.keys/" xmlns:ns8="http://variable.process.common.jevi.cursor.de/">
<return success="false">
<Config transactionTime="300" version="1.0" testRun="false"/>
<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
<FieldValue>
<stringValue>Vertragsverlaengerung</stringValue>
</FieldValue>
</Field>
<Field name="ActStatusKey.Activity" fieldType="PK" identifyingField="false">
<FieldValue>
<stringValue>S_ACTSTATUS-A</stringValue>
</FieldValue>
</Field>
</Entry>
<Entry action="CREATE" found="NO_SEARCH" entity="Activity">
<Field name="Subject.Activity" fieldType="VALUE" identifyingField="false">
<FieldValue>
<stringValue>Vertragsverlaengerung angenommen</stringValue>
</FieldValue>
</Field>
<Field name="ActStatusKey.Activity" fieldType="PK" identifyingField="false">
<FieldValue>
<stringValue>S_ACTSTATUS-A</stringValue>
</FieldValue>
</Field>
</Entry>
</return>
</ns3:searchXMLWithParamsOrderByResponse>
</soap:Body>
</soap:Envelope>
REST interface for document handling
Using Web service calls, it is possible to receive documents from the CRM system and transfer them to the CRM system.
Service documentation https://carmenbig.cursor.de:18443/rest/doc/v1/services/document
Action | Method | URL | Parameter | Result |
---|---|---|---|---|
creation | POST | https://server.baseUrl/rest/api/document/v1/documents?documentName=<documentName> | documentName QUERY, document FORM-DATA | {"documentPk":"fvvvvvuov9tr21bsa6pc7qDo","name":"Doppelter-Haupt_AP.jpg","updateDate":"2017-10-13T07:12:21Z","size":163938}DocumentMetaDataDTO |
read | GET | https://server.baseUrl/rest/api/document/v1/documents/<documentPk>/read | documentPk PATH | binary |
edit | GET | https://server.baseUrl/rest/api/document/v1/documents/<documentPk>/edit | documentPk PATH | binary |
return | POST | https://server.baseUrl/rest/api/document/v1/documents/<documentPk>/return?documentName=<documentName> | documentName QUERY, document FORM-DATA | {"documentPk":"fvvvvvuov9tr21bsa6pc7qDo","name":"Doppelter-Haupt_AP.jpg","updateDate":"2017-10-13T07:12:21Z","size":163938}DocumentMetaDataDTO |
discard | GET | https://server.baseUrl/rest/api/document/v1/documents/<documentPk>/discard | dokumentPk PATH | {"documentPk":"fvvvvvuov9tr21bsa6pc7qDo","name":"Doppelter-Haupt_AP.jpg","updateDate":"2017-10-13T07:12:21Z","size":163938}DocumentMetaDataDTO |
Web service for receiving time events
Time events can be stored in the CRM via Rest Service.
URL:
/rest/api/event/v1/events
Documentation:
/rest/doc/v1/services/event
The call as POST can be given the type of event, optionally the time (default is the time of the call) and a payload in JSON format. The eventType
is a technical identifier of the time event and should be structured as follows:
<Top-Level-Domain>.<Second-Level-Domain>.<technical identifier> → de.cursor.portalAccess, org.company.calculation
{
"eventType" : "domain.myEventType",
"payload" : {
"key1" : "stringValue",
"key2" : 1987,
"key3" : true
}
}
An alternative service URL has been provided to simplify the call:
URL: /rest/api/event/v1/events/type/{eventType}
Example: /rest/api/event/v1/events/type/domain.myEventType
{
"key1" : "stringValue",
"key2" : 1987,
"key3" : true
}
Additional parameters in the URL can be used to provide the services with further options. (Example: /rest/api/event/v1/events/type/domain.myEventType?async=true¶llel=true)
dateTime: The date of the event is determined from the current system time by default. This parameter can be used to overwrite the date in ISO-8601 format.
async: Can be activated with the value "true". The event is placed in a queue and checked. The event is processed asynchronously.
parallel: With asynchronous execution of events, the order between service call and execution remains stable. To speed up the processing of events, processing can be parallelized. The order of these events is then no longer certain.
Only with asynchronous processing can an order of events be controlled. With synchronous, direct processing, individual service calls are not synchronized with each other.
This call creates a time event in the clipboard. The data can be viewed by the administrator.
![](../../../__attachments/69206427/EventArchive_AdminMenu.png?inst-v=01ce9f95-f40d-424e-a7da-0f3a4bad5824)
Each event can be checked using the C0Event.check()
method. The check also takes place during asynchronous processing directly when the service is called.
The further processing logic of the events is triggered synchronously in the script library under C0Event.process()
.
It is important to ensure that the checking of events is implemented with high performance. If the check of an event exceeds a period of 50 ms, a message is sent to the system administrator.
The methods of the script library can be overridden and extended in the client layer.
SC0Event
@BpmScript @Released @Override
private Boolean check(String eventType, Map<String, Object> payloadRequest, Map<String, Object> payloadResponse)
{
// ...
return super.check(eventType, payloadRequest, payloadResponse);
}
@BpmScript @Released @Override
private void process(String eventPk, Date eventDate, String eventType, Map<String,Object> payloadRequest, Map<String,Object> payloadResponse)
{
// ...
super.process(eventPk, eventDate, eventType, payloadRequest, payloadResponse);
}
In the script class, you can react to the type of the time event to trigger customer-specific processing logic. The type can be freely selected by the caller or predefined in the key range "Time event type". The call contains the following parameters:
eventPk
: The primary key for the dataset of the time eventeventDate
: The time of the time eventeventType
: The key to selecting the logicpayloadRequest
: A map with the values from the payload of the Rest ServicepayloadResponse
: A map for the return of results of the logics to the caller
A predefined logic is the "CreateActivity
" type. This allows the rapid new creation of activities by the service. The fields of the activity can be preassigned in the payload.
CreateActivity: Request
{
"eventType": "CreateActivity",
"payload": {
"myfield1": "myValue1",
"Activity": {
"Subject": "Mein Betreff",
"Text.Activity": "<html><body><p>Mein Text</p></boby></html>",
"StartDate": "2020-02-02T20:20:20+01:00", // optional
"EndDate": "2020-02-02T20:35:20+01:00", // optional
"ActStatusKey": "S_ACTTYPE-E",
"ActTypeKey": "S_ACTSTATUS-O",
"DelegatedBy": "ged-personpkTechUser#TechUser",
"DelegatedTo": "ged-personpkTechUser#TechUser",
"IsTaskRead": true,
"ContactCosts": 1,
"FreeNumber1": 1.23456789
}
}
}
The definition of the activity must be stored under the value "Activity". For the conversion from Map to IContainer the WorkSpaceScriptUtils.converToIContainer()
method is used. The start and end dates are preset by default with the time of the event. The primary key of the event and activity is returned as the result.
CreateActivity: Response
{
"id": "fvvvvvucldhsc1e11vhi8iEvAr",
"status": "DONE",
"payload": {
"Activity": {
"Pk.Activity": "1vlq1uh1e11vhideAc"
}
}
}
If a link between time event and activity is desired, a C2 lookup field must be excluded in the activity and the logic in the script method must be overridden
C0Event.createEntity
entityMap.put("C2EventKey", eventPk); //Neues C2-Feld in Aktivitäten aufnehmen
super.createEntity(eventPk, eventDate, entityName, entityMap, payloadResponse)
Dynamic addressing of different URLs in web services
A web service call in the CRM system can be used dynamically in such a way that different URLs can be addressed with one web service.
For example, in order to distinguish the web service configuration between development system, QA system and production system, the WSDL definition can now be outsourced to a global variable.
![](../../../__attachments/69206427/CRM-12066_GlobalVariable_URL.png?inst-v=01ce9f95-f40d-424e-a7da-0f3a4bad5824)
It is possible to store the URL for the WSDL definition as well as the entire XML definition in XML format, in which the URL for the service is stored.
![](../../../__attachments/69206427/CRM-12066_GlobalVariable_XML.png?inst-v=01ce9f95-f40d-424e-a7da-0f3a4bad5824)
During the new creation of a web service, the global variable can now also be selected as an option to the URL or file. The availability check and service creation can then be performed as usual.
![](../../../__attachments/69206427/CRM-12066_WebService.png?inst-v=01ce9f95-f40d-424e-a7da-0f3a4bad5824)
After the customizing transport of the global variable and the web service definition, in the other systems only the URL in the global variable of the service must be adjusted.
![](../../../__attachments/69206427/CRM-12066_WebServiceTest.png?inst-v=01ce9f95-f40d-424e-a7da-0f3a4bad5824)