How can I configure WSO2 to automatically replace API urls? - uri

I have an API running on http://my_internal_api.com, and I'm exposing it with WSO2, on https://mywso2:8280/my_api.
Everything works just fine, but the REST API is giving off url attributes in json that are formatted for the original server url.
Example:
When retrieving contact info, I get a JSON object:
[{contact_id: 1, url: contact_url}, {}]
This contact_url is in the form: http://my_internal_api.com/contacts/1
It should be: https://mywso2:8280/my_api/contacts/1
Is there a way to solve this? I'm guessing a squence should be used, but I don't know if this is the right approach or I'm trying to reinvent the wheel.

You can add an out sequence using mediation extension[1].There find all occurrence of "my_internal_api.com" and replace by "mywso2:8280".For replacing you string in the payload you can use the script mediator.
<script language="js">
var payload = mc.getPayloadXML().toString();
<property name="PAYLOAD" value="payload"/>
var changedPayload = payload.replace(/http:\/\/my_internal_api.com/, mc.getProperty('apiURL'));
var xml = new XML(newPayLoad);
mc.setPayloadXML(xml);</script>
1.https://docs.wso2.com/display/AM180/Adding+Mediation+Extensions

The easiest way is to use a header mediator to add a X-Forwarded-Host header, like this:
<sequence name="WSO2AM--Ext--In">
<header name="X-Forwarded-Host"
scope="transport"
expression="get-property('transport','Host')"/>
<header name="X-Forwarded-Proto" scope="transport" value="https"/>
</sequence>
This way, most APIs will be able to correctly resolve the host

Related

Call a Google App Maker App with a parameter

Hello i am new here so if i ask a stupid question please forgive me.
We at AppAtSchool are working with Google ApMaker and we want to call a published App with 2 parameters. How can we read those in App Maker? Thanks in advance!
I'm guessing, that you are trying to read page URL parameters. In this case you can pass parameters like this:
https://script.google.com/<SomeMagic>/exec/?param1=value1&param2=value2#PageName
And then read them in page onAttach event(https://developers.google.com/appmaker/ui/logic#events):
google.script.url.getLocation(function(location) {
var params = location.parameter;
var param1 = params.param1;
var param2 = params.param2;
// Use parameters...
});
Maybe you also will need a way to genarate such links with parameters:
Integration between different Google Appmaker Apps
you can call your application with url something like this: script.google.com/blablabla/#viewname/paramValue, and take param on client side and send it to server side.
If you pass parameters to your App Maker app through URL parameters, your app can read the parameters using the google.script.url.getLocation method:
google.script.url.getLocation(function(location) {
console.log(location.parameters);
console.log(location.hash);
});
Find more details in the documentation

Linq2Dynamodb run expression string on Table

I have an ASP.NET Web API site which records all objects in AWS DynamoDb. I took a quick look at linq2Dynamodb. It seems that the common way to use it is like:
var moviesTable = ctx.GetTable<Movie>();
var inceptionMovie = moviesTable
.Where(m => m.Genre == "Thriller" && m.Title == "Inception")
.Single();
But I want some API like:
moviesTable.Execute(string querystring);
The reason is that from the Web API, I usually get some query like:
http://host/service.svc/Orders?$filter=ShipCountry eq 'France'
I'd like to pass the filter string "ShipCountry eq 'France'" here. Do anyone know if there is a way for me to do this? Thanks.
With Linq2DynamoDb you can expose your DynamoDb tables as OData resources. Please, see the doc here.
As soon as you have an OData resource, you can query it with OData queries of any valid kind.
And you can use any OData client library for that. E.g. with System.Data.Services.Client you would say something like:
var entities = myContext.Execute<MyEntityType>(new Uri("<here goes URI with valid OData query string>"), "GET", true);
or just construct a LINQ query on the client side.
The drawback is that you will need to host your OData service somewhere (DynamoDb itself doesn't support OData, so that's the reason).
The advantages are:
you will be able to cache your data in ElastiCache.
you will be able to implement custom authentication inside your service.
Sorry for a bit late answer.

Is it possible to use computed keys with KeyValueMaps?

I would like to use KeyValueMaps to store some simple values, but they keys I need to use would be computed at runtime. For example in my 'InitialEntries' I want to do something like this:
<KeyValueMapOperations async="false" continueOnError="false" enabled="true" name="Sandbox-Read-Count">
<DisplayName>Sandbox - Read Count</DisplayName>
<FaultRules/>
<Properties/>
<ExclusiveCache>false</ExclusiveCache>
<ExpiryTimeInSecs>-1</ExpiryTimeInSecs>
<InitialEntries>
<Entry>
<Key>
<Parameter>{variable}.sandbox.calls</Parameter>
</Key>
<Value>0</Value>
</Entry>
</InitialEntries>
<Scope>apiproxy</Scope>
</KeyValueMapOperations>
However, when doing this I get an error when I try to save the policy:
Error while Uploading file for API Test.
messaging.config.beans.InvalidBundle. Errors:[Entity : policy-Sandbox-Read-Count, Invalid Key Names For Entries: [{apikey}.sandbox.calls];]
Is it possible to use computed values in the KeyValueMap policy? Is there a different syntax that I should be using?
I've investigated this. What happens is when you save the proxy with InitialEntries in the apiproxy-scoped KVM, the KVM is immediately created with the initial entries. Therefore, there is no way to use runtime variables, because the priming of the KVM has happened before the proxy ever runs.
You didn't use the mapIdentifier field in your KeyValueMapOperations element (look at the KeyValueMap PUT Sample in the Apigee docs), so the KVM you would create would be named kvmap.
You can use the following management API call to get a list of the KVMs and their contents for a given apiproxy:
GET https://api.enterprise.apigee.com/v1/o/{org}/apis/{apiname}/keyvaluemaps?expand=true
Authorization: Basic {base64 username:password}
Since The InitialEntries section is only used when the proxy is first loaded successfully (even if you change the InitialEntries section and redeploy, no changes will be made if the KVM of that name already exists), I think the usefulness of the InitialEntries section is rather limited. I'd recommend manually priming your KVM's using the management API to initialize the KVM:
PUT https://api.enterprise.apigee.com/v1/o/{org}/apis/{apiname}/keyvaluemaps
Authorization: Basic {base64 username:password}
Content-Type: application/json
{
"entry" : [ {
"name" : "key",
"value" : "0"
} ],
"name" : "{kvmName}"
}

Spring Integration HTTP inbound adapter method name?

Is it possible to map the method name to a header with a int-http:inbound-gateway? for example:
<int-http:inbound-gateway request-channel="requests" reply-channel="replies"
supported-moethds="GET,PUT"
path="/user">
<int-http:header name="requestMethod" expression="#requestMethod"/>
</int-http:inbound-gateway>
<!-- ... -->
<int:header-value-router input-channel="requests" header-name="requestMethod>
<int:mapping value="GET" channel="getUserRequests"/>
<int:mapping value="PUT" channel="addUserRequests"/>
</int:header-value-router>
Furthermore, I see examples that utilize #requestParams, but the javadoc for 2.1 mentions #queryParameters, and I don't see documentation for either of these in the official documentation page. Do you guys know a good resource that describes not only how SpEL parses expressions but what fields are available to use with it? All I can tell is I have headers, payload, #pathVariables, and maybe #requestParams or #queryParams, along with any other #beans I have defined in the current context.
Thanks in advance!
That method is always mapped to a header
... http_requestMethod=POST ...
Message<?> message = messageBuilder
.setHeader(org.springframework.integration.http.HttpHeaders.REQUEST_URL, request.getURI().toString())
.setHeader(org.springframework.integration.http.HttpHeaders.REQUEST_METHOD, request.getMethod().toString())
.setHeader(org.springframework.integration.http.HttpHeaders.USER_PRINCIPAL, servletRequest.getUserPrincipal())
.build();
The javadoc is wrong. The two additional variables are #requestParams and #pathVariables.

JAX-WS: define server side handler chain in code and not in external xml

i want to enable http compression for my jax-ws webservice. i found out that i have to do it with a custom handlerchain that can modify the http-headers.
all tutorials i found refer to the annotation #HandlerChain that points to a handler chain configuration xml-file but my problem is that my webservice has to be as lightweight as possible therefore i cant define my handler chain in an external xml file.
i tried the following but did not succeed:
final Endpoint ep = Endpoint.publish("http://localhost:8878/mywebservice",
new WebserviceImpl() );
final Binding binding = ep.getBinding();
final List<Handler> handlerChain = binding.getHandlerChain();
handlerChain.add(new MySuperbSOAPHandler());
binding.setHandlerChain(handlerChain);
does anyone know how to do this? is it even possible?
It doesn't appear that you can change the handler chain when the service has already been published.
If your actual use case is as above, it's easy to fix by simply create()ing and then publish()ing.
final Endpoint ep = Endpoint.create(new WebserviceImpl() );
final Binding binding = ep.getBinding();
final List<Handler> handlerChain = binding.getHandlerChain();
handlerChain.add(new MySuperbSOAPHandler());
binding.setHandlerChain(handlerChain);
ep.publish("http://localhost:8878/mywebservice");

Resources