tag:blogger.com,1999:blog-65688989181453715422017-09-26T23:40:47.655-07:00Ryan CarterRyan Carterhttp://www.blogger.com/profile/12683154470348126758noreply@blogger.comBlogger8125tag:blogger.com,1999:blog-6568898918145371542.post-58002309198706146642015-09-12T13:40:00.002-07:002015-09-12T13:40:14.824-07:00Deploying Mule to Websphere<p>This post describes the necessary stops to deploy a Mule application to WebSphere Application Server(In this case 7.x and Mule 3.3.x, both older version of each products so may need less/additional changes for newer versions) and some additional steps if you are using certain modules such as CXF.</p> <h3>Enable parent last class loading</h3> <p>Only do this at the MODULE level. Navigate to: </p><p>Application Types > WebSphere enterprise applications > swaggerProject_war > Modules > Manage Modules > myApp.war </p><p? Change: Class loader order -> Classes loaded with local class loader first (parent last) Apply and Save directly to the master configuration. </p> <h3>Exclude Servlet APIs and Geronimo Stax lib</h3><p><script src="https://gist.github.com/ryandcarter/72fa9056cf7a4383d964.js?file=plugin-snippet-pom.xml"></script></p> <h3>Disable IBM JAXWS Engine</h3> <p>Modify the configuration of the maven-war-plugin to add a manifest entry to shut off activation of IBM WSAS' JAX-WS engine. (Add the following manifestEntries element to the maven-war-plugin configuration: <script src="https://gist.github.com/ryandcarter/72fa9056cf7a4383d964.js?file=jaxws-snippet-pom.xml"></script> </p><h3>Add additional JVM/Endorsed dependencies</h3><p><script src="https://gist.github.com/ryandcarter/72fa9056cf7a4383d964.js?file=dependencies-pom.xml"></script><p>Ryan Carterhttp://www.blogger.com/profile/12683154470348126758noreply@blogger.com0tag:blogger.com,1999:blog-6568898918145371542.post-55568574071730075392014-06-12T07:02:00.000-07:002014-06-12T07:16:51.318-07:00Synchronizing data across Mule applications with MongoDB<p>One of the many things that Mule does extremely well, is transparently store state between messages. Take the idempotent-message-filter for example; The idempotent-message-filter keeps track of what messages have been processed previously to ensure no duplicate messages are processed. This is all achieved with one single xml element. Or take OAuth enabled cloud connectors that need to keep track of access tokens so you're not redirected to some authorize page each time. All this is handled behind the scenes without you having to worry about it.</p> <p>Mule’s ability to store this state is implemented via object-stores. Object-stores provide a simple generic way to store data in Mule. Many message processors such as the idempotent-meesage-filter, OAuth message processors, until-successful routers and many more all transparently use object-stores behind the scenes to store state between messages.</p> <p>By default Mule uses in-memory object-stores behind the scenes. Things get more interesting however, when your Mule application is distributed across multiple Mule nodes. At some point you are going to need to synchronise object-stores across multiple applications. If you are fortunate to be using the Enterprise Edition of Mule you can take advantage of its out of the box clustering support for synchronizing state across an entire cluster. But even then as mentioned in this blog post by John Demic: <a href="http://blogs.mulesoft.org/synchronizing-mule-applications-across-data-centers-with-apache-cassandra/">Synchronizing Mule Applications Across Data Centers with Apache Cassandra</a>, this may not be ideal if your Mule nodes are geographically distributed across multiple data centres.</p> <p>In the aforementioned post, John gives a great example of how to use Apache Cassandra as a shared object-store. But many other traditonal and NoSql data stores can be used as well. In this blog post I'm going to show a simple example of how you can achieve the same using MongoDB. If it's good enough for the Hipster Hacker then it's good enough for me!</> <blockquote class="twitter-tweet" lang="en"><p>OMG! Does this officially make <a href="https://twitter.com/MuleSoft">@MuleSoft</a> Mule part of the Hipster Stack? <a href="http://t.co/OwM4dzhGvi">pic.twitter.com/OwM4dzhGvi</a></p>&mdash; Ryan Carter (@rydcarter) <a href="https://twitter.com/rydcarter/statuses/387935535236280320">October 9, 2013</a></blockquote><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script> <h3>Configuring the MongoDB object-store</h3><p><a href="http://www.mongodb.org/">MongoDB</a> is an open-source document database, and the leading NoSQL database. The <a href="https://github.com/mulesoft/mongo-connector">MongoDB module</a> can be used to read/write/query and perform a whole load of other operation a MongoDB database as part of your Mule flows. It also exposes an additional submodule for using your MondogDB database as an object-store implementation in Mule. Here is a sample configuration from one of the tests:</p> <script src="https://gist.github.com/ryandcarter/cb078d3e1a868d856f65.js"></script> <p>As you can see, it's classed as it's own module with it's own namespace and is configured simply using the <b>mos:config name="mos" database="mongo-connector-test"</b> element.</p> <p>However, this doesn't work for the current version of the connector. Due to the following <a href="https://github.com/mulesoft/mongo-connector/pull/32">bug</a>. You can simply apply the fix in the aforementioned pull request, or you can instantiate the object store yourself using Spring - similar to that in the Apache Cassandra configuration.</p> <p>The object-store class can be found here: <a href="https://github.com/mulesoft/mongo-connector/blob/master/src/main/java/org/mule/module/mongo/MongoObjectStore.java">MongoObjectStore.java</a>. As you can see, it has various annotations for default values and initialising the class. However, as we are not using this as a fully fledged Mule Devkit module, those annotations have no effect. So we have to pass in the default values ourselves and call the <i>initialise</i> method when instantiating our object-store.</p> <p>This is quite simple with Spring. Here is a full working example using the Spring instantiated object-store as the store for the idempotent-message-filter: <script src="https://gist.github.com/ryandcarter/c4aad0dfb290646ad1ea.js"></script> <p>If you run this configuration, Mule will poll every 10 seconds with the exact same message: "1". The first time it polls you should see "Passed Filter" in the log output. Subsequent polls should not log anything as the idempotent message filter will filter them out. This is usually performed with the default in-memory object-store. To prove this is persisted you should be able to check the value in the Mongo database collection: <i>db.getCollection('mule.objectstore._default').find()</i>. Also you can stop your Mule app and restart it to prove that it works between restarts and failovers etc. Ryan Carterhttp://www.blogger.com/profile/12683154470348126758noreply@blogger.com1tag:blogger.com,1999:blog-6568898918145371542.post-48783047671245462512014-05-29T05:26:00.000-07:002014-05-29T05:26:37.408-07:00Getting Started with Mule Cloud Connect v1.2 is published<p><div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-e58UdnVZyyA/UQwYSwl7xvI/AAAAAAAAAAQ/HjH7sATVWXg/s1600/chapter01-02-front-231x300.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="http://4.bp.blogspot.com/-e58UdnVZyyA/UQwYSwl7xvI/AAAAAAAAAAQ/HjH7sATVWXg/s320/chapter01-02-front-231x300.png" /></a></div> The O'Reilly book "Getting Started with Mule Cloud Connect"(<a href="http://oreil.ly/mule-cloud">http://oreil.ly/mule-cloud</a>) has been out for just over a year now and has received some great feedback. But there's always room for improvement and with Mule 3.5 ready, I have updated the book to include some new 3.5 functionality and added some extra content.</p> <p>The latest revision covers new Mule 3.5 features including new OAuth functionality and data synchronization. There is also a new chapter on orchestration - something that the original was missing for people new to Mule.</p> <h2>Already got it, and want the updates for free?</h2><p>Good news is that if you already purchased the ebook edition then these updates are free and you can grab the new edition from O'Reilly.</p> <h2>Want a free copy?</h2><p>If you would like to review the book on Amazon, O'Reilly or Google books let me know and I can send you a free review copy.</p> <h2>Want to buy a copy?</h2><p>Buy it direct from O'Reilly and get free updates for the lifetime of the book: <a href="http://oreil.ly/mule-cloud">http://oreil.ly/mule-cloud</a></p>Ryan Carterhttp://www.blogger.com/profile/12683154470348126758noreply@blogger.com0tag:blogger.com,1999:blog-6568898918145371542.post-79833425003197055182013-08-23T07:06:00.000-07:002013-08-23T07:10:10.818-07:00Running Mule on Openshift - Part 2<p>A little while back I wrote a post on "Running Mule Natively on OpenShift" - <a href="http://ryandcarter.blogspot.co.uk/2013/03/natively-running-mule-on-openshift.html">http://ryandcarter.blogspot.co.uk/2013/03/natively-running-mule-on-openshift.html</a>. This post showed some workarounds for a few conflicting "features" of both products and showed how to run a simple Hello World app. Since then both products have moved up major versions with both fixing the need for some of the previous work-arounds and also introducing some new ones. I have also had time to expand on a simple Hello World app and start trying out some other Mule components which also require some hacks to get up and running. In this article I'll do a quick recap of getting the app up and running and then show how to work with these new features.</p> <h3>HTTP Server Binding</h3><p>In the previous post we tried to deploy the following app to Mule 3.3.1:</p><script src="https://gist.github.com/ryandcarter/5082852.js?file=helloworld.xml"></script> <p>The only thing to take note of here is that we are using the ${OPENSHIFT_DIY_IP} environment variable which has changed from the previous ${OPENSHIFT_INTERNAL_IP}. This is the suggested IP address for creating socket connections on localhost. Typical values like "localhost", "127.0.0.1" and "0.0.0.0" are all locked down. </p> However, if you try using this environment variable as your host you will get an error similar to the following: </p><p><i>Permission denied (java.net.BindException) java.net.PlainSocketImpl:-2 (null) 2. Failed to bind to uri "http://127.8.109.1:8080"</i></p> <p>After digging through the source, there is a slight issue with Mules' TCP transport for versions < 3.4.</p><script src="https://gist.github.com/ryandcarter/5082852.js?file=TcpServerSocketFactory.java"></script> <p>Here, the internal IP is a loopback address, so Mule forces it down the path of creating a TCP socket that listens on all interfaces for that port. Fortunately there is already af fix in the 3.4 release which is now GA. If you want to use Mule versions < 3.4 then you will need to modify the TCP transport as detailed in the previous post.</p> <h3>HTTP Client Binding</h3><p>The previous app just focused on exposing an inbound endpoint over HTTP and didn't look at using outbound endpoints. Take the following modified Hello World application:</p> <script src="https://gist.github.com/ryandcarter/5082852.js?file=helloworld-outbound.xml"></script> <p>Feeling a bit european, this modified app simply contacts an external HTTP API to request "Hello World" in Italian. Here, the http:outbound-endpoint shouldn't need to bind to any internal port as it's not necessary for client TCP connections. However, when running the application you will still get: Permission denied (java.net.BindException). Under the hood, Mule uses the Apache commons-httpclient3 library for client connections which in turn uses uses it's DefaultSocketFactory class to create java.net.Socket objects. The java.net.Socket class has several different constructors, and commons-httpclient by default will call: </p><p><i>public Socket(String host, int port, InetAddress localAddr, int localPort) throws IOException...</i></p><p>Here, for the "localAddr" argument, null is passed. When null is passed for the "localAddr" argument, the java.net.Socket will use InetAddress.anyLocalAddress(); This will perform a bind on the localAddr/port which is not necessary for client TCP connections, although under most circumstances is harmless. Except on OpenShift where this is specifically locked down and results in the java.net.BindException being thrown.</p> <p>This is rectified in later versions of the library which are now refactored into the Apache HttpComponents library and the HttpClient Inerfaces have changed signigicantly resulting in a non-trivial upgrade path. There is a solution however, with thanks to mikebennettjackbe - <a href="https://www.openshift.com/forums/openshift/commons-httpclient-permission-denied">https://www.openshift.com/forums/openshift/commons-httpclient-permission-denied</a> to create a custom SocketFactory to override the creation of the Socket and not bind on any local address: <script src="https://gist.github.com/ryandcarter/5082852.js?file=OSProtocolSocketFactory.java"></script> <p>To make commons-httpclient use the new OSProtocolSocketFactory instead of its own, we need to regiser it when he app starts up. One approach to this, is we can implement the MuleNotificationListener interface: </p> <script src="https://gist.github.com/ryandcarter/5082852.js?file=SocketFactoryOverrider.java"></script> <p>This class allows us to check when the Mule context is initialised and register the new Socket factory for the http and/or the https protocols. After creating the above class, you just need to define it as a bean within your Mule config, like so:</p> <script src="https://gist.github.com/ryandcarter/5082852.js?file=hello-world-outbound-override.xml"></script> <p>And that's it. You should now be able to use http outbound endpoints and use connectors that rely on the Apache commons-httpclient3 library such as the Twitter Cloud Connector. There are more than likely other transports or connectors that have issues around this area so feel free to comment or raise an issue or pull request on Github. Full project can be found here: <a href="https://github.com/ryandcarter/mule-diy-cartridge">https://github.com/ryandcarter/mule-diy-cartridge</a></p>Ryan Carterhttp://www.blogger.com/profile/12683154470348126758noreply@blogger.com1tag:blogger.com,1999:blog-6568898918145371542.post-54851343830863286712013-03-04T08:13:00.001-08:002013-03-05T14:42:20.321-08:00Natively Running Mule on OpenShift<p>In this article I'll show how you can run Mule natively on OpenShift wihout using a Servlet container and show you how I got over a few implementation hurdles.</p> <p>If you are familiar with Mule you know it gives you many deployment options including both standalone deployment or embedding itself within a Java application or Webapp. The recommended approach is to run Mule ESB standalone from the command prompt, as a service or daemon, or from a script. This is the simplest architecture, so it reduces the number of points where errors can occur. It's typically best for performance as well, since it reduces the number of layers and eliminates the inherent performance impact of an application server on the overall solution. With Mule 3.x, you can also now run multiple applications side by side in a Mule instance using the new deployment model can support live deployment and hot redeployment of applications. Lastly, standalone mode has full support for the Mule High Availability module and the Mule management console.</p> <p>OpenShift gives you many choices for developing and deploying applications in the cloud. You can pick among PHP, Ruby, Perl, Python, Node.js or Java. As Mule is Java based, we are pretty much covered. OpenShift provides an end to end Java application stack including: Java EE6, CDI/WeldSpring and Spring. You can choose between multiple application server's for Webapps including JBoss AS7, JBoss EAP6, Tomcat, and GlassFish. But if you want to run Mule natively in standalone mode for the aforementioned benefits, you will need to create a "DIY" cartridge/application.</p> <p>A "DIY" application is just a barebones app, with no server preloaded, ready to be tailored to your needs. With this app type, OpenShift is begining to blur the line between an IaaS and a PaaS, providing you with a controlled and scalable environment, and at the same time giving you the freedom to implement the technology that best suits your needs.</p> <h3>Getting Started</h3> <p>Before attempting to create a DIY application on OpenShift, you should familiarize yourself with the technology you are about to use. You should have a clear understanding of the steps needed to set it all up on your workstation and then reproduce it on OpenShift.</p> <p>For a Mule application we won't need JBoss, or any application sever, not any servlet container at all. We just have to install Mule and start it up.</p> <p>Doing this on your own workstation is as easy as downloading Mule, unzipping it, and then running: </p> <script src="https://gist.github.com/ryandcarter/5082852.js?file=start+mule"></script> <p>And to stop Mule:</p> <script src="https://gist.github.com/ryandcarter/5082852.js?file=stop+mule"></script> Now we'll have to do the same on our server at OpenShift. First, let's create a new application named "mule": <script src="https://gist.github.com/ryandcarter/5082852.js?file=createapp.bash"></script> <p>Now let's see what we created. Running the following script:</p> <script src="https://gist.github.com/ryandcarter/5082852.js?file=rhc-show-app"></script> <p>Should output similar to he following:</p><script src="https://gist.github.com/ryandcarter/5082852.js?file=app+details"></script> <p>You can browse to <i>http://mule-yourdomain.rhcloud.com/</i> to see the default index page running. It's just the same static page you can find at raw/index.html</p> <p>Now let's see what we have in our repo:</p> <script src="https://gist.github.com/ryandcarter/5082852.js?file=show-repo"></script> <p>It's a pretty barebone app, but there's a folder that's quite interesting for us - <i>.openshift/action_hooks</i>:</p> <script src="https://gist.github.com/ryandcarter/5082852.js?file=show-acion-hooks"></script> <p>These are the scripts that OpenShift uses for building, deploying, starting and stopping our app. These scripts are executed on the remote OpenShift server. These are the scripts we will need to ammend to download Mule and perform any configuration as well as starting and stopping our Mule Server. Let's take a look at a simplified version of the script that we used to install Mule.</p> <h3>Installing Mule</h3><b>.openshift/action_hooks/pre_build</b><p>The pre_build script is used for downloading the required Mule installation and unzipping it.</p> <script src="https://gist.github.com/ryandcarter/5082852.js?file=action_hooks-pre_build-simple"></script> <b>.openshift/action_hooks/start</b><p>Then to start the Mule server:</p> <script src="https://gist.github.com/ryandcarter/5082852.js?file=action_hooks-start"></script> <b>.openshift/action_hooks/stop</b><p>And to stop the Mule server:</p> <script src="https://gist.github.com/ryandcarter/5082852.js?file=action_hooks-stop"></script> <h3>Upgrading the Java Service Wrapper</h3> <p>When you run the mule command, it launches the mule.bat or mule.sh script in your MULE_HOME/bin directory. These scripts invoke the Java Service Wrapper. The Java Service Wrapper from Tanuki Software is s fancy, little tool which helps with managing your application and JVM it is running in. By default it uses sockets to communicate back and forth with the JVM. But OpenShift is very restrcitive on what IP's and ports you are allowed to listen on.</p> <p>By default the current Mule 3.3.1 release uses version 3.5.7 of the Java Service Wrapper. If you try running the default Mule instalation on OpenShift, you will get the following error:</p> <pre>"unable to bind listener to any port in the range 32000-32999. (Permission denied)"</pre> <p>The Java Service Wrapper is controlled by a wrapper.conf file that can be found in you MULE_HOME/conf directory and has a host of configuration of options, including setting the rang eof ports that the wrapper can listen on. Ports aside, OpenShift only allows applications to bind on a specific IP address via the environment variable OPENSHIFT_INTERNAL_IP. Unfortunately there is no configuration option to override this IP address. Game Over!</p> <p>Extra Life! In a later version of the wrapper, there is a new configuration option: <b>wrapper.backend.type=PIPE</b> to allow you to avoid using sockets and use pipes instead to get around this problem.</p> <p>To upgrade the wrapper we simply download the later wrapper libraries and replace them within the MULE_HOME/lib directory.</p> <b>.openshift/action_hooks/pre_build</b><script src="https://gist.github.com/ryandcarter/5082852.js?file=action_hooks-pre_build-wrapper"></script> <p>To update the wrapper.conf file with the new configuration. We take a copy of the original wrapper.conf file, ammended to contain the wrapper.backend.type=PIPE option and includ it within our git repo so that we can replace the original when building the instalation.</p> <h3>.openshift/action_hooks/pre_build</h3><script src="https://gist.github.com/ryandcarter/5082852.js?file=action_hooks-pre_build-wrapper-conf"></script> <h3>Deploying a Mule application</h3><p>Deploying the application is as simple as copying a Mule application archive to the required <i>apps</i>directory:</p><h3>.openshift/action_hooks/deploy</h3><script src="https://gist.github.com/ryandcarter/5082852.js?file=action_hooks-deploy"></script> <p>Where helloworld.zip is a simple Mule applicaion exposed over HTTP that returns "Hello World".</p> <script src="https://gist.github.com/ryandcarter/5082852.js?file=helloworld.xml"></script> <h3>HTTP Binding</h3><p>The only thing to take note of here is that we are using the ${OPENSHIFT_INTERNAL_IP} environment variable. This is the suggested IP address for creating socket connections on localhost. Typical values like "localhost", "127.0.0.1" and "0.0.0.0" are all locked down. </p> However, if you try using this environment variable as your host you will get an error similar to the following: </p><pre>Permission denied (java.net.BindException) java.net.PlainSocketImpl:-2 (null) 2. Failed to bind to uri "http://127.8.109.1:8080"</pre> <p>As you can see; the internal IP resolves fine and we are using 8080 which is the suggested port for HTTP connections, but still no dice. <h3>Hacking the TCP transport</h3><p>After digging through the source, there is a slight issue with Mules' TCP transport.</p><script src="https://gist.github.com/ryandcarter/5082852.js?file=TcpServerSocketFactory.java"></script> <p>Here, the internal IP is a loopback address, so Mule forces it down the path of creating a Socket that listens on all interfaces for that port. Fortunately there is already af fix in the upcoming 3.4 release - <a href="http://mule.1045714.n5.nabble.com/mule-scm-mule-25194-branches-mule-3-x-transports-tcp-src-MULE-6584-HTTP-TCP-bound-to-127-0-0-1-listes-td5716551.html">MULE-6584: HTTP/ TCP bound to 127.0.0.1 listens on all interfaces</a>. </p> <p>Unfortunately, it's only upcoming at the moment. So instead I have ammended the source of this transport myself for the same functionality and included the resulting jar as part of my diy project to replace the orignal transport jar.</p> <b>.openshift/action_hooks/pre_build</b><script src="https://gist.github.com/ryandcarter/5082852.js?file=action_hooks-pre_build-tcp"></script> <h3>And that's it!</h3><p> If you now take a look at your app at: <i>http://mule-yourdomain.rhcloud.com/</i> you should now see "Hello World"! The full diy project for this with instructions can be found on GitHub: <a href="https://github.com/ryandcarter/mule-diy-cartridge">https://github.com/ryandcarter/mule-diy-cartridge</a></p> Ryan Carterhttp://www.blogger.com/profile/12683154470348126758noreply@blogger.com1tag:blogger.com,1999:blog-6568898918145371542.post-31169041538956487952013-02-03T11:47:00.000-08:002013-02-12T02:18:47.727-08:00Cross-Origin Resource Sharing with Mule, AJAX and JavaScript<h3>The Same-Origin Policy</h3><p>The Same-Origin policy is a security policy enforced on client-side web apps to prevent interactions between resources from different origins. While useful for preventing malicious behaviour such as XSS(Cross Site Scripting) attacks, this security measure also prevents useful and legitimate interactions between known origins. </p><p>For example, your new awesome JavaScript mashup hosted at http://myawesomeapp.com might want to use a REST API hosted at myawesomeapi.cloudhub.io. However, because these are two different origins from the perspective of the browser, the browser won't allow a script from myawesomeapp.com to fetch resources from myawesomeapi.cloudhub.io because the resource being fetched is from a different origin.</p> <h3>Cross-Origin Resource Sharing</h3><p>Fortunately, there is a solution via Cross-Origin Resource Sharing(CORS). The CORS spec was developed by the World Wide Web Consortium (W3C) to support this very case. It's a working draft but is already supported by the majority of web browsers, probably including the very browser you are using to view this page. The full specification can be found at: <a href="http://www.w3.org/TR/access-control/">http://www.w3.org/TR/access-control/</a> and supported browsers can be found here: <a href="http://caniuse.com/cors">http://caniuse.com/cors</a>.</p> <h3>How CORS works</h3><p>CORS works via a set of HTTP headers in the request from the client app and the response from the requested resource. In it's simplest form; the requesting application specifies a <b>Origin</b> header in the request which describes the origin of the request and the requested resource will reply intern with an <b>Access-Contol-Allow-Origin</b> header indicating specific origins that are allowed to access a particular resource.</p><b>Request headers:</b> <script src="http://gist.github.com/4702962.js"></script> <b>Response headers:</b><script src="http://gist.github.com/4703310.js"></script> <p>There are more complicated scenarios that require additional HTTP headers when using non-simple HTTP headers. More information on this can be found here: <a href="https://developer.mozilla.org/en/docs/HTTP_access_control#Access-Control-Allow-Methods">https://developer.mozilla.org/en/docs/HTTP_access_control#Access-Control-Allow-Methods. For the purposes of this post we will just be using simple headers.</a></p> <h3>Using CORS with the Mule HTTP transport</h3><p>To demonstrate CORS in action, I'll show a simple JavsScript client app using JQuery to access a simple HTTP service in Mule.</p><b>Simple JQuery Client</b><script src="http://gist.github.com/4703123.js"></script> <h4>Simple HTTP Mule Flow</h4><script src="http://gist.github.com/4703069.js"></script> <p>This is just a simple JQuery client and a simple HTTP Mule flow returning some plain text: "Hello World". The most important part here is the <b>set-property</b> element. Here we are setting the HTTP header to be returned in the response. Simple right? We have just set the value to "*" indicating that any origin is allowed. This can be configured as needed to include specific origins if you so desire. <h4>Using CORS with the Mule AJAX transport</h4><p>On top of the HTTP transport in Mule, there is also a specific AJAX transport. The Mule AJAX transport allows Mule events to be sent and received asynchronously to and from the web browser.</p> <p>You might think that you would be able to se this property the same way. Unfortunately, no. Under the hood; the AJAX transport uses Jetty and the CometD libraries to provide the long-polling functionality and currently do not propagate HTTP headers set in Mule and instead set their own. </p> <p>Never fear, there is a solution. It's a little more long winded, but still simple none the less. The solution relies on Jetty's configuration, which is used by the AJAX transport when running in embedded mode. This configuration can be overrided within your Mule application by provided a custom Jetty XML configuration file and creating custom Handler to add new HTTP headers. </p> <b>Simple JQuery CometD client</b><p>To start let's amend the original client application to use CometD to subscribe to a channel in Mule. </p> <script src="http://gist.github.com/4699602.js"></script> <h4>Mule AJAX Flow</h4> <p>The Mule flow just polls every ten seconds and publishes a message to an AJAX outbound endpoint. </p> <script src="http://gist.github.com/4699552.js"></script> <p>In addition to the standard AJAX connector configuration, we are injecting a reference to a custom jetty configuration file to register our CORS handler. </p> <h4>Jetty Configuration</h4><script src="http://gist.github.com/4699594.js"></script> <p>This is just a simple jetty configuration file that we referenced in the previous Mule configuration to register our new custom Handler. The most important part here is the class reference that will be our new Handler to add the required headers: <b> org.oreilly.mulecloudconnect.CORSHandler</b></p> <b>Custom CORS Handler</b><script src="http://gist.github.com/4699538.js"></script> <p>And finally the last part to our CORS puzzle is the custom Handler itself. This class is an extension of the org.mortbay.jetty.handler.AbstractHandler class that gives us access to the Servlet request and response. In this example we are simply adding the <b>Access-Control-Allow-Origin</b> header to the HttpServletResponse. But again, you can customize this to add specific origins and so on.</p> <p>And that's it. Happy mashing!</p>Ryan Carterhttp://www.blogger.com/profile/12683154470348126758noreply@blogger.com13tag:blogger.com,1999:blog-6568898918145371542.post-47276853844719091032013-02-01T11:37:00.000-08:002013-02-04T01:54:12.556-08:00Getting Started with Mule Cloud Connect: Accelerating Integration with SaaS, Social Media, and Open APIs - Sample Chapters <div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-e58UdnVZyyA/UQwYSwl7xvI/AAAAAAAAAAQ/HjH7sATVWXg/s1600/chapter01-02-front-231x300.png" imageanchor="1" style="clear:left; float:left;margin-right:1em; margin-bottom:1em"><img border="0" height="300" width="231" src="http://1.bp.blogspot.com/-e58UdnVZyyA/UQwYSwl7xvI/AAAAAAAAAAQ/HjH7sATVWXg/s320/chapter01-02-front-231x300.png" /></a> </div><div><br /><h3>Print Edition Now Available!</h3><p>With the number of open APIs reaching over 13,000 this year according to APIhub, 2013 will all be about how developers orchestrate APIs to create applications. Mule Cloud Connect is here to help. For those looking to get started with Mule and Mule Cloud Connect or even just working with APIs, my latest O'Reilly book will get you up and running: <a href="http://oreil.ly/mule-cloud">http://oreil.ly/mule-cloud</a>. If you're not already convinced, here are the first 2 chapters to get you started <a href="http://blogs.mulesoft.org/wp-content/uploads/2012/12/chapter01-02.pdf">http://blogs.mulesoft.org/wp-content/uploads/2012/12/chapter01-02.pdf</a>.</p></div>Ryan Carterhttp://www.blogger.com/profile/12683154470348126758noreply@blogger.com0tag:blogger.com,1999:blog-6568898918145371542.post-76278946671729007392013-02-01T10:53:00.002-08:002013-02-12T02:20:21.819-08:00Local WebHooks with Mule Cloud Connect and LocalTunnel v2<p>When using an external API for WebHooks or Callbacks as discussed in Chapters 3 and 5 of Getting Started with Mule Cloud Connect; The API provider running somewhere out there on the web needs to callback your application that is happily running in isolation on your local machine. For an API provider to callback your application, the application must be accessible over the web. Sure, you could upload and test your application on a public facing server, but you may find it quicker and easier to work on your local development machine and these are typically behind firewalls, NAT, or otherwise not able to provide a public URL. You need a way to make your local application available over the web.</p> <p>There are a few good services and tools out there to help with this. Examples include ProxyLocal, and Forward.io. Alternatively, you can set up your own reverse SSH Tunnel if you already have a remote system to forward your requests, but this is cumbersome to say the least. I find Localtunnel to be an excellent fit for this need and localtunnel have just recently released v2 of its service with a host of new features and enhancements. More information can be found here: <a href="http://progrium.com/blog/2012/12/25/localtunnel-v2-available-in-beta/">http://progrium.com/blog/2012/12/25/localtunnel-v2-available-in-beta/</a></p> <h3>Installing Localtunnel </h3> <p>Those familiar with version 1 of the service will know that the v1 Localtunnel client was written in Ruby and required Rubygems to install it. The v2 client is now written in Python and can instead be installed via easy_install or pip. </p> <p>If instead you're interested in using Localtunnel v1, then I have wrote a previous blog post on the subject here: <a href="http://blogs.mulesoft.org/connector-callback-testing-local/">http://blogs.mulesoft.org/connector-callback-testing-local/</a></p><p>To get started, you will first need to check that you have Python installed. Localtunnel requires Python 2.6 or later. Most systems come with Python installed as standard, but if not you can check via the following command: </p> <pre class="brush: csharp"><br />$ python -version<br /></pre><p>More info on installing Python can be found here: <a href="http://wiki.python.org/moin/BeginnersGuide/Download">http://wiki.python.org/moin/BeginnersGuide/Download</a></p><p>Once complete, you will need easy_install to install the Localtunnel client.If you don't have easy_install after you install Python, you can install it with this bootstrap script: </p> <pre><br />$ curl http://peak.telecommunity.com/dist/ez_setup.py | python<br /></pre><p>Once complete, you can install the Localtunnel client using the following command: </p><pre class="brush: sharp"><br />$ easy_install localtunnel<br /></pre> <h3>First run with LocalTunnel</h3> <p>Once installed, creating a tunnel is as simple as running the following command: </p><pre class="brush: sharp"><br />$ localtunnel-beta 8082<br /></pre> <p>The parameter after the command: "8000" is the local port we want Localtunnel to forward to. So whatever port your app is running on should replace this value. Each time you run the command you should get output similar to the following: </p> <pre class="brush: sharp"><br />Port 8082 is now accessible from http://fb0322605126.v2.localtunnel.com ...<br /></pre> <b>Note:</b><i> As v2 is still in beta; the command local-tunnel-beta will eventually be installed as just localtunnel. This lets you keep the v1 just in case anything goes wrong with v2 during the beta.</i> <h3>Configuring the Connector</h3><p>Now onto Mule! To demonstrate I will use the Twilio Cloud Connector example from Chapter 5. Twilio has an awesome WebHook implementation with great debugging tools. Twilio uses callbacks to tell you about the status of your requests; When you use Twilio to a place a phone call or send an SMS the Twilio API allows you to send a URL where you'll receive information about the phone call once it ends or the status of the outbound SMS message after it's processed.</p><script src="http://gist.github.com/4693295.js"></script><p>This example uses the Twilio Cloud Connector to send a simple SMS message. The most important thing to note is that the "status-callback-flow-ref" attribute. All connector operations that support callback's will have an optional attribute ending in "-flow-ref". In this case : "status-callback-flow-ref". As the name suggests, this attribute should reference a flow. This value must be a valid flow id from within your configuration. It is this flow that will be used to listen for the callback. </p> <p>Notice that the flow has no inbound endpoint? This is where the magic happens; when Twilio process the SMS message it will send a callback automatically to that flow without you having to define an inbound endpoint. The connector automatically generates an inbound endpoint and sends the auto generated URL to Twilio for you. </p><h3>Customizing the Callback</h3><p>The URL generated for the callback URL is built using 'localhost' as the host, the 'http.port' environment variable or 'localPort' value as the port and the path of the URL is typically just a random generated string or static value. So if I run this locally it would send Twilio my non public address, something like: http://localhost:80/...vv3v3er342fvvn. Each connector that accepts HTTP callbacks will provide you with an optional http-callback-config child element to override these settings. These settings can be set at the connector's config level as follows: </p> <script src="http://gist.github.com/4693391.js"></script> <p>Here we have amended the previous example to add the additonal http-callback-config configuration. The configuration takes three additional arguments: domain, localPort and remotePort. These settings will be used to constuct the URL that is passed to the external system. The URL will be the same as the default generated URL of the HTTP inbound-endpoint except that the host is replaced by the 'domain' setting (or its default value) and the port is replaced by the 'remotePort' setting (or its default value). </p><p>In this case we have used the domain from the URL that Localtunnel generated for us earlier: fb0322605126.v2.localtunnel.com and set the localPort to 8082 as we run the Localtunnel command using port 8082 and the remotePort to 80 as the localtunnel server just runs on port 80. </p><p>And that's it! If you run this configuration you should start seeing your callback being printed to the console. The same goes for any OAuth connectors too. If your using any OAuth connectors built using the DevKit OAuth modules, you can configure the OAuth callback in a similar fashion. </p> <p>A full Mule/Twilio WebHook project can be found here: <a href="https://github.com/ryandcarter/GettingStarted-MuleCloudConnect-OReilly/tree/master/chapter05/twilio-webhooks">https://github.com/ryandcarter/GettingStarted-MuleCloudConnect-OReilly/tree/master/chapter05/twilio-webhooks</a> Ryan Carterhttp://www.blogger.com/profile/12683154470348126758noreply@blogger.com0