ServiceCallout / LocalTargetConnection Always returns http 200

Not applicable

When I callout to a LocalTargetConnection http service, the variable calloutResponse.status.code is ALWAYS 200 yet, when I invoke it externally via curl, it can return different status-codes. It is as though the LocalTargetConnection only emulates an HTTP call and doesn't set the status properly.

Flow:

<Step>
<Name>Service-Callout-Authzn</Name>
</Step>
<Step>
<Name>Raise-Fault-401NotAuthd</Name>
<Condition>calloutResponse.status.code != "200"</Condition>
</Step>

Policy:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<ServiceCallout async="false" continueOnError="false" enabled="true" name="Service-Callout-Authzn">

<DisplayName>Service Callout-Authzn</DisplayName>

<Properties/>

<Response>calloutResponse</Response>

<LocalTargetConnection>

<APIProxy>user-mgmt-v1</APIProxy>

<ProxyEndpoint>default</ProxyEndpoint>

<Path>/authenticate</Path>

</LocalTargetConnection>

</ServiceCallout>

The trace for the CalloutService itself shows the Request Body for both the request and response but doesn't show the status. The subsequent conditional RaiseFault policy DOES show the status and it is always 200, even if the Callout should have returned 4xx (ie. passwordX is wrong):

Trace Output (RaiseFault - Not Executed.)

Raise Fault-401NotAuthd POST /v1/auth/token

--------------------

Variables

calloutResponse.status.code 200

:

Request Content

Body{"username":"training1", "password": "passwordX"}{"username":"training1", "password": "passwordX"}

Properties

action PAUSE

enforcement requestrequest

expression (calloutResponse.status.code not equals "200")

expressionResult false

:

stepDefinition-displayName Service Callout-AuthznRaise Fault-401NotAuthd

Yet, the call returns the correct 4xx status if invoked by curl from the outside world:

curl -v -X POST -H 'Content-Type: application/json' -d '{"username":"training1", "password": "passwordX"}' https://lanceb-test.apigee.net/v1/users/authenticate

< HTTP/1.1 403 Forbidden

< Date: Thu, 15 Sep 2016 01:58:28 GMT

< Content-Type: application/json

< Content-Length: 75

< Connection: keep-alive

< Server: Apigee Router

< { [75 bytes data] 100 124 100 75 100 49 57 37 0:00:01 0:00:01 --:--:-- 58

{"status":"failure", "message":"Authentication failed for user training1."}

* Connection #0 to host lanceb-test.apigee.net left intact

Note that I have also tried the ServiceCallout with HTTPTargetConnection but always get a 404/Not Found, as though a proxy-rule prevents calls to *.apigee.net going out from apigee and coming back in:

<HTTPTargetConnection>

<Properties/>

<URL>https://lanceb-test.apigee.net/v1/users/authenticate</URL>

</HTTPTargetConnection>

0 1 662
1 REPLY 1

Hi,

In Service Callout Policy you either need to pass a Request variable created using a Assign Message policy or you can create a request inline directly in Service Callout.

From your Curl command it looks like your /authenticate policy needs JSON payload with username and password, where as you have not defined this in a Request variable nor it is in your callout.

<ServiceCallout async="false" continueOnError="false" enabled="true" name="Service-Callout-Authzn">
	<DisplayName>Service Callout-Authzn</DisplayName>
	<Properties/>
	<Response>calloutResponse</Response>
	<Request>
		<Set>
			<Payload contentType="application/json">{"username" : "training1", "password" : "password123"}</Payload>
		</Set>
		<IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
	</Request>
	<LocalTargetConnection>
		<APIProxy>user-mgmt-v1</APIProxy>
		<ProxyEndpoint>default</ProxyEndpoint>
		<Path>/authenticate</Path>
	</LocalTargetConnection>
</ServiceCallout>

Try this ServiceCallout.