1

I am looking to build a stand-alone ExactTarget SOAP client using CXF.

I was able to create a client using Glassfish Metro, but due to future support considerations we would like to use CXF. I found an old example and associated project, but it is too old to be useful.

Currently I am trying to understand how can I set a handler on the stub/port object and to pass dynamic username and password to it. By dynamic I mean: the app gets username and password from the user at the time of running. Here is the code that I currently have for the Metro implementation:

PartnerAPI service = new PartnerAPI();
Soap stub = service.getSoap();      
Map<String, Object> outProperties = new HashMap<String, Object>();        
Map ctx = ((BindingProvider) stub).getRequestContext();

requestContext.put(BindingProvider.USERNAME_PROPERTY, user);
requestContext.put(BindingProvider.PASSWORD_PROPERTY, password);

List<Handler> chain = new ArrayList<Handler>();
chain.add(new SecurityHandler());
((BindingProvider) stub).getBinding().setHandlerChain(chain);

I am trying to reuse the first 4-6 lines for the CXF implementation, but I cannot use the handlers I have since they depend on com.sun.xml.wss.XWSSProcessor.

  • 1
    If I understand this correctly, this is mostly about connecting to exacttarget from CXF, which is not really exacttarget specific ? Maybe your question is better asked at stackoverflow, which deals with development in a broader perspective ? – Samuel De Rycke Jan 28 '14 at 16:26
  • Ok, my thinking was that there is likely someone who already uses CXF ExactTarget client. I read tons of tutorials and examples on CXF, but they all seem either outdated or not quite applicable. – DaSh Jan 28 '14 at 16:36
  • 2
    Check out the FuelSDK for Java: github.com/ExactTarget/FuelSDK-Java It uses CXF for the SOAP component. I haven't spent much time in the source but it might be helpful. – Mac Jan 28 '14 at 18:29
  • @Mac: Do all customers get access to FuelSDK. I had a sense that my company does not. – DaSh Jan 28 '14 at 18:34
  • 2
    @DaSh the SDK itself is open source so you can go take a look. If your company has access to ExactTarget web services(which is the case if you are able to make SOAP calls), then the FuelSDK can be downloaded and used. – Mac Jan 28 '14 at 19:42
1

Here is code that does everything:

private static Soap createApiStub() {
    PartnerAPI service = new PartnerAPI();
    Soap stub = service.getSoap();          
    Client client = org.apache.cxf.frontend.ClientProxy.getClient(stub);     

    Map<String, Object> outProps = new HashMap<String, Object>();        
    outProps.put(WSHandlerConstants.ACTION, WSHandlerConstants.USERNAME_TOKEN);
    outProps.put(WSHandlerConstants.USER, username);     
    outProps.put(WSHandlerConstants.PASSWORD_TYPE,WSConstants.PW_TEXT);        
    // Automatically adds a Base64 encoded message nonce and a created timestamp
    outProps.put(WSHandlerConstants.ADD_UT_ELEMENTS,WSConstants.NONCE_LN + " " + WSConstants.CREATED_LN);    
    outProps.put(WSHandlerConstants.PW_CALLBACK_REF, new ClientPasswordCallback(username, password));
    WSS4JOutInterceptor wssOut = new WSS4JOutInterceptor(outProps);
    client.getOutInterceptors().add(wssOut);

    //Enable GZip compression
    Map<String, java.util.List<String>> httpHeaders = new HashMap<String, java.util.List<String>>();
    httpHeaders.put("Content-Encoding",Collections.singletonList("gzip"));
    httpHeaders.put("Accept-Encoding",Collections.singletonList("gzip"));
    Map<String, Object> reqContext = client.getRequestContext();
    reqContext.put(MessageContext.HTTP_REQUEST_HEADERS,httpHeaders);

    return stub;
}

And here is handler implementation:

public class ClientPasswordCallback implements CallbackHandler {

    private String username;
    private String password;

    public ClientPasswordCallback(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public void handle(Callback[] callbacks) throws IOException, 
    UnsupportedCallbackException {
        for (Callback callback: callbacks){
            if (callback instanceof WSPasswordCallback){
                WSPasswordCallback pc = (WSPasswordCallback) callback;              
                if (username.equals(pc.getIdentifier())) {                  
                    pc.setPassword(password);                   
                }
            } else if (callback instanceof NameCallback){
                throw new UnsupportedCallbackException(callback);
            } else {
                throw new UnsupportedCallbackException(callback);
            }           
        }
    }
}

This answer helped me to pass the password dynamiclly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.