Trouble connecting sam local api to secrets manager - java

I'm trying to set up AWS SAM locally so I don't have to deploy every time I make a code change. But I'm having trouble getting the secrets out of Secrets Manager. I've created a new SAM project using sam init --runtime java
I then created a new secret in Secret Manager, and changed the code in the HelloWorldFunction to try to retrieve the secret.
package helloworld;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.secretsmanager.AWSSecretsManager;
import com.amazonaws.services.secretsmanager.AWSSecretsManagerClientBuilder;
import com.amazonaws.services.secretsmanager.model.*;
/**
* Handler for requests to Lambda function.
*/
public class App implements RequestHandler<Object, Object> {
public Object handleRequest(final Object input, final Context context) {
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
headers.put("X-Custom-Header", "application/json");
try {
String secretName = "testsecret";
String region = "us-west-2";
// Create a Secrets Manager client
AWSSecretsManager client = AWSSecretsManagerClientBuilder.standard()
.withRegion(region)
.build();
String secret, decodedBinarySecret;
GetSecretValueRequest getSecretValueRequest = new GetSecretValueRequest()
.withSecretId(secretName);
GetSecretValueResult getSecretValueResult = null;
try {
getSecretValueResult = client.getSecretValue(getSecretValueRequest);
} catch (DecryptionFailureException e) {
// Secrets Manager can't decrypt the protected secret text using the provided KMS key.
// Deal with the exception here, and/or rethrow at your discretion.
throw e;
} catch (InternalServiceErrorException e) {
// An error occurred on the server side.
// Deal with the exception here, and/or rethrow at your discretion.
throw e;
} catch (InvalidParameterException e) {
// You provided an invalid value for a parameter.
// Deal with the exception here, and/or rethrow at your discretion.
throw e;
} catch (InvalidRequestException e) {
// You provided a parameter value that is not valid for the current state of the resource.
// Deal with the exception here, and/or rethrow at your discretion.
throw e;
} catch (ResourceNotFoundException e) {
System.out.println(e.getMessage());
StringWriter outError = new StringWriter();
e.printStackTrace(new PrintWriter(outError));
System.out.println(outError.toString());
// We can't find the resource that you asked for.
// Deal with the exception here, and/or rethrow at your discretion.
throw e;
}
// Decrypts secret using the associated KMS CMK.
// Depending on whether the secret is a string or binary, one of these fields will be populated.
if (getSecretValueResult.getSecretString() != null) {
secret = getSecretValueResult.getSecretString();
return new GatewayResponse(secret, headers, 200);
}
else {
decodedBinarySecret = new String(Base64.getDecoder().decode(getSecretValueResult.getSecretBinary()).array());
return new GatewayResponse(decodedBinarySecret, headers, 200);
}
} catch (Exception e) {
return new GatewayResponse("{}", headers, 500);
}
}
}
When I run sam local start-api and navigate to http://127.0.0.1:3000/hello, I get this error:
Secrets Manager can’t find the specified secret. (Service: AWSSecretsManager; Status Code: 400; Error Code: ResourceNotFoundException; Request ID: 6881467f-d968-4f4e-ae60-7e3128124cc5)
com.amazonaws.services.secretsmanager.model.ResourceNotFoundException: Secrets Manager can’t find the specified secret. (Service: AWSSecretsManager; Status Code: 400; Error Code: ResourceNotFoundException; Request ID: 6881467f-d968-4f4e-ae60-7e3128124cc5)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1632)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1304)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1058)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:743)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:717)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667)
at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:513)
at com.amazonaws.services.secretsmanager.AWSSecretsManagerClient.doInvoke(AWSSecretsManagerClient.java:2024)
at com.amazonaws.services.secretsmanager.AWSSecretsManagerClient.invoke(AWSSecretsManagerClient.java:2000)
at com.amazonaws.services.secretsmanager.AWSSecretsManagerClient.executeGetSecretValue(AWSSecretsManagerClient.java:878)
at com.amazonaws.services.secretsmanager.AWSSecretsManagerClient.getSecretValue(AWSSecretsManagerClient.java:853)
at helloworld.App.handleRequest(App.java:53)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at lambdainternal.EventHandlerLoader$PojoMethodRequestHandler.handleRequest(EventHandlerLoader.java:259)
at lambdainternal.EventHandlerLoader$PojoHandlerAsStreamHandler.handleRequest(EventHandlerLoader.java:178)
at lambdainternal.EventHandlerLoader$2.call(EventHandlerLoader.java:888)
at lambdainternal.AWSLambda.startRuntime(AWSLambda.java:293)
at lambdainternal.AWSLambda.<clinit>(AWSLambda.java:64)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at lambdainternal.LambdaRTEntry.main(LambdaRTEntry.java:114)
But, it's the same code to get the secret that was given in the secrets manager. Is it not possible to connect to real AWS services from sam local? I had a similar issue with DynamoDB, but was able to get it working with by using DynamoDB Local.
Any suggestions on how to either connect to the real secrets manager or to fake it locally somehow?

When you run DynamoDB Local, it is actually running a mock DDB server in a thread (or as a local process depending on how you start it) within you running test process. Unfortunately, Secrets Manager and other AWS services do not offer an equivalent testing solution.
However, if you are getting back ResourceNotFoundException it seems likely that you were able to successfully connect to Secrets Manager. It may be possible that the connection to secrets manager is using a different account than the one in which you stored the secret. One way you can check which credentials the code is using is to use the STS get caller identity call.

Related

Docusign API integration issue

I am trying to integrate Docusign in our Java (Java-11) application.
I am trying to use the JWT flow for the same. After having authorized the app, I could get to the point of creating getting the access token, however when trying to create an envelope and create an embededded request I am seeing the following error :
[2021-07-21 15:00:32.954] [EC2AMAZ-5EFUJD8] [http-nio-8080-exec-2] ERROR c.p.e.h.GovCloudBaseExceptionHandler#handleException:237 - -- handleException() - {}
org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: MessageBodyReader not found for media type=text/html;charset=utf-8, type=class com.docusign.esign.model.EnvelopeSummary, genericType=class com.docusign.esign.model.EnvelopeSummary.
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:232)
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:156)
at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1091)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:874)
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:834)
at org.glassfish.jersey.client.ClientResponse.readEntity(ClientResponse.java:363)
at org.glassfish.jersey.client.InboundJaxrsResponse$2.call(InboundJaxrsResponse.java:126)
at org.glassfish.jersey.internal.Errors.process(Errors.java:316)
at org.glassfish.jersey.internal.Errors.process(Errors.java:298)
at org.glassfish.jersey.internal.Errors.process(Errors.java:229)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestSco
The createEnvelope Method in the following code is throwing the error
void CreateEnvelope()
{
// Create the envelope definition
EnvelopeDefinition envelope = null;
try {
envelope = makeEnvelope("anur.puniyani#teliolabs.com", "Anur");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// Call DocuSign to create the envelope
//ApiClient apiClient = createApiClient("", bearerToken);
EnvelopesApi envelopesApi = new EnvelopesApi(apiClient);
EnvelopeSummary envelopeSummary = null ;
try {
envelopeSummary = envelopesApi.createEnvelope("1a9c289e-f63d-4f63-b6cd-5c43af184603", envelope);
} catch (ApiException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
envelopeId = envelopeSummary.getEnvelopeId();
System.out.println("Envelope ID (&(*&(&( !!!!= "+envelopeId);
}
I used the following base url for the ApiClient constructor : https://account-d.docusign.com
As the one in my App dashboard (demo.docusign.com) did not seem to work for giving permissions and was throwing a page not found error.
Please help me and my colleague are stuck with this since the entire day. We tried contacting support but they don't give API support unless you have the license.
EDIT: I figured out that the basepath you're using is missing /restapi it should be https://demo.docusign.com/restapi. Also I incorrectly said docusign.net when it should be docusign.com
As far as I am aware, there is no class method to create the envelope directly within the EnvelopeDefinition. You will need to specify the various associated portions necessary for the API call to succeed. This portion of code comes from eSignature example 002 in our Launcher. I've made a few small changes to make it work with a single document. You'll need to send this envelope definition to the host "demo.docusign.net" :
package com.docusign.controller.eSignature.examples;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Base64;
import com.docusign.esign.api.EnvelopesApi;
import com.docusign.esign.client.ApiClient;
import com.docusign.esign.client.ApiException;
import com.docusign.esign.model.Document;
import com.docusign.esign.model.EnvelopeDefinition;
import com.docusign.esign.model.EnvelopeSummary;
import com.docusign.esign.model.Recipients;
import com.docusign.esign.model.SignHere;
import com.docusign.esign.model.Signer;
import com.docusign.esign.model.Tabs;
class CreateEnvelope
{
public static void main(String[] args) {
// Create the envelope definition
String accessToken = "eyJ0eXAi......JgAkJuZ8A";
String accountId = "xxxxxxx-xxxx-xxxx-xxxx-xxxxxxx";
// Call DocuSign to create the envelope
ApiClient apiClient = new ApiClient("https://demo.docusign.net/restapi");
apiClient.addDefaultHeader("Authorization", "Bearer " + accessToken);
EnvelopesApi envelopesApi = new EnvelopesApi(apiClient);
EnvelopeDefinition envelope = makeEnvelope("anur.puniyani#teliolabs.com", "Anur");
try {
EnvelopeSummary envelopeSummary = envelopesApi.createEnvelope(accountId, envelope);
String envelopeId = envelopeSummary.getEnvelopeId();
System.out.println("Envelope ID = "+envelopeId);
} catch (ApiException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static EnvelopeDefinition makeEnvelope(String signerEmail, String signerName) {
// Create a signer recipient to sign the document, identified by name and email
// We set the clientUserId to enable embedded signing for the recipient
Signer signer = new Signer();
signer.setEmail(signerEmail);
signer.setName(signerName);
// signer.clientUserId("1000"); # will not receive docuSign email to sign if client user id is present
signer.recipientId("1");
SignHere signHere = new SignHere();
signHere.setAnchorString("/sn1/");
signHere.setAnchorUnits("pixels");
signHere.setAnchorYOffset("20");
signHere.setAnchorXOffset("10");
Tabs signerTabs = new Tabs();
signerTabs.setSignHereTabs(Arrays.asList(signHere));
// Add the recipient to the envelope object
Recipients recipients = new Recipients();
recipients.setSigners(Arrays.asList(signer));
EnvelopeDefinition envelopeDefinition = new EnvelopeDefinition();
envelopeDefinition.setEmailSubject("Please sign this document");
envelopeDefinition.setRecipients(recipients);
Path path = Paths.get("./path/to/my/code-examples-java/src/main/resources/World_Wide_Corp_lorem.pdf");
byte[] data = null;
try {
data = Files.readAllBytes(path);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Document document = new Document();
document.setDocumentBase64(Base64.getEncoder().encodeToString(data));
document.setName("Hello Doc");
document.setFileExtension("pdf");
document.setDocumentId("3");
envelopeDefinition.setDocuments(Arrays.asList(document));
// Request that the envelope be sent by setting |status| to "sent".
// To request that the envelope be created as a draft, set to "created"
envelopeDefinition.setStatus("sent");
return envelopeDefinition;
}
}
This code above comes from the Code example launcher here. A pre-packaged version that has all of your configuration details filled in here on the Quickstart page is also provided.

JNDI Authentciation fails in plain java class but passes in Spring

This might sound silly but I am encountering this behavior. I am using JNDI for LDAP authentication. I have a demo program setup, where the authentication fails upon providing incorrect credentials, but the same seems to go through in a Spring controller method(I'm making a post call from a react app).
Plain Java implementation
import java.util.Properties;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
public class Demo {
public static void main(String[] args) {
Properties environment = new Properties();
String userDomain = "#region.company.net";
environment.setProperty(DirContext.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
environment.setProperty(DirContext.PROVIDER_URL, "ldap://region.company.net:3268");
environment.setProperty(DirContext.SECURITY_AUTHENTICATION, "simple");
environment.setProperty(DirContext.SECURITY_PRINCIPAL, "userId"+userDomain);
environment.setProperty(DirContext.SECURITY_CREDENTIALS, "wrongPassword");
try {
DirContext context = new InitialDirContext(environment);
System.out.println("Authentication Successful !!!\n\n");
} catch (NamingException e) {
System.out.println("Authentication Failed !!!\n\n");
e.printStackTrace();
}
}
}
Controller implementation
#PostMapping("/authenticateUser")
public String authenticateUser(#RequestBody HashMap<String, String> user) {
Properties environment = new Properties();
String userDomain = "#region.company.net";
environment.setProperty(DirContext.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
environment.setProperty(DirContext.PROVIDER_URL, "ldap://region.company.net:3268");
environment.setProperty(DirContext.SECURITY_AUTHENTICATION, "simple");
// environment.setProperty(DirContext.SECURITY_PRINCIPAL, "userId"+userDomain);
environment.setProperty(DirContext.SECURITY_CREDENTIALS, "wrongPassword");
try {
DirContext context = new InitialDirContext(environment);
System.out.println("Authentication Successful !!!\n\n");
} catch (NamingException e) {
System.out.println("Authentication Failed !!!\n\n");
e.printStackTrace();
}
return "Method executed successfully";
}
After providing incorrect password, if I execute this code then it prints Authentication Failed !!! which is expected, but when I insert this same code in a controller's method, it prints Authentication Successful !!!.
Shouldn't both behave in the same way? I find this behavior pretty weird. Perhaps, I am overlooking something?
EDIT 1 : START
It appears the line that sets the SECURITY_PRINCIPAL was commented out in case of the Spring Controller. I have commented out that part of code.
This now gives rise to another question as to why it never threw any exception ?
Not sure if I should ask this in a separate post.
Is it a proper way to authenticate by passing Username(like abc#xyz.com) as SECURRITY_PRINCIPAL or one should pass the entry path ?
EDIT 1 : END

how to authorize an user using jGit

I'm creating an application in Java and using jGit. As part of this I need to authenticate an user. I want to output if the user is existing or not. Currently I get an exception as user is not authorized. Below is my code.
import java.io.File;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
public class AuthenticateanUser {
public static void main(String[] args) throws Exception {
final String REMOTE_URL = "https://myRepo.git";
// prepare a new folder for the cloned repository
File localPath = File.createTempFile("TestGitRepository", "");
localPath.delete();
// then clone
try (Git result = Git.cloneRepository().setURI(REMOTE_URL)
.setCredentialsProvider(new UsernamePasswordCredentialsProvider("myId", "myPwd"))
.setDirectory(localPath).call()) {
System.out.println("Having repository: " + result.status());
}
}
}
when I run my above code, If I give correct credentials, I get the output as
Having repository:XXXXX
if I give wrong credentials I get error as
Exception in thread "main" org.eclipse.jgit.api.errors.TransportException: https://myRepo.git: not authorized
Instead of this I want to print, Invalid credentials.
please let me know where am I going wrong and how can I fix this.
Thanks
You go:
try (Git result = Git.cloneRepository().setURI(REMOTE_URL) {
...
} catch (TransportException te) {
System.out.println("Invalid credentials");
}
for example.
You should not tell the user if the account exists or not. As in: if you tell that an attacker, he can conclude that he already got a valid username.

PeerUnavailableException using JAIN SIP API on Android

I'm trying to build SIP application using JAIN SIP 1.2 and the NIST implementation on android.
I have rebuilt jain-sip-api-1.2.jar and jain-sip-ri-1.2.1111.jar from source, and renamed javax -> jain_javax and gov.nist.javax -> jain_gov.nist.jain_javax. I tested the jar files on textclient example on standard java without problem. However, when I run it on Android I still get the error:
"The Peer SIP Stack: jain_gov.nist.jain_javax.sip.SipstackImpl could not be instantiated. Ensure the Path Name has been set".
Did I miss anything here?
It is not sufficient to rename the packages. JAIN-SIP has internal references to some classes by their original package name "gov.nist". You should also double check all your code to rename any "gov.nist" references such as the prefix for the stack classes.
Android has built-in an older version of JAIN-SIP which is taking over some of the existing references to those "gov.nist" classes. It's not an exported API, so not quite obvious. That's why it may behave differently on desktop machines. Post you code and full error messages/debug logs if you need more help.
Sovled. Jain Sip is using log4i-1.2.x.jar which does not work properly on Android. There are lots of discussion on Internet how to make log4j working on Android but none of them works for me. I have removed all log4j related code from Jain Sip source and now the sip stack is working properly on Android.
I am using JAIN-SIP-1-2-164. Here is the app code:
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.text.ParseException;
import java.util.*;
import android.os.Handler;
import jain_javax.sip.*;
import jain_javax.sip.address.*;
import jain_javax.sip.header.*;
import jain_javax.sip.message.*;
public class SipLayer implements SipListener {
private SipStack sipStack;
private SipFactory sipFactory;
private Properties properties;
private String local_ip;
int listen_port;
/** Here we initialize the SIP stack. */
public SipLayer(int listen_port) {
try {
setUsername(username);
this.local_ip = InetAddress.getLocalHost().getHostAddress();;
this.listen_port = listen_port;
// Create the SIP factory and set the path name.
this.sipFactory = SipFactory.getInstance();
this.sipFactory.setPathName("jain_gov.nist");
// Create and set the SIP stack properties.
this.properties = new Properties();
this.properties.setProperty("jain_javax.sip.STACK_NAME", "stack");
this.properties.setProperty("jain_javax.sip.IP_ADDRESS", local_ip);
if(proxy != null)
this.properties.setProperty("jain_javax.sip.OUTBOUND_PROXY", proxy + ':' + server_port + '/' + protocol);
//DEBUGGING: Information will go to files textclient.log and textclientdebug.log
this.properties.setProperty("jain_gov.nist.javax.sip.TRACE_LEVEL", "32");
// this.properties.setProperty("jain_gov.nist.javax.sip.SERVER_LOG", "textclient.txt");
// this.properties.setProperty("jain_gov.nist.javax.sip.DEBUG_LOG", "textclientdebug.log");
// Create the SIP stack.
this.sipStack = this.sipFactory.createSipStack(properties);
}
catch (Exception e) {
msgProc.processError("SipLayer failed: " + e.getMessage() + "\n");
}
}
}
Same code runs ok on java on a windows machine, but android emulator I got above mentioned error message.
I found that it failed in following Jain SIP 1.2 routine at "SipStack sipStack = (SipStack) sipStackConstructor.newInstance(conArgs);"
private SipStack createStack(Properties properties)
throws PeerUnavailableException {
try {
// create parameters argument to identify constructor
Class[] paramTypes = new Class[1];
paramTypes[0] = Class.forName("java.util.Properties");
// get constructor of SipStack in order to instantiate
Constructor sipStackConstructor = Class.forName(
getPathName() + ".jain_javax.sip.SipStackImpl").getConstructor(
paramTypes);
// Wrap properties object in order to pass to constructor of
// SipSatck
Object[] conArgs = new Object[1];
conArgs[0] = properties;
// Creates a new instance of SipStack Class with the supplied
// properties.
SipStack sipStack = (SipStack) sipStackConstructor.newInstance(conArgs);
sipStackList.add(sipStack);
String name = properties.getProperty("jain_javax.sip.STACK_NAME");
this.sipStackByName.put(name, sipStack);
return sipStack;
} catch (Exception e) {
String errmsg = "The Peer SIP Stack: "
+ getPathName()
+ ".jain_javax.sip.SipStackImpl"
+ " could not be instantiated. Ensure the Path Name has been set.";
throw new PeerUnavailableException(errmsg, e);
}
}
Any suggestion or how to debug further?

running an axis2 client version 1.5

So I'm running out of ideas to try to actually get a client to connect to the SOAP service I'm running through axis2.
I tried two methods, one was to use wsdl2java to build the stub and associated client side classes, and then write a Client class that build the requests messages and sends them through the Stub. The other way was to use the ServiceClient to connect..
Both are failing in their own way..
Option #1, every time a message is sent through the stub I get this back:
org.apache.axis2.AxisFault: The input stream for an incoming message is null.
at org.apache.axis2.transport.TransportUtils.createSOAPMessage(TransportUtils.java:87)
at org.apache.axis2.transport.TransportUtils.createSOAPMessage(TransportUtils.java:67)
at org.apache.axis2.description.OutInAxisOperationClient.handleResponse(OutInAxisOperation.java:354)
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:417)
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:229)
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:165)
Option #2, everytime I run it I get this Exception:
org.apache.axis2.deployment.DeploymentException: org.apache.axis2.transport.local.LocalTransportSender
Option #2 source:
import javax.xml.stream.XMLStreamException;
import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.Constants;
import org.apache.axis2.client.ServiceClient;
public class loyaltyClient {
private static EndpointReference targetEPR =
new EndpointReference(
"http://localhost:8080/axis2/services/service");
public static OMElement verifyCustomer(String customer_id) {
OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace omNs = fac.createOMNamespace(
"http://localhost/", "service");
OMElement method = fac.createOMElement("VerifyCustomer", omNs);
OMElement value1 = fac.createOMElement("customer_id",omNs);
OMElement value2 = fac.createOMElement("source_id",omNs);
OMElement value3 = fac.createOMElement("source_password",omNs);
OMElement value4 = fac.createOMElement("source_txnid",omNs);
OMElement value5 = fac.createOMElement("timestamp",omNs);
value1.addChild(fac.createOMText(value1, customer_id));
value2.addChild(fac.createOMText(value2, "source"));
value3.addChild(fac.createOMText(value3, "1234"));
value4.addChild(fac.createOMText(value4, "123"));
value5.addChild(fac.createOMText(value5, "06-01-2010 12:01:01"));
method.addChild(value1);
method.addChild(value2);
method.addChild(value3);
method.addChild(value4);
method.addChild(value5);
return method;
}
public static void main(String[] args) {
try {
OMElement vctest = loyaltyClient.verifyCustomer("6177740603");
Options options = new Options();
options.setTo(targetEPR);
options.setTransportInProtocol(Constants.TRANSPORT_HTTP);
ServiceClient sender = new ServiceClient();
sender.setOptions(options);
OMElement result = sender.sendReceive(vctest);
String response = result.getFirstElement().getText();
System.out.println(response);
} catch (Exception e) { //(XMLStreamException e) {
System.out.println(e.toString());
}
}
}
I've also encountered the error "The input stream for an incoming message is null" while using Axis to connect to a .Net service provider.
The problem is that .Net doesn't not support a feature called "chunked encoding", by default Axis will break its request header in chunks which is suppose to be a HTTP 1.1 compliant thing.
Anyway, you can turn this feature off in Axis by doing the following:
// Turn off the Axsis Chunked feature, some service providers (like .Net) don't support chunked headers.
Options options = serviceClient.getOptions();
options.setProperty(HTTPConstants.CHUNKED, Constants.VALUE_FALSE);
serviceClient.setOptions(options);
This worked for me. Another thing to make sure of when dealing with .Net services is to be able to specify the port name and make sure your message payload has the namespace prefix for each element.
Hope this info helps somebody.
Cheers,
DC
With the caveat that Axis2 is a buggy pile of crap, I recently had to write an Axis2 client, and found that using the default ServiceClient() constructor didn't work well -- I had to manually create a ConfigurationContext, etc. I found that using ServiceClient.getOptions() instead of creating new Options() preserved some default data. I'd also recommend dropping the options.setTransportInProtocol(...) unless you really need it -- everything should work fine via HTTP without this. Also, you may need to set options.setAction(...) to correspond with the "operation" in your WSDL.
I've included the bulk of my client (with sensitive information stripped out), in hopes that it will help. You can probably safely ignore the portions regarding addressing unless you plan to use WS-Addressing.
ConfigurationContext cfgCtx = null;
try {
/* Passing null to both params causes an AxisConfiguration to be created that uses
* the default axis2.xml file, which is included in the axis2 distribution jar.
* This is ideal for our case, since we cannot pass a full file path (relative
* paths are not allowed) because we do not know where the customer will deploy
* the application. This also allows engaging modules from the classpath. */
cfgCtx = ConfigurationContextFactory.createConfigurationContextFromFileSystem(null , null);
} catch (AxisFault e) {
// Bubble up the error
}
ServiceClient svcClient = null;
try {
svcClient = new ServiceClient(cfgCtx, null);
} catch (AxisFault e) {
// Bubble up the error
}
try {
/* This will work with the above ConfigurationContext as long as the module
* (addressing-1.5.1.mar) is on the classpath, e.g. in shared/lib. */
svcClient.engageModule("addressing");
} catch (AxisFault e) {
// Bubble up the error
}
Options opts = svcClient.getOptions();
opts.setTo(new EndpointReference("http://myservername:8080/axis2/services/MyService"));
opts.setAction("urn:doSomething"); // Corresponds to the "operation" in MyService's WSDL
opts.setSoapVersionURI(SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI); // Set output to SOAP 1.2
SOAPFactory factory = OMAbstractFactory.getSOAP12Factory();
svcClient.addHeader(createSOAPSecurityHeader(factory, response)); // CreateSOAPHeader just creates an OMElement
try {
svcClient.sendReceive(createSOAPBody(factory, response)); // CreateSOAPBody just creates an OMElement
} catch (AxisFault e) {
throw new ResponseDeliveryException(1, "Error sending SOAP payload.", e);
}

Categories

Resources