Is there a more effective way of configuring API's for CA API Gateway - api-gateway

I am trying to configure some API's through CA-API Gateway.
However the CA product seem to be heavily based on UI interaction JSP.
I have seen that they also provide REST interface.
Has anyone set up a complete API using something else than the JAVA based UI?
Ideally I would like to have my complete configurations as code.
The REST api for the API Gateway seems to provide a lot of get and post functionality, but I have not been able to get it working:
Executing a get template towards my CA APIGW instance (https://localhost:9443/restman/1.0/services/template) yields:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<l7:Item xmlns:l7="http://ns.l7tech.com/2010/04/gateway-management">
<l7:Name>SERVICE Template</l7:Name>
<l7:Type>SERVICE</l7:Type>
<l7:TimeStamp>2017-06-13T07:30:22.487Z</l7:TimeStamp>
<l7:Link rel="self" uri="https://d7a66e5db02e:9443/restman/1.0/services/template"/>
<l7:Link rel="list" uri="https://d7a66e5db02e:9443/restman/1.0/services"/>
<l7:Resource>
<l7:Service>
<l7:ServiceDetail folderId="FolderID">
<l7:Name>My New Service</l7:Name>
<l7:Enabled>false</l7:Enabled>
</l7:ServiceDetail>
<l7:Resources>
<l7:ResourceSet tag="policy">
<l7:Resource type="policy">Policy XML</l7:Resource>
</l7:ResourceSet>
</l7:Resources>
</l7:Service>
</l7:Resource>
</l7:Item>
From reading the template I expect to be able to create a new published service using post and the following body:
<l7:Service>
<l7:ServiceDetail folderId="0000000000000000ffffffffffffec76">
<l7:Name>MyNewService</l7:Name>
<l7:Enabled>false</l7:Enabled>
</l7:ServiceDetail>
<l7:Resources>
<l7:ResourceSet tag="policy">
<l7:Resource type="policy">Policy XML</l7:Resource>
</l7:ResourceSet>
</l7:Resources>
</l7:Service>
The POST to https://localhost:9443/restman/1.0/services however yields:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>400 Bad Request</title>
</head>
<body>
<h1>Bad Request</h1>
<h3>The request sent by the client was syntactically incorrect.</h3>
</body>
</html>
And there is no apparent way for me to debug what actually fails.
I would expect to be able to trace the error in a log somewhere but can not find any documentation or examples of this.

The following worked for me:
Query the object type you'd like to create, e.g. GET /restman/1.0/services/{ID} or use GET /restman/1.0/services?name={service-name}
To create a new instance, find the right sub-element of the XML response, e.g. for services //Item/Resource/Service
Use this sub-element in your RESTMAN POST request
If you'd like to oupdate an existing service:
Query the existing version number (and ID)
PUT /restman/1.0/services/{ID} with version in the version attribute
If the version does not match, the update will fail.

There is no good alternative to native CA Policy manager application, but you can use REST management API's to make updates and move policy code between different environments.
All policies are written in XML so you can export them to a file and manage them in your normal version control system.
You can use deployment tools like Jenkins https://jenkins.io where you can configure custom plugin to integrate it with API deployments, but you will still have to rely on RESTMAN API's.
Hope that helps!

Related

Azure API Management Add Auth token param using rewite url/set param?

Help;
Trying to call Dynamics Marketing API from api management however the api has and end point that requires emApplicationtoken to be set as a query param which I don't want to expose and also the Origin header url as the api management url which again i don't want to expose to the public api.
I try to use set the following policy for all operations
<inbound>
<base />
<set-header name="Origin" exists-action="append">
<value>https://someurl</value>
</set-header>
<set-query-parameter name="emApplicationtoken" exists-action="append">
<value>somekeyvalue</value>
</set-query-parameter>
</inbound>
However looking at the trace it never applies. I then tried to use URL rewrite thinking that because the params dont exist then it cant override them or append so ill try adding the emAuthetication toaken by using the following policy
<inbound>
<base />
<rewrite-uri template="/EvtMgmt/api/v2.0/events/{readableEventId}?emApplicationtoken=sametoken=" copy-unmatched-params="true" />
-->
</inbound>
Again, the policy doesn't apply
Here is the api design screen. its a simple API
Screenshot of API setup:
Here is a link to the Event API i am calling in the background. I can get the function working in API management by setting the query params and header, but they are exposed to the public Api which I need to avoid (don't want people seeing the auth token).
https://learn.microsoft.com/en-us/dynamics365/marketing/developer/using-events-api
Hoping some one can tell me what Im doing wrong. Im quite new to API management, and i cant find any real help for this specific problem.
To note when I put the param and header in the policies do apply byt then muck up the url function by duplicating the param and header detail.
Thanks in advance.

Oidc not available

When my oidc is not available, I have this error 500 return on my endpoint generated by Quarkus :
<!doctype html>
<html lang="en">
<head>
<title>Internal Server Error - Error handling c1d5a584-89d8-49ba-9df0-822ecb9b47da-3, io.quarkus.oidc.OIDCException:
OIDC server is not available at the 'http://localhost:8080/auth/realms/test' URL. Please make sure it is
correct. Note it has to end with a realm value if you work with Keycloak, for example:
'https://localhost:8180/auth/realms/quarkus'</title>
<meta charset="utf-8">
<style>...
Is it possible to customize this with a chosen error code and no content ?
I have tried with ExceptionMapper without success
The exception mapper would be what you want, but you may need to use the JAX-RS way of implementing the mapper (docs). This lets you set an #Priority on the mapper implementation so that it triggers earlier than a default defined mapper which is likely what's happening with your request.

How to make self hosted prebid server work with AMP?

The github repo does not mention any thing on how to use the self hosted server work with AMP . They have given an endpoint to access after storing the request in the server:
/openrtb2/amp?tag_id={ID} //id is the file name of request stored.
I do get the empty targeting response(since server is on local setup).But how will this data reach the amp page? where should this endpoint be requested?
I read in AMP docs that user generated js doesn't work in AMP. I also setup rtc config on amp ad tag and adding vendor as per vendor config(callout-vendor.js)which sends request to the bidder's prebid server url. For example:
If i add appnexus in rtc-config vendors, the request is getting sent to:
https://prebid.adnxs.com/pbs/v1/openrtb2/amp?tag_id={id of tag}
How do i make the request to go to self hosted prebid server url
ok, figured this thing out..
Doc reference: https://github.com/ampproject/amphtml/blob/master/extensions/amp-a4a/rtc-publisher-implementation-guide.md#setting-up-rtc-config
So, first we make an amp-ad tag wherein we have rtc-config attribute. Since, we are using our own server, we'll need to add it in url property as mentioned in that example in doc.
<amp-ad width="320" height="50"
type="network-foo"
data-slot="/1234/5678"
rtc-config={"urls":["our-server-url"]}>
</amp-ad>
The targeting data returned by server will be fetched by amp-ad tag and will be appended to adserver request.
Additionally, we can make a pull request to amphtml repo on github to add our server url in callout-vendor.js file
file reference: https://github.com/ampproject/amphtml/blob/master/extensions/amp-a4a/0.1/callout-vendors.js
Then, the amp-ad tag will look like this:
<amp-ad width="320" height="50"
type="network-foo"
data-slot="/1234/5678"
rtc-config={"vendors": {"serverAliasAsSetInCalloutVendorFile": {"MACRO1": "MacroValue"}}>
</amp-ad>

Cordova Https ajax requests fails or encoded response

We have developed an application which is running perfectly fine on desktop and mobile web with verisign certificate (https). We have developed iOS and android cordova application which was working fine with http server. For production they have enabled SSL. The iOS and android hybrid applications are not working fine because of ajax call response. The following response I am receiving for both http and https. Is there any changes required in client side or its all about SSL? Is there any workaround for SSL decoded response? We are using IBM's websphere application server.
Response from http server
[{"SALT":"3FzekTIywrmm9jojnfHn11"}]
Response from https server
<html>
<head>
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Expires" CONTENT="-1"></head><body>
<script type=text/javascript>
function decode_base64(input){
var keyStr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";var output="";
var chr1,chr2,chr3;var enc1,enc2,enc3,enc4;var i=0;input=input.replace(/[^A-Za-z0-9+/=]/g,"");
while(i<input.length){
enc1=keyStr.indexOf(input.charAt(i++));
enc2=keyStr.indexOf(input.charAt(i++));
enc3=keyStr.indexOf(input.charAt(i++));
enc4=keyStr.indexOf(input.charAt(i++));
chr1=(enc1<<2)|(enc2>>4);
chr2=((enc2&15)<<4)|(enc3>>2);
chr3=((enc3&3)<<6)|enc4;output=output+String.fromCharCode(chr1);if(enc3!=64){
output=output+String.fromCharCode(chr2)
}
if(enc4!=64){
output=output+String.fromCharCode(chr3)}}return output;
}
document.write(decode_base64("PHNjcmlwdCB0eXBlPXRleHQvamF2YXNjcmlwdD52YXIgdG9fZGVjPWRlY29kZV9iYXNlNjQoImNtUjFWV2hzWkc1MGRTbG5kRzlpZFdodWJ5RXBLSG9oWlc1aWRHeGtiM1V2Ylc1aVlIVm9ibTg4SXk0eGUzRnZMaU02SVh3dElUQXhNVEVvIik7IGRlY19yZXM9IiI7IHZhciB4b3Jfa2V5PTE7IGZvcihpPTA7aTw2MDtpKyspeyBkZWNfcmVzKz1TdHJpbmcuZnJvbUNoYXJDb2RlKHhvcl9rZXledG9fZGVjLmNoYXJDb2RlQXQoaSkpO30gZXZhbChkZWNfcmVzKTs8L3NjcmlwdD4="));
</script>
</body>
</html>
That is quite odd way to return the error message, but your HTTPS server is telling
i18n-values: Missing value for "primaryParagraph"
You can see that by
copy-paste the HTML to text editor,
Name it like foo.html,
Open it on browser,
Open developer tools and see console where it says that.
To answer your question: from point of view of client-side coding there isn't really much difference between HTTP and HTTPS calls. Browser tends to hide those quite effectively, though the performance is in general weaker on HTTPS calls etc.

Response message not being accepted by WeChat

So we got our application accepted in the wechat debug console, and are looking to respond with rich media type messages.
the request expected from the server is as follows:
<xml>
<ToUserName>UserName</ToUserName>
<FromuserName>TestUser</FromuserName>
<CreateTime>7200</CreateTime>
<MsgId>12302</MsgId>
<Content>Test Message</Content>
</xml>
To which we reply with the following:
<xml>
<ToUserName>TestUser</ToUserName>
<FromUserName>UserName</FromUserName>
<CreateTime>7200</CreateTime>
<MsgType>news</MsgType>
<ArticleCount>1</ArticleCount>
<Articles>
<item>
<Title>Test</Title>
<Description>Test</Description>
<PicUrl>http://PICURL</PicUrl>
<Url>http://ARTICLE_URL</Url>
</item>
</Articles>
</xml>
However the application doesn't seem to be getting the requests as it was setup so the questions is:
Will requests go to the URL setup?
If so is the xml provided correct for the response and also for the messages that gets posted to the url provided?
Are there specific headers presents in the request?
Yes the Requests will go to the URL that you have setup and send a straight XML post to your script.
Check your XML there seems to be quite a few differences from the actual system input and output also check the example of working input and output XML and try this. Obviously replacing the ToUserName and FromUserName:
INPUT RESPONSE
<xml>
<ToUserName><![CDATA[gh_4456]]></ToUserName>
<FromUserName><![CDATA[123abc]]></FromUserName>
<CreateTime>1397201326</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[test]]></Content>
<MsgId>6000934001298302633</MsgId>
</xml>
OUTPUT RESPONSE
<xml>
<ToUserName><![CDATA[123abc]]></ToUserName>
<FromUserName><![CDATA[gh_4456]]></FromUserName>
<CreateTime>1397201781</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<ArticleCount>1</ArticleCount>
<Articles>
<item>
<Title><![CDATA[Your test title]]></Title>
<Description><![CDATA[test description]]></Description>
<PicUrl><![CDATA[http://test.com/img.jpg]]></PicUrl>
<Url><![CDATA[http://test.com/]]></Url>
</item>
</Articles>
</xml>
No headers you need to worry about.
FOR OFFICIAL OA: I think your problem might be that you have not enabled developer mode yet. Even though you have setup the URL and TOKEN. Please confirm developer mode is ENABLED. Go to admin.wechat.com -> login -> function -> advanced -> developer mode should be ENABLED.
FOR SANDBOX ACCOUNT: developer mode is always enabled.
Also check your CreateTime this should be a unix timestamp.
If none of that resolves it go and look at your access logs. Find the URL wechat is posting to. Once you have the URL got to http://www.hurl.it/ change the destination type to POST and paste the URL there. Add a Header called "Content-Type" with the value "text/xml" click on add body and post your input response in there. This will give you the response that WeChat sees. I tested yours and found the ToUserName was blank, also ensure you don't have unneeded spaces or newlines there.

Resources