Exact Target Client in Java

      5 Comments on Exact Target Client in Java

Disclaimer – Most of the code in this post are from the code samples provided by Exact Target. I have encountered little difficulties in using the code samples. Therefore I am writing this post to document how I made it work finally. Hope it helps.

Recently, We have implemented Grails/Java client for Exact Target .net webservices. We have use Axis 1.4 to generate the exact target client. ET provides very good samples and examples. Our implementation was derived from one of the sample project they have provided.

Important Note: Exact Target has released new version of webservices recently. If that is the case then this post may not be of much help. This post is based on the following environment. If your environment is different then YMMV.

Java 5+, Axis 1.4, Exact Target Partner API 1.0, Apache Ant

These are the steps we have followed

i) Create a new java project and have the structure similar to this

Few files to take note of.

  • build.xml
  • etframework.wsdl
  • Code generated by wsdl2java will be in src/com.exacttarget.wsdl.partnerapi package
  • com.exacttarget.samples.Axisv14.client.ClientTest is used to test the client and com.exacttarget.samples.Axisv14.client.PWCBHandler is the implementation of Password Callback Handler
  • jars in the lib folder . These jars may be required to make things work.
  • client_deploy.wsdd is used by the framework
  • Generated client jar will be put in dist/lib/ folder
  • Folder build/com will have the compiled classes.

Normal java project stuff. Shouldn’t be new to you!

Now let’s get our hands dirty

ii) Open the PWCBHandler.java and update your api username and password


/*
 * Copyright 2004,2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.exacttarget.samples.Axisv14.client;

import java.io.IOException;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.WSPasswordCallback;

/**
 * Modified WSS4J callback handler to accept user and password information from properties file via ClientTest.
 * The original class from Apache required hard-coded values for this information. This class may be further
 * modified for production usage so that this information is fetched from any external store, such as a database.
 *
 * @author Erik Gfesser
 */
public class PWCBHandler implements CallbackHandler {
 public static String user = "myusername";
 public static String password = "mypassword";

 public void handle(Callback[] callbacks) throws IOException,
 UnsupportedCallbackException {

 for (int i = 0; i < callbacks.length; i++) {
 if (callbacks[i] instanceof WSPasswordCallback) {
 WSPasswordCallback pwcb = (WSPasswordCallback)callbacks[i];
 String id = pwcb.getIdentifer();
 if(user.equals(id)) {
 pwcb.setPassword(password);
 }
 } else {
 throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
 }
 }
 } //end method handle
} //end class PWCBHandler

For your reference here is how client_deploy.wsdd looks like

<?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<transport name="http" pivot="java:org.apache.axis.transport.http.HTTPSender"/>
<globalConfiguration>
 <requestFlow>
 <handler type="java:org.apache.ws.axis.security.WSDoAllSender">
 <parameter name="action" value="UsernameToken"/>
 <parameter name="user" value="myuserid"/>
 <parameter name="passwordCallbackClass" value="com.exacttarget.samples.Axisv14.client.PWCBHandler"/>
 <parameter name="passwordType" value="PasswordText"/>
 </handler>
 </requestFlow>
</globalConfiguration>
</deployment>

And last but not the least, here is the build.xml

<project basedir=".">
 <property name="build.dir" value="build"/>
 <property name="lib.dir" value="lib"/>
 <property name="resources.dir" value="resources"/>
 <property name="src.dir" value="src"/>
 <property name="dist.dir" value="dist"/>

 <path id="axis.jaf.javamail.wss4j.xmlsec.xerces.lib.classpath">
 <fileset dir="${lib.dir}">
 <include name="*.jar"/>
 </fileset>
 </path>

 <path id="client.lib.classpath">
 <fileset dir="${dist.dir}/lib" >
 <include name="*.jar" />
 </fileset>
 </path>

 <target name="init">
 <mkdir dir="${build.dir}"/>
 <mkdir dir="${dist.dir}/lib"/>
 </target>

 <target name="generate.client" depends="init">
 <taskdef resource="axis-tasks.properties"
 classpathref="axis.jaf.javamail.wss4j.xmlsec.xerces.lib.classpath"/>
 <axis-wsdl2java url="${resources.dir}/META-INF/etframework.wsdl"
 output="${src.dir}"
 verbose="false"
 debug="false">
 <mapping namespace="http://exacttarget.com/wsdl/partnerAPI"
 package="com.exacttarget.wsdl.partnerapi" />
 </axis-wsdl2java>
 </target>

 <target name="compile.client">
 <javac destdir="${build.dir}"
 debug="true"
 failonerror="true">
 <src path="${src.dir}"/>
 <classpath refid="axis.jaf.javamail.wss4j.xmlsec.xerces.lib.classpath"/>
 </javac>
 <jar destfile="${dist.dir}/lib/mysample-exacttarget-client-1.0.jar"
 basedir="${build.dir}/">
 </jar>
 </target>

 <target name="generate.compile.client" depends="generate.client,compile.client"/>

 <target name="clean">
 <delete dir="${build.dir}"/>
 </target>
</project>

iii) Run ant generate.client to generate the client classes. This target uses wsdl2java to generate java code from wsdl. After
this target is successfully run you should see java classes under com.exacttarget.wsdl.partnerapi package

iii) Now you should try to test the generated client. We will make use of ClientTest.java for the same. Here is a part of ClientTest.java
I have. Again the basic templated was given by ET itself

package com.exacttarget.samples.Axisv14.client;

import java.io.FileInputStream;
import java.rmi.RemoteException;
import java.util.Properties;

import javax.xml.rpc.ServiceException;

import org.apache.axis.EngineConfiguration;
import org.apache.axis.configuration.FileProvider;

import com.exacttarget.wsdl.partnerapi.APIObject;
import com.exacttarget.wsdl.partnerapi.Attribute;
import com.exacttarget.wsdl.partnerapi.CreateOptions;
import com.exacttarget.wsdl.partnerapi.CreateRequest;
import com.exacttarget.wsdl.partnerapi.CreateResponse;
import com.exacttarget.wsdl.partnerapi.CreateResult;
import com.exacttarget.wsdl.partnerapi.DefinitionRequestMsg;
import com.exacttarget.wsdl.partnerapi.DefinitionResponseMsg;
import com.exacttarget.wsdl.partnerapi.Email;
import com.exacttarget.wsdl.partnerapi.List;
import com.exacttarget.wsdl.partnerapi.ListSubscriber;
import com.exacttarget.wsdl.partnerapi.ObjectDefinition;
import com.exacttarget.wsdl.partnerapi.ObjectDefinitionRequest;
import com.exacttarget.wsdl.partnerapi.Owner;
import com.exacttarget.wsdl.partnerapi.PartnerAPI;
import com.exacttarget.wsdl.partnerapi.PartnerAPILocator;
import com.exacttarget.wsdl.partnerapi.RetrieveRequest;
import com.exacttarget.wsdl.partnerapi.RetrieveRequestMsg;
import com.exacttarget.wsdl.partnerapi.RetrieveResponseMsg;
import com.exacttarget.wsdl.partnerapi.Send;
import com.exacttarget.wsdl.partnerapi.SimpleFilterPart;
import com.exacttarget.wsdl.partnerapi.SimpleOperators;
import com.exacttarget.wsdl.partnerapi.Soap;
import com.exacttarget.wsdl.partnerapi.Subscriber;
import com.exacttarget.wsdl.partnerapi.TriggeredSend;
import com.exacttarget.wsdl.partnerapi.TriggeredSendCreateResult;
import com.exacttarget.wsdl.partnerapi.TriggeredSendDefinition;

/**
 * Example to show Axis 1.4 usage pattern as a client to invoke services from
 * ExactTarget Integration Framework Web Service API endpoint.
 *
 * @author Erik Gfesser
 */
public class ClientTest {
 static String user = null;
 static String password = null;
 static String clientWSDD = null;
 static String customerKey = null;
 static String validEmailAddress = null;
 static String validSubscriberKey = null;
 static String validFromAddress = null;
 static String validFromName = null;
 static String invalidEmailAddress = null;
 static String invalidSubscriberKey = null;
 static String invalidFromAddress = null;
 static String invalidFromName = null;

 public static void main(String[] args) throws ServiceException,
 RemoteException {
 EngineConfiguration config = new FileProvider(clientWSDD);

 // Create PartnerAPI stub with ExactTarget Web Service API endpoint and
 // Axis configuration
 PartnerAPI service = new PartnerAPILocator(config);
 Soap stub = service.getSoap();

 testET( stub );

 } // end method main
}

In the testET method you can use any one of the ET API method to test the connectivity to the ET is working or not.

iv) If it works then you can generate the ET jar using compile.client ant target and you may use this jar as ET client in your target projects.

5 thoughts on “Exact Target Client in Java

  1. Chittedi

    Paras,
    Nice post just had a small question where do we put the username and password

    PWCBHandler.java or client_deploy.wsdd or ClientTest.java

    Thanks,
    Chittedi.

    Reply
    1. Paras

      Hi Chittedi,
      Thanks for the comments. As far as I remember your password will be in PWCBHandler.java. Refer to the code examples in my post.
      public static String password=”yourpasswordgoeshere”

      Reply
      1. Chittedi

        Thanks for the reply, I looked at the package again.

        Configuration files have the password,and the client just reads from the configuration file.

        client_deploy.wsdd has the username

        axisv14-client-test-properties.xml has the username(again) and password.

        Does anybody know, how to set it for multiple users instead of hardcoding the username, passwords in those configuration files.

        Thanks in advance..

        Reply
  2. Amit

    Hi Paras,

    This doesn’t show what testET function is doing? I am trying to trigger the createRequest event but not been able to. Can you please suggest what should be soap request to send the same.

    Thanks,
    Amit

    Reply
    1. Paras

      Hello Amit,
      Sorry for the late reply. I don’t have the test project I have setup to write this blog, but most likely in testET function you will call a Exact Target API method to test if your settings are working or not. The test project and testET method within it is just to test API method etc. In real projects you will inject this is as a service and call service methods to access ET API methods.

      Reply

Leave a Reply

Your email address will not be published. Required fields are marked *