This documentation applies to older versions of WSO2 ESB connectors. To find the documentation relevant to the version you are using, select the connector from the WSO2 Connector Store and click Documentation.

All docs This doc
Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 12 Next »

This section walks you through the basic structure of a connector and describes how you can write your own connector based on the API you have decided to use.

The basic structure of a connector

Use your IDE to create a Maven project, and create a directory structure similar to the following:

Folder Structure

1connector.xmlThis defines the connector name and dependant modules. (i.e., the metadata of the connector)
2component.xmlThis is included in each module, and defines the available methods in the module.
3init.xmlThis is mandatory for every connector By using this, you can initialize the connector environment. For example, when writing the Salesforce connector, login call can be included here. Sessiontoken and API URL returned as the response can be stored in a property and used with other operations.
4assemble-connector.xml/filter.propertiesThese files are used at the connector build time. You do not need to modify this file.
5pom.xmlThis contains the required dependencies for the connector core libraries, relevant synapse libraries as well as maven repositories for a specific connector.
6<operation-name>.xmlThis is the actual API operation calling configuration. This contains the steps necessary to call the API that is exposed by the third party. Each method of the API can be written in a manner similar to init.xml. If there is any Java code, the code should be included under Java and the relevant dependencies should be added to pom.xml

You can create the required template using the maven archetype https://github.com/wso2-extensions/archetypes/tree/master/esb-connector-archetype, using the following command:

mvn archetype:generate -DarchetypeGroupId=org.wso2.carbon.extension.archetype -DarchetypeArtifactId=org.wso2.carbon.extension.archetype.esb.connector-archetype -DarchetypeVersion=1.0.0  -DgroupId=org.wso2.carbon.esb.connector -DartifactId=org.wso2.carbon.esb.connector.test -Dversion=1.0.0 -DarchetypeRepository=http://maven.wso2.org/nexus/content/repositories/wso2-public/

Now that you understand the basic structure of a connector, you can start writing your own connector, which can either be a soap-based connector, REST-based connector or a JAVA API-based connector. 

SOAP-based connectors

If you are writing a SOAP API based connector, you can write the entire connector with Synapse configurations. You can create a maven project in your preferred IDE with a folder structure as described above. See The basic structure of a connector.

Following is an example of a SOAP-based connector that is written for Salesforce in order to execute the query method of the API:

<templatename="query"xmlns="http://ws.apache.org/ns/synapse">
 <parametername="sessionId"/>
 <parametername="url"/>
 <parametername="queryString"/>
 <sequence>
  <payloadFactory>
   <format>
    <soapenv:Envelopexmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"xmlns:urn="urn:partner.soap.sforce.com">
     <soapenv:Header>
      <urn:SessionHeader>
       <urn:sessionId>$1</urn:sessionId>
      </urn:SessionHeader>
     </soapenv:Header>
     <soapenv:Body>
      <urn:query>
       <urn:queryString>$2</urn:queryString>
      </urn:query>
     </soapenv:Body>
    </soapenv:Envelope>
   </format>
   <args>
    <argexpression="$func:sessionId"/>
    <argexpression="$func:queryString"/>
   </args>
  </payloadFactory>
  <propertyname="messageType"scope="axis2"value="text/xml"/>
  <headername="Action"value="urn:partner.soap.sforce.com/Soap/queryRequest"/>
  <propertyvalue="true"name="FORCE_ERROR_ON_SOAP_FAULT"/>
  <propertyname="HTTP_METHOD"scope="axis2"value="POST"/>
  <headername="To"expression="$func:url"/>
  <call>
   <endpoint>
    <defaultformat="soap11">
     <timeout>
      <duration>60000</duration>
      <responseAction>fault</responseAction>
     </timeout>
     <suspendOnFailure>
      <initialDuration>2000</initialDuration>
      <progressionFactor>1.0</progressionFactor>
      <maximumDuration>3000</maximumDuration>
     </suspendOnFailure>
    </default>
   </endpoint>
  </call>   
 </sequence>
</template>

Here the required payload is created using the PayloadFactory Mediator and the request is sent using the Call Mediator.

REST-based connectors

You can write a REST-based connector in a manner very much similar to how you write a SOAP-based connector. The only difference is the underlying communication mechanism. You can basically write a REST-based connector by using synapse configurations similar to SOAP-based connector.

Following is an example of a SOAP-based connector calling the Twitter rest API:

< template xmlns = "http://ws.apache.org/ns/synapse" name = "search" >
  < parameter name = "search" />
  < parameter name = "accessToken" />
   < sequence >
    < property name = "uri.var.twitter.search" expression = "$func:search" />
    < property name = "Authorization" expression = "$func:accessToken" scope = "transport" />
    < property name = "messageType" value = "application/x-www-form-urlencoded" scope = "axis2" />
    < payloadFactory media-type = "xml" >
     < format >
      < soapenv:Envelope 
                  xmlns:soapenv
                 = "http://schemas.xmlsoap.org/soap/envelope/" >
       < soapenv:Header />
       < soapenv:Body />
      </ soapenv:Envelope >
     </ format >
     < args />
    </ payloadFactory >
   < call >
    < endpoint >
     < http method = "GET" uri-template = "https://api.twitter.com/1.1/search/tweets.json?q={uri.var.twitter.search}" />
    </ endpoint >
   </ call >
  </ sequence >
</ template >

Java API-based connectors

If you are writing a Java API-based connector, you have to use a custom class mediator to implement it. You need to extend the AbstractConnector class and implement its connect method. All the required logic must be done within this method. Once you have implemented this method, you can call the method using the synapse configuration, which is in the .xml file.

Following is an example of a connector Java class written for Twilio in order to send an SMS:

 import java.util.HashMap;
import java.util.Map;
import org.apache.axiom.om.OMElement;
import org.apache.synapse.MessageContext;
import org.apache.synapse.SynapseException;
import org.apache.synapse.SynapseLog;
import org.wso2.carbon.connector.core.AbstractConnector;
import org.wso2.carbon.connector.core.util.ConnectorUtils;
import org.wso2.carbon.connector.twilio.util.TwilioUtil;
import com.twilio.sdk.TwilioRestClient;
import com.twilio.sdk.resource.factory.SmsFactory;
import com.twilio.sdk.resource.instance.Sms;
public class SendSms extends AbstractConnector {
  public void connect(MessageContext messageContext) {
   SynapseLog log = getLog(messageContext);
   log.auditLog("Start: send SMS");
   String to =  (String) ConnectorUtils.lookupTemplateParamater(messageContext, TwilioUtil.PARAM_TO);
   String from = (String) ConnectorUtils.lookupTemplateParamater(messageContext, TwilioUtil.PARAM_FROM);
   String body = (String) ConnectorUtils.lookupTemplateParamater(messageContext, TwilioUtil.PARAM_BODY);
   String statusCallBackUrl = (String) ConnectorUtils.lookupTemplateParamater(messageContext, TwilioUtil.PARAM_STATUS_CALLBACK_URL);
   String applicationSid = (String) ConnectorUtils.lookupTemplateParamater(messageContext, TwilioUtil.PARAM_APPLICATION_SID);
   Map< string ,  string = "" > params = new HashMap< string ,  string = "" >();
   params.put(TwilioUtil.TWILIO_TO, to);
   params.put(TwilioUtil.TWILIO_FROM, from);
   params.put(TwilioUtil.TWILIO_BODY, body);
   if (applicationSid != null) {
    params.put(TwilioUtil.TWILIO_APPLICATION_SID, applicationSid);
   }
   if (statusCallBackUrl != null) {
    params.put(TwilioUtil.TWILIO_STATUS_CALLBACK, statusCallBackUrl);
   }
   try {
    TwilioRestClient twilioRestClient = TwilioUtil.getTwilioRestClient(messageContext);
    SmsFactory messageFactory = twilioRestClient.getAccount().getSmsFactory();
    Sms message = messageFactory.create(params);
    OMElement omResponse = TwilioUtil.parseResponse("sms.create.success");
    TwilioUtil.addElement(omResponse, TwilioUtil.PARAM_MESSAGE_SID, message.getSid());
    TwilioUtil.addElement(omResponse, TwilioUtil.PARAM_STATUS, message.getStatus());
    TwilioUtil.preparePayload(messageContext, omResponse);
   } catch (Exception e) {
    log.error(e.getMessage());
    messageContext.setProperty(SynapseConstants.ERROR_EXCEPTION, e);
    messageContext.setProperty(SynapseConstants.ERROR_MESSAGE, e.getMessage());
    messageContext.setProperty(SynapseConstants.ERROR_CODE, "0007");
    throw new SynapseException(e);
   }
   log.auditLog("End: send SMS");
  }
}
</ string ,></ string ,>

 

Following is the associated sendSms.xml that calls the class mediator:

< template name = "sendSms" xmlns = "http://ws.apache.org/ns/synapse" >
  < parameter name = "body" />
  < parameter name = "to" />
  < parameter name = "from" />
  < parameter name = "statusCallBackUrl" />
  < parameter name = "applicationSid" />
  < sequence >
   < class name = "org.wso2.carbon.connector.twilio.sms.SendSms" />
  </ sequence >
</ template >

Now that you understand how to create each type of connector, you can start writing your own connector that can either be a soap-based connector, REST-based connector or a JAVA API-based connector.

  • No labels