Expose an existing API through HTTP Inbound Endpoint - wso2

I have an API deployed en wso2 ESB500. Just take this as an example.
<api xmlns="http://ws.apache.org/ns/synapse" name="patient" context="/patient">
<resource methods="GET" uri-template="/{patientID}">
<inSequence>
<payloadFactory media-type="text">
<format>I am patient $1</format>
<args>
<arg evaluator="xml" expression="get-property('uri.var.patientID')"/>
</args>
</payloadFactory>
<respond/>
</inSequence>
</resource>
</api>
I have the requirement to expose it in three different ways. One in plain HTTP, one way HTTPS and two way HTTPS. So there are 3 kind of consumers for the API, non-secured ones, secured ones, and "doubled" secured ones.
Multi-HTTPS is not an option as we are not able to start the ESB with different listening interfaces. So I have decided to expose the original API through three different HTTP Inbound Endpoints
This one exposes the API in regular HTTP
<?xml version="1.0" encoding="UTF-8"?>
<inboundEndpoint xmlns="http://ws.apache.org/ns/synapse"
name="http"
protocol="http"
suspend="false">
<parameters>
<parameter name="inbound.http.port">40000</parameter>
<parameter name="dispatch.filter.pattern">/patient/.*</parameter>
</parameters>
</inboundEndpoint>
This other one exposes the API in one way HTTPS
<?xml version="1.0" encoding="UTF-8"?>
<inboundEndpoint xmlns="http://ws.apache.org/ns/synapse"
name="oneWayHttps"
protocol="https"
suspend="false">
<parameters>
<parameter name="inbound.http.port">40001</parameter>
<parameter name="keystore">
<KeyStore xmlns="">
<Location>repository/resources/security/wso2carbon0.jks</Location>
<Type>JKS</Type>
<Password>wso2carbon</Password>
<KeyPassword>wso2carbon</KeyPassword>
</KeyStore>
</parameter>
<parameter name="dispatch.filter.pattern">/patient/.*</parameter>
</parameters>
</inboundEndpoint>
And two way HTTPS finally
<?xml version="1.0" encoding="UTF-8"?>
<inboundEndpoint xmlns="http://ws.apache.org/ns/synapse"
name="twoWayHttps"
protocol="https"
suspend="false">
<parameters>
<parameter name="inbound.http.port">40002</parameter>
<parameter name="keystore">
<KeyStore xmlns="">
<Location>repository/resources/security/wso2carbon1.jks</Location>
<Type>JKS</Type>
<Password>wso2carbon</Password>
<KeyPassword>wso2carbon</KeyPassword>
</KeyStore>
</parameter>
<parameter name="truststore">
<TrustStore xmlns="">
<Location>repository/resources/security/client-truststore.jks</Location>
<Type>JKS</Type>
<Password>wso2carbon</Password>
</TrustStore>
</parameter>
<parameter name="SSLVerifyClient">require</parameter>
<parameter name="dispatch.filter.pattern">/patient/[0-9]+</parameter>
</parameters>
</inboundEndpoint>
Everything works perfect. I give each client a different port and they are happy. But I have noticed the original API is still exposed through the transportReceiver configured in the axis2.xml file. So I would it like to be hidden, nobody should be calling it directly, but through the Inbounds. I know you can achieve this using firewall or load balancers. But I would like to know if there is a way to achieve it using an ESB solution.
I have thougth about inserting a property inside the inboud endpoint and check for its existance in the API itself. But it is not working for me as it seems the sequence for the inbound Endpoint is only executed when there is no dispatch.filter.pattern.
From the docs
The regular expression that defines the proxy services and API's to
expose via the inbound endpoint. Provide the .* expression to expose
all proxy services and API's or provide an expression similar to
^(/foo|/bar|/services/MyProxy)$ to define a set of services to expose
via the inbound endpoint. If you do not provide an expression only the
defined sequence of the inbound endpoint will be accessible.
So here I ask a lot of questions. But I believe the most important one is whenever I have an already deployed API en the ESB, how can I expose it in http, https one-way and mutual? and how can I hide the original API?
EDIT, the inbound.only parameter seems to be exactly what I am looking for. Unfortunately it is only available for proxy services, not API. Besides according to the documentation it can only be used in HTTP Inbound, not HTTPS.

You can expose not only APIs but also proxy services through the inbound endpoints. Here for the proxy services, there is a parameter inbound.only which allows only the inbound endpoint to invoke the proxy service. This parameter seems to be available only for the proxy services [1]. Refer to the following sample configuration
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="patient"
startOnLoad="true"
statistics="disable"
trace="disable"
transports="http,https">
<target>
<inSequence>
<log level="custom">
<property name="--Proxy--" value="invoked"/>
</log>
<respond/>
</inSequence>
</target>
<parameter name="inbound.only">true</parameter>
<description/>
</proxy>
[1]- https://docs.wso2.com/display/EI660/HTTP+Inbound+Protocol

Related

How can WSO2 pick up messages from ActiveMQ without calling any WSO2 api or proxy by client application?

How can WSO2 pick up messages from ActiveMQ without calling any WSO2 api or proxy by client application?
[Please note:- Source System will send messages through ActiveMQ and WSO2 will have to pick up those messages]
Can anybody provide any solution?? I am clueless...
you need to:
Configure wso2 esb to work with activemq...copy /lib
directory to < ESB_HOME>/repository/components/lib
Enable and configure JMSReceiver and JMSSender for Activemq in conf/axis2/axis2.xml. uncomment the configuration for activemq.
The wso2 esb proxy need jms transport active inside it configuration.
configure this parameters after target section inside proxy configuration:
<proxy xmlns="http://ws.apache.org/ns/synapse" name="ForwardProxy" startOnLoad="true" statistics="disable" trace="disable" transports="jms1">
<target>
</target>
<parameter name="transport.jms.DestinationType">queue</parameter>
<parameter name="transport.jms.Destination">yourQueue</parameter>
<parameter name="transport.jms.ContentType">
<rules xmlns="">
<jmsProperty>contentType</jmsProperty>
<default>application/xml</default>
</rules>
</parameter>
<parametername="transport.jms.ConnectionFactory">
myQueueConnectionFactory
</parameter>
</proxy>
create yourQueue inside activeMQ.
put a message in yourQueue.

WSO2 Esb VFS through proxy

I am currently trying to set up a vfs proxy which works fine on a local ftp server. The problem is that our company internet access is blocked by a proxy so I am searching for how to specify this proxy information. As far as I know JSCH is used underneath but I haven't found a way to pass the proxy parameter.
Here is my current proxy xml:
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="ftpCollection" statistics="disable" trace="disable" transports="vfs">
<target>
<inSequence>
<clone>
<target sequence="processSeq"/>
</clone>
</inSequence>
<outSequence/>
<faultSequence/>
</target>
<parameter name="transport.vfs.ReplyFileURI">vfs:sftp://user:pw#192.168.2.99:22/reply</parameter>
<parameter name="transport.PollInterval">15</parameter>
<parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
<parameter name="transport.vfs.FileProcessInterval">100</parameter>
<parameter name="transport.vfs.FileURI">vfs:sftp://user:pw#192.168.2.99:22/process/</parameter>
<parameter name="transport.vfs.MoveAfterProcess">vfs:sftp://user:pw#192.168.2.99:22/success/</parameter>
<parameter name="transport.vfs.MoveAfterFailure">vfs:sftp://user:pw#192.168.2.99:22/failure/</parameter>
<parameter name="transport.vfs.FileNamePattern">.*.xml</parameter>
<parameter name="transport.vfs.Locking">disable</parameter>
<parameter name="transport.vfs.ContentType">application/xml</parameter>
<parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
<parameter name="transport.vfs.MoveTimestampFormat">yyyy-MM-dd'T'HH:mm:ss.SSS</parameter>
</proxy>
Thanks
SFTP (SSH) through a proxy does work over a HTTP tunnel. You can do that with JSch described on this page.
Now already the VFS transport in WSO2 (which finally uses JSch) does not have an implementation of the HTTP tunneling. So you cannot use a simple VFS WSO2 ProxyService to do that.
You can solve it by implementing your own wso2esb transport listener. Have a look at the code of VFSTransportListener.java (or just copy/paste) and code the JSch access over http yourself. You can then add the transport in the axis2.xml configuration of your wso2esb.

WSO2 ESB as a JMS Producer and Consumer

I have been trying to do a poc and WSO2 ESB as a JMS producer and consumer. First thing a could not understand is that how our proxy service will consume the message, do we need to initiate or run the service using tryit or soap ui, or it will consume message every time whenever there is a new message in the queue.
can anyone suggest a link or provide a step by step example for this.
below are my proxy service source:
<proxy xmlns="http://ws.apache.org/ns/synapse" name="NewJMSQueue" transports="jms" statistics="disable" trace="disable" startOnLoad="true">
<target>
<inSequence>
<log level="full"/>
<send>
<endpoint>
<address uri="http://localhost:9000/services/SimpleStockQuoteService"/>
</endpoint>
</send>
</inSequence>
</target>
<parameter name="transport.jms.ContentType">
<rules>
<jmsProperty>contentType</jmsProperty>
<default>application/xml</default>
</rules>
</parameter>
<parameter name="transport.jms.Destination">NewJMSQueue</parameter>
<description></description>
</proxy>
You can find several examples from here where ESB is used as a JMS consumer and a producer.
When you put the message into the queue the proxy will automatically pick it from the queue. That is by default ESB will be listening on a JMS queue with the same name as the proxy service and when there is a message proxy service will pick that. Note that you have to configure the JMS transport listener in order achieve that.
You need to copy the required libraries to ESB_HOME/repository/components/lib folder (activemq-core-5.7.0.jar, geronimo-j2ee-management_1.1_spec-1.0.1.jar, and geronimo-jms_1.1_spec-1.1.1.jar)

WSO2 ESB ftp to SOAP

We have a legacy application that is only able to upload files through ftp protocol. Our current application has SOAP interface for similar file submissions. Is there any way to configure the WSO2 ESB to transform the uploaded file through ftp to SOAP request for consuming by our current application?
Yes that is a very common approach. You can create a VFS proxy that is reading from an FTP. You may then make a transformation (depends on the input format) (i.e. XSLT) to fit your SOAP Endpoint and then simply make a <send> to your WS.
Here an example (only pseudo-code - not tested), but will give you a good starting point:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="ftp_proxy_example" transports="vfs" startOnLoad="true" trace="disable">
<parameter name="transport.PollInterval">10</parameter>
<parameter name="transport.vfs.FileURI">vfs:ftp://user:password#server/path</parameter>
<parameter name="transport.vfs.FileNamePattern">.*[.]xml</parameter>
<parameter name="transport.vfs.ContentType">application/xml</parameter>
<target faultSequence="errorSequence">
<inSequence>
<!-- maybe a transformation -->
<!-- send to your WS endpoint -->
</inSequence>
</target>
</proxy>

WSO2 ESB SFTP Listener not firing

i am testing some sample use cases with WSO2 where the ESB must scan an SFTP folder and perform some actions. Here is what i did:
1) I enabled the VFS transport listener in axis2.xml:
<transportReceiver name="vfs" class="org.apache.synapse.transport.vfs.VFSTransportListener"/>
<transportSender name="vfs" class="org.apache.synapse.transport.vfs.VFSTransportSender"/>
2) I inserted the following proxy (i have changed user:pass for obvious reasons) :
<proxy xmlns="http://ws.apache.org/ns/synapse" name="SFTPVFSProxy" transports="vfs" statistics="disable" trace="enable" startOnLoad="true">
<target>
<inSequence>
<log level="full" />
</inSequence>
</target>
<parameter name="transport.vfs.ActionAfterProcess">MOVE</parameter>
<parameter name="transport.PollInterval">3</parameter>
<parameter name="transport.vfs.MoveAfterProcess">vfs:sftp://user:pass#10.254.241.69:22/home/user/sftp/out</parameter>
<parameter name="transport.vfs.FileURI">vfs:sftp://user:pass#10.254.241.69:22/home/user/sftp/in</parameter>
<parameter name="transport.vfs.MoveAfterFailure">vfs:sftp://user:pass#10.254.241.69:22/home/user/sftp/out</parameter>
<parameter name="transport.vfs.FileNamePattern">.*.txt</parameter>
<parameter name="transport.vfs.ContentType">text/plain</parameter>
<parameter name="transport.vfs.ActionAfterFailure">MOVE</parameter>
</proxy>
In both versions 4.5.0 & 4.5.1 nothing is triggered. No output in the log files other than some info that the proxy was successfully deployed. The exact same script works in version 3.0.1.
Furthermore, if i change "sftp" to "ftp" or to local file the listener is triggered normally in v4.X as well which makes me believe it's probably something specific to sftp handling.
Am i doing something wrong or is there a bug in the software?
Thank you in advance,
Thodoris
I think the problem is with the way you have defined the transport.vfs.FileURI property. Assuming your user's username is "user", then when you log in to sftp you go to the /home/user folder. Therefore, try defining the above property as follows.
<parameter name="transport.vfs.FileURI">vfs:sftp://user:pass#10.254.241.69:22/sftp/in</parameter>
or
<parameter name="transport.vfs.FileURI">vfs:sftp://user:pass#10.254.241.69:22/in</parameter>
I cannot say the exact config because I dont know your folder structure.
I have tried this in WSO2 ESB 4.0.3 with SFTP. My username was amilaftp. So I defined the property as follows.
<parameter name="transport.vfs.FileURI">vfs:sftp://amilaftp:password#localhost/in?vfs.passive=true</parameter>
When you try with FTP, you need to give the full path as you have done in the configuration you have provided. Thats why it is working for you with FTP in WSO2 ESB 4.X. If this works for you in 4.0.3, this should work in 4.5.x too. I suggest you to try with 4.0.3 first because it has worked for me.