Adding FaultRule to ServiceCallout - apigee

I have been trying to make sense of the Apigee Guide on Fault Handling (http://apigee.com/docs/api-services/content/fault-handling) but it is not making sense to me.
The following request can result in a 404 error from the target server. How do I correctly catch this fault?
<ServiceCallout async="false" continueOnError="false" enabled="true" name="CalloutSessionSignIn">
<Request variable="SignInRequest"/>
<Response>SignInResponse</Response>
<HTTPTargetConnection>
<URL>http://localhost/{service_name}/{request.formparam.session_id}/signin</URL>
</HTTPTargetConnection>

One of the possible solutions is in my blog Handling 404 backend response
One you do the solution described, you can generate appropriate response based on SignInResponse.status.code=404 condition.

Related

POST call converting to GET

I am new to apigee.
I am trying to make a post call in apigee with queryparameters.
The flow is below.
Client send request --> verify API key ---> extract payload --> remove access token --> call target endpoint conditional based on POST
I am using curl command to make POST call.But issue is while calling target endpoint its taking as /GET call and condition is evaluating to false.
Apigee can convert in inbound POST to a back-end GET. In Apigee that means using a policy to rebuild the call, to use a GET method (verb) on your target back-end, when you need to receive a POST from your upstream calling client. You will need to use the AssignMessage policy. These product docs are exactly what you need to review:
https://docs.apigee.com/api-platform/reference/policies/assign-message-policy#set-verb
Example, AssignMessage:
<AssignTo type="request" createNew="false"/>
and
<Set> ... <Verb>GET</Verb>
Note though that when converting the method (verb) from POST to GET, the policy will not automatically convert the POST's form parameters to query parameters. You will need to use the <Add> and/or <Remove> functionality of the AssignMessage policy to manipulate the message further. Example use in the AssignMessage policy to add the queryparams, referencing the formparams:
<Add>
<QueryParams>
<QueryParam name="q1">{request.formparam.q1}</QueryParam>
</QueryParams>
</Add>
Credit to user Michael Russo for his Answer about this from eight years ago.

How to enable CORS as I dont have WebApiConfig.cs

I want to enable CORS on my controller in ASP website. The tutorials show that I have to change WebApiConfig.cs and add a line config.EnableCors();
The problem is I dont have this file. The closes I have is RouteConfig.cs, where do enable CORS in my project then?
I have added the following section in web.config file
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
but the Ajax calls to the API's still return
the server responded with a status of 405 (Method Not Allowed)
When I call the API using the browser, it works.
CORS or Cross-Origin Resource Sharing is used for cross domain communication from the browser. The endpoint you're calling from the browser is the one to tell the browser if the request is allowed to be fulfilled and processed by the browser or not by sending Access-Control-* headers in the response.
When the browser receives the response it first checks if Access-Control-* headers exist and if the information in them matches your request, if they exist and the information in them matches the request then the browser will allow your custom client code to process the response, if headers are not there or the information in the headers do not match the request you made then the browser will block the response for any further processing.
What you have to do is to set those headers in your response.
For further reading about CORS headers: W3C CORS

Web Service Adding extra forward slash in SOAPAction

I am using SoapUI to test a .Net Web Service that will be consumed by a Java client application.
When I hook up my Web Service to SoapUI but updating the WSDL location and call one of the preset testing scripts, the Web Service fails with the following code
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: urn:mycode:us:gu:das:supplierengagement:v02:SupplierEngagement:/AppointSupplier.
at System.Web.Services.Protocols.Soap11ServerProtocolHelper.RouteRequest()
at System.Web.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage message)
at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)
</faultstring>
<detail/>
</soap:Fault>
</soap:Body>
</soap:Envelope>
As you can see from the above error, the problem is with the SOAPAction parameter having an extra forward slash.
I am using the following attribute on the class:
<WebService(Namespace:= "urn:mycode:us:gu:das:supplierengagement:v02:SupplierEngagement:AppointSupplier")>
and the following attribute on the method call:
<WebMethod(MessageName:="appointSupplierRq")>
From these, .Net is adding the forward slash.
It must be possible to remove the forward slash that is automatically being generated.
From reviewing the code, creating mock samples and such I don't see the problem. Yes I do see the extra forward slash as you mention in your post however that is by design. That is how the ASMX service notes the method within the class to execute.
Now from your SOAP message and your WebService \ WebMethod attributes there is something out of sync. Your SOAP Header action should be
urn:mycode:us:gu:das:supplierengagement:v02:SupplierEngagement:AppointSupplier/appointSupplierReq
not
urn:mycode:us:gu:das:supplierengagement:v02:SupplierEngagement:/AppointSupplier
This leads me to believe either you haven't updated the SOAP UI project to the new generated WSDL. Try creating a new Project in SOAP UI pointing the WSDL file of the ASMX web service such as.
http://<web host>/SupplierEngagement.asmx?wsdl
And run the test methods. If this does not fix the issue please post (as an edit) the full class for the SupplierEngagement asmx file (you can omit the method content) as we are only really interested in the full setup.
I had a similar issue that was finally a permissions issues on the server side that was providing the forward slash error, but other things can be done to diagnose the problem
Can the SoapAction of a SOAP REQUEST be altered by interoperability issues between .NET and JAVA or a network/infraestructure proxy

CORS POST Requests not working - OPTIONS (Bad Request) - The origin is not allowed

I'm having a lot of trouble getting a cross domain POST request to hit an Api controller in the latest beta 2 release.
Chrome (and other browsers) spit out:
OPTIONS http://api.hybridwebapp.com/api/values 400 (Bad Request)
POST http://api.hybridwebapp.com/api/values 404 (Not Found)
It may be related to this issue but I have applied that workaround and several other fixes such as web.config additions here
I've been banging my head with this for a while so I created a solution to reproduce the problem exactly.
Load the web app there will be 2 buttons one for GET one for POST and the response will appear next to the button. GET works. Cannot get POST to return successfully.
I'm able to get a hint at the cause from Fiddler but it makes no sense because if you look at the response it DOES include the domain in the Access-Controll-Allow-Origin header:
There is a folder in the solution called "ConfigurationScreenshots" with a few screenshots of the IIS configuration (website bindings) and Project properties configurations to make it as easy as possible to help me :)
EDIT: Don't forget to add this entry to host file (%SystemRoot%\system32\drivers\etc):
127.0.0.1 hybridwebapp.com api.hybridwebapp.com
**STATUS: ** It seems that some browsers like Chrome allow me to proceed with the POST regardless of the error message in the OPTIONS response (while others like Firefox don't). But I don't consider that solved.
Look at the Fidler screenshots of the OPTIONS request it has
Access-Control-Allow-Origin: http://hybridwebapp.com
And yet the error:
The origin http://hybridwebapp.com is not allowed
That is completely contradictory it's as if it's ignoring the header.
Ok I got past this. This has got to be the strangest issue I've ever encountered. Here's how to "solve" it:
Continue on with life as usual until suddenly out of no where OPTIONS requests to this domain begin returning 200 OK (instead of 400 Bad Request) and POST never happens (or at least seems like it doesn't because the browser swallows it)
Realize that Fiddler's OPTIONS response mysteriously contains duplicates for "Access-Control-Allow-XXX".
Try removing the following statement from you web.config even though you clearly remember trying that to fix the previous issue and it not working:
Remove this:
<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
<add name="Access-Control-Allow-Origin" value="http://mydomain.com" />
<add name="Access-Control-Allow-Headers" value="Accept, Content-Type, Origin" />
<add name="Access-Control-Allow-Methods" value="GET, PUT, POST, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
Because you already have this:
var enableCorsAttribute = new EnableCorsAttribute("http://mydomain.com",
"Origin, Content-Type, Accept",
"GET, PUT, POST, DELETE, OPTIONS");
config.EnableCors(enableCorsAttribute);
Moral: You only need one.
if you use OAuth Authorization . request not go direct to web api. You need to enable OWIN CORS support for that endpoint.
How i do on my site:
Install owin cors
Install-Package Microsoft.Owin.Cors
Note: please not use : Install-Package Microsoft.AspNet.WebApi.Cors
In file Startup.Auth.cs
//add this line
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
I have an MVC controller (not an ApiController) but the solution I came up with may help others. To allow cross domain access to a POST action (/data/xlsx) on the controller I implemented 2 actions:
for the pre-flight check
for the post
If you don't have the HttpOptions action then you get 404's on the pre-flight check.
Code:
[HttpOptions]
public ActionResult Xlsx()
{
// Catches and authorises pre-flight requests for /data/xlsx from remote domains
Response.AddHeader("Access-Control-Allow-Origin", "*");
Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
Response.AddHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS");
return null;
}
[HttpPost]
public ActionResult Xlsx(string data, string name)
{
Xlsx(); // Add CORS headers
/* ... implementation here ... */
}
I've tested it in IE 11, Chrome, FireFox.
Add this to your startup.cs file inside ConfigureOAuth
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
Try to add below code in your Response header:
Response.AddHeader("Access-Control-Allow-Origin", "*");

Coldfusion SOAP request preview

I need to consume a asp.net web service using ColdFusion 8 and return an XML file.
I am able to communicate with asp.net service but am returned an error from the service that basically says the information I passed was not valid.
Here is a run down of my code :
<cfxml variable="soap">
<?xml version="1.0" encoding="UTF-8" ?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<cfoutput> <GetSession xmlns="#stagingurl#"></cfoutput>
<strApplicationKey>myappkey</strApplicationKey>
<UID>myuserid</UID>
<arrProperties>
<Property>
<Name>IP</Name>
<Value>127.0.0.1</Value>
</Property>
</arrProperties>
<arrRoles />
</GetSession>
</soap:Body>
</soap:Envelope>
</cfxml>
<cfhttp url="#apiurl#" method="post" result="httpresponse" port="443">
<cfhttpparam type="header" name="content-type" value="text/xml">
<cfhttpparam type="header" name="SOAPAction" value="#mysoapaction#">
<cfhttpparam type="header" name="content-length" value="#len(trim(soap))#">
<cfhttpparam type="header" name="charset" value="utf-8">
<cfhttpparam type="Body" value="#trim(soap)#" name="FileContent"/>
</cfhttp>
<cfdump var="#GetHttpRequestData()#" label="Get Http Request Data" />
Is there a way to preview the information being sent to make sure that ColdFusion is actually sending my XML/SOAP request?
I did use #GetHttpRequestData()# to return some data and within the structure, content is "empty string" and this is where I need help. Should this be empty? This is new for me, but, I guess I expected that my information being passed to the asp.net service would be in there.
FYI - I can see the HTTP and SOAP response fine, I just can not see the request information. How do I view the Request information?
Still trying to determine if the issue is on my end, or theirs and need to gather facts at this point.
Another invaluable tool when working with web services is soapUI. That should definitely be a part of your toolkit as well. You can build your request using soapUI and check the responses. Once you have it working with soapUI you can copy your request into your ColdFusion code.
One thing that I noticed is that your are wrapping your XML in a cfxml tag. I'm not sure if that is messing with your request or not. I typically wrap my XML request in cfsavecontent tags. So you could try changing your code like this:
<cfsavecontent variable="soap">
<?xml version="1.0" encoding="UTF-8" ?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<cfoutput> <GetSession xmlns="#stagingurl#"></cfoutput>
<strApplicationKey>myappkey</strApplicationKey>
<UID>myuserid</UID>
<arrProperties>
<Property>
<Name>IP</Name>
<Value>127.0.0.1</Value>
</Property>
</arrProperties>
<arrRoles />
</GetSession>
</soap:Body>
</soap:Envelope>
</cfsavecontent>
The rest of your code can remain the same.
If you're on Windows (or have a windows machine to hand) install Fiddler and start it. It's a proxy that listens on port 8888 by default so in your cfhttp call, add proxyServer="127.0.0.1" and proxyPort="8888" and run your request again.
Just noticed that you're using port 443, so probably SSL. You can enable HTTPS decrypt Tools->Fiddler Options->HTTPS Tab->Decrypt HTTPS traffic. You may then also need to import the Certificate that Fiddler uses into your keystore.
Each request will now show up in Fiddler and you can use the request and response inspectors on the right to look at the exact data going between the servers (the Raw tab shows the data unchanged). This has saved me so many times and is now part of my standard toolkit.
In your particular case, is there a reason you're not using CreateObject("webservice","http://....") . I'm assuming that it's not playing well with a .Net-based webservice?
Also, the call to GetHttpRequestData() shows the request you made to your test page, not the HTTP call you made to the test webservice. Unfortunately, CFHTTP doesn't return any structure showing the full HTTP request details it used. I think that would be a pretty sound feature request, as at the moment, you'll have to use a tool like fiddler or wireshark to see what was sent.
Simple issue with dot net is, it cannot processs XML document created by coldfusion. To return XML to dot net, convert into string format (XMLvariable.Tostring)
param of HTTP request should be
<cfhttpparam type="Body" value="#trim(soap).ToString#" name="FileContent"/>

Resources