Java Call Out Response

Not applicable

In a standalone java code, using Apache HTTPClient libs, implementing the NTLM Authentication with SharePoint Server and accessing its Web Service and receiving the huge XML content as response. Now this final output is in String format. Created the Java Call Out Policy and uploaded all the jars. I need some help here,

How to pass the java's final output response to Apigee's response.

My requirement is: If I hit the Apigee API Proxy then I need to receive the Java's output(String) as Apigee's response.

1) Can I use No Target Backend EndPoint since inside the java code I access the SharePoint EndPoint URL and receiving 200 Ok and huge XML response as String

2) Which policy is more appropriate to handle this response?

Appreciate your help! Thanks in Advance.

1 14 3,224
14 REPLIES 14

Former Community Member
Not applicable

Hi @P.Ganesan, you have access to the messageContext object within your java code so you can set variables & their values:

messageContext.setVariable("some_variable", "variable_value");

Once you do that, "some_variable" is then available inside any subsequent policies by using the {some_variable} notation.

Some comments on your bullet points:

1) You can definitely use the "No Target" endpoint proxy type and access what ever URLs that you need to within your Java code. AS discussed above you can capture the XML response in a variable that you set on the "messageContext" object. You can use an AssignMessage policy following the Java callout policy which can set the response payload with the value from the variable that is set in the java code.

2) Java callout seems like a good approach, given that you have to do NTLM authentication and Java has good libraries to support it. I am sure there are other options as well.

Hi @Prithpal Bhogill

Thanks a lot for your time & response. I'll try it out and let you know the outcome.

Could you please share me what other options are there?

Not applicable

hi @P.Ganesan,

You can use No Target Backend. On the response path you can have your Java Callout Policy returning the response from your java code, you want to.

You can use messageContext to set the response message:

messageContext.getResponseMessage().setContent(yourResponse);

But if your sharepoint endpoint is an HTTP endpoint, why don't you use a regular Target Endpoint and have your Java Callout or a javascript, set the required headers needed for NTLM authentication?

Not applicable

Hi @Sandeep Murusupalli

Thanks a lot for your response and solution. I'll try this...

In my understanding, it is not only about Headers, for Microsoft NTLM, any logic should implement the below "Process Flow". So I've used Apache HTTPClient Libs in my Java code.

"Windows integrated authentication" is what's known as NTLM authentication. When you receive a HTTP 401 from IIS with aWWW-Authenticateheader containingNTLM.

1.The client requests a protected resource from the server:

GET /index.html HTTP/1.1

2.The server responds with a401status, indicating that the client must authenticate.NTLMis presented as a supported authentication mechanism via theWWW-Authenticateheader. Typically, the server closes the connection at this time:

3.HTTP/1.1401Unauthorized
4.WWW-Authenticate: NTLM
Connection: close

Note that Internet Explorer will only select NTLM if it is the first mechanism offered; this is at odds with RFC 2616, which states that the client must select the strongest supported authentication scheme.

5.The client resubmits the request with anAuthorizationheader containing aType 1 messageparameter. The Type 1 message is Base-64 encoded for transmission. From this point forward, the connection is kept open; closing the connection requires reauthentication of subsequent requests. This implies that the server and client must support persistent connections, via either the HTTP 1.0-style "Keep-Alive" header or HTTP 1.1 (in which persistent connections are employed by default). The relevant request headers appear as follows:

6.GET /index.html HTTP/1.1
Authorization: NTLM TlRMTVNTUAABAAAABzIAAAYABgArAAAACwALACAAAABXT1JLU1RBVElPTkRPTUFJTg==

7.The server replies with a401status containing aType 2 messagein theWWW-Authenticateheader (again, Base-64 encoded). This is shown below.

8.HTTP/1.1401Unauthorized
WWW-Authenticate: NTLM TlRMTVNTUAACAAAADAAMADAAAAABAoEAASNFZ4mrze8AAAAAAAAAAGIAYgA8AAAARABPAE0AQQBJAE4AAgAMAEQATwBNAEEASQBOAAEADABTAEUAUgBWAEUAUgAEABQAZABvAG0AYQBpAG4ALgBjAG8AbQADACIAcwBlAHIAdgBlAHIALgBkAG8AbQBhAGkAbgAuAGMAbwBtAAAAAAA=

9.The client responds to the Type 2 message by resubmitting the request with anAuthorizationheader containing a Base-64 encodedType 3 message:

10.GET /index.html HTTP/1.1
Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGoAAAAYABgAggAAAAwADABAAAAACAAIAEwAAAAWABYAVAAAAAAAAACaAAAAAQIAAEQATwBNAEEASQBOAHUAcwBlAHIAVwBPAFIASwBTAFQAQQBUAEkATwBOAMM3zVy9RPyXgqZnr21CfG3mfCDC0+d8ViWpjBwx6BhHRmspst9GgPOZWPuMITqcxg==

11.Finally, the server validates the responses in the client's Type 3 message and allows access to the resource.

HTTP/1.1200 OK

Pls. share me, if u have some other solution. Thanks again.

what version of Sharepoint? Is NTLM the only authentication mechanism you have available? If so, you will need to do the entire NTLM dance for every request. This is because NTLM auth is valid for the life of the connection, but Edge will not maintain the connection between the Java callout and the sharepoint backend.

Sharepoint 2013 accepts OAuth Bearer tokens. Your API Proxy could obtain and then stash the token, to allow it to be used across multiple requests. Microsoft says: "If you plan to build an app for SharePoint that runs in an remote web application and communicates back to SharePoint using server-side code, you will need to use OAuth."

Not applicable

@Dino Hi Dino,

//This is because NTLM auth is valid for the life of the connection, but Edge will not maintain the connection between the Java callout and the sharepoint backend.//

SharePoint version is 2010.

So, If I can not use Java Call Out for my requirement then what is the benefit of Java Call out... What'll be the best approach if it is backend SP 2010?

More background: In my Standalone Java Code in Eclipse, I'm using Service Account, here apigee host name is added and using this credentials for NTLM dance between apigee and SP,by support of Apache HTTPClient libs.Using this code,I can access the SP GET Call WS and receive the valid response.

Actual requirement is, I want to pass this response to Client App. using Java Call Out Policy.

In this scenario, can I use Java Call out? Please guide me. Thanks!

Yes, you can use the Java call out. You will need to do the NTLM authentication for every request. It will work properly.

Not applicable

NTLM carries significant overhead for this type of integration in that you are authenticating connections, not requests - meaning you will incur the auth overhead on every connection. Keep-alives may help reduce the overhead, but in the end it is almost always better to use another scheme if possible.

Not applicable

I would have Apigee proxy talk to a target that handles NTLM auth.

Not applicable

@Dino @Prithpal Bhogill @Sandeep Murusupalli @sriki77

Hi, What could be the reason for following error

{ "fault": { "faultstring": "flow.execution.ExecutionReturnedFailure", "detail": { "errorcode": "flow.execution.ExecutionReturnedFailure" } } }

Other Details:

error_msg APIGEE Execution Failed Properties

action: ABORT

stepDefinition-async: true

internal: false

stepDefinition-type: javacallout

type: SecurityWrappedExecution

enforcement: request

stepDefinition-continueOnError: false

stepDefinition-displayName: NTLM SP Java Call Out stepDefinition-name: NTLM-SP-Java-Call-Out

stepDefinition-enabled: true

result: false

error: flow.execution.ExecutionReturnedFailure

type: ErrorPoint

state: PROXY_REQ_FLOW

error.class: com.apigee.flow.FlowException

Identifier: fault

@P.Ganesan - this seems like a new question. In the future, Please add a new question instead of providing a new question as an "answer" in an existing question.

It sure looks like you have generated an exception in your Java code. Which exception? I don't know exactly, but what I suggest is that you follow standard Java development procedure for isolating the source and nature of the error. Insert try/catch clauses, and in the catch, you will want to capture and format the stacktrace. Within the catch clause, Put the stacktrace into a context variable so that you can view the exception in the Trace window.

I cannot answer fully here, as this is a comment, not an answer. (This is why it is better to ask a new question as a new question, not in an "answer").

...continuing my prior comment, This is a pattern i use for catching exceptions:

import org.apache.commons.lang.exception.ExceptionUtils;


....


try {
    // ... do things here...
}
catch (Exception e) {
    e.printStackTrace(); // goes to MP stdout, not visible in trace
    String varName = "mycallout_error";
    msgCtxt.setVariable(varName, "Exception: " + e.toString());
    varName = "mycallout_stacktrace";
    msgCtxt.setVariable(varName, "Stack: " + ExceptionUtils.getStackTrace(e));
    return ExecutionResult.ABORT;
}

The ExceptionUtils class is provided by apache's commons-lang library, which is included in the Apigee Edge runtime. You should compile against v2.6, but you do not need to upload the commons-lang jar when you import your API Proxy containing a Java callout with the above code.

Hi @Dino,

Good answer. Posted it as an article, since it can be helpful for others too!

http://community.apigee.com/articles/5314/debugging-java-callouts.html

Not applicable

@Dino @Sandeep Murusupalli Thank You! Your tips really helped me to fix the exceptions.