Enable Oracle JCS to access External REST API

Enable Oracle JCS to access External REST API

For a training I’m preparing I had to implement a POC on how to access an external REST API and to make it available in an ADF application running in the Oracle Java Could Service.

This task sounds pretty easy, nevertheless it’s best to see this working before starting a training which in the end will not work.

I decided to use Spotify public available REST API at https://api.spotify.com for this task. I started by creating a simple Fusion Web Application using JDev version 12.2.1.2.0. To this project I added a custom model Project which I later used to add the REST DataControl pointing to the Spotify track search API.

As this post isn’t about how to create such a project and use it in your normal ADF application, I spare the details here and write this up in another blog post.

Implementing a REST DataControl is pretty straight forward and the sample application was set up quickly. The first problem you might run into, even on the local development machine is this

null

error you get when you try to access the public API from inside the WebLogicServer. To make this error searchable for other users here is a part of the stack trace

javax.net.ssl.SSLKeyException: Hostname verification failed: HostnameVerifier=weblogic.security.utils.SSLWLSHostnameVerifier, hostname=api.spotify.com.
at weblogic.security.SSL.jsseadapter.JaSSLEngine.doPostHandshake(JaSSLEngine.java:686)
at weblogic.security.SSL.jsseadapter.JaSSLEngine.doAction(JaSSLEngine.java:757)
at weblogic.security.SSL.jsseadapter.JaSSLEngine.unwrap(JaSSLEngine.java:133)
at weblogic.socket.JSSEFilterImpl.unwrap(JSSEFilterImpl.java:644)
at weblogic.socket.JSSEFilterImpl.unwrapAndHandleResults(JSSEFilterImpl.java:541)
at weblogic.socket.JSSEFilterImpl.doHandshake(JSSEFilterImpl.java:99)
at weblogic.socket.JSSEFilterImpl.doHandshake(JSSEFilterImpl.java:78)
at weblogic.socket.JSSESocket.startHandshake(JSSESocket.java:240)
at weblogic.net.http.HttpsClient.New(HttpsClient.java:574)
at weblogic.net.http.HttpsClient.New(HttpsClient.java:545)
at weblogic.net.http.HttpsURLConnection.connect(HttpsURLConnection.java:236)
at weblogic.net.http.HttpURLConnection.getInputStream(HttpURLConnection.java:685)
at weblogic.net.http.SOAPHttpsURLConnection.getInputStream(SOAPHttpsURLConnection.java:41)
at weblogic.net.http.HttpURLConnection.getResponseCode(HttpURLConnection.java:1545)
...

This problem can easily sorted out by changing the ‘Hostname Verification’ to custom and to specify ‘weblogic.security.utils.SSLWLSWildcardHostnameVerifier’ as ‘Custom Hostname Verifier’. Here are the detailed steps:

  1. Go to the WebLogic admin console -> Environment -> Servers -> Server -> Configuration -> SSL
  2. Under advanced options , change “Hostname Verification” from “BEA Hostname Verifier” to “Custom Hostname Verifier”.
  3. Set “Custom Hostname Verifier” to weblogic.security.utils.SSLWLSWildcardHostnameVerifier
  4. Click “Save” and then “Activate Changes”
  5. Restart your server.

After this the sample application will run on the local development machine or an stand alone webLogic Server.

Now the fun part begins, making the application run in the Oracle JCS. Here I started with setting up a new Java Cloud Service with a WebLogic Server of version 12.2.1.2 and deployed my local running application to this new JCS.

The application did start OK, but when I came to the point where the application tried to call the external REST API all I got is: NOTHING

I only saw a spinning cursor, no error message on the UI regardless of my exception handler. It turned out, that I did not wait long enough for the error message to come up. The REST call timed out eventually providing more info in the servers log file

Exception in invoking HTTP method GET from Rest data control. Cause: javax.ws.rs.ProcessingException: java.net.ConnectException: Tried all: 3 addresses, but could not connect over HTTPS to server: api.spotify.com port: 443

It looks like the external REST call is not allowed. Here is the REST call

https://api.spotify.com/v1/search?q=sorry&type=track

If you write this into your browser you’ll get a JSON string in return, something like

{
 "tracks" : {
 "href" : "https://api.spotify.com/v1/search?query=sorry&type=track&offset=0&limit=20",
 "items" : [ {
 "album" : {
 "album_type" : "album",
 "artists" : [ {
 "external_urls" : {
 "spotify" : "https://open.spotify.com/artist/1uNFoZAHBGtllmz…

telling me that the problem is somewhere with the JCS. I ask for help in the OTN Java Cloud Service space and got an answer that there must be a rule missing. This is true to some point as I tried to access the REST API with curl from the JCS command shell

null

which did not work either. The interesting part is that you can do the same from the DBCS command shell and get the right answer.

I tried to add a rule to allow the access but looking at the possible source and destinations lists this did not work. Only

  • OTD — The Oracle Traffic Director load balancer VMs
  • WLS_ADMIN_SERVER — The WebLogic Server Administration Server VM
  • WLS_MANAGED_SERVER — The WebLogic Server Managed Server VMs

are allowed as destinations and my rule should allow the managed server (source) to access the PUBLIC_INTERNET or allow access to https protocol port 443.

After some more reading and testing I found a solution, however I’m not sure if this is the best way to handle this. Anyway, for others users who run into the same problem here it is:

First you have to create a ‘Security List’ Which you name e.g. outbound_wlsms_https_traffic which denies incoming packages and allows outgoing packages

null

Next a ‘Security Rule’ can be created like

null

with source set as the managed server and destination the new security list. After that the access to the external REST API works.

Advertisements

JDeveloper Versions vs. Weblogic Server Versions

UPDATE 21-Dec-2012: added info for JDev 11.1.2.x running on WLS 10.3.5 to match the Certification Matrix
UPDATE 29-Nov-2012: added note for new JDev 11.1.1.6.0 Build 6229 released Nov-2012
UPDATE 13-Jul-2013: added info for JDev 12c released 10-Jul-2013
UPDATE 26-Jun-2014: added info for JDev 12cR1 (12.1.3) released 26-Jun-2014

The last couple of days more people are trying to run ADF applications build with JDeveloper of version X on a Weblogic Server with a different ADF Runtime version Y installed.

To make it clear, this will not work!

You need to make sure that the ADF Runtime versions of  JDeveloper and Weblogic Server match. Next thing is that you can’t install the ADF Runtime on any Weblogic Server you like. The ADF Runtime will only work with a specific Weblogic Server. As each JDeveloper version comes with its own ADF Runtime version, there is a direct connection between JDeveloper and Weblogic Server.

To help you to use the right combination use the below table:

JDeveloper (ADF Runtime) Weblogic Server Info
11.1.1.2.0 10.3.2
11.1.1.3.0 10.3.3
11.1.1.4.0 10.3.4
11.1.1.5.0 10.3.5
11.1.1.6.0 10.3.5, 10.3.6 Integrated WLS is 10.3.5, stand alone WLS can be 10.3.5 or 10.3.6 (see Chris Muir on adf runtime 11.1.1.6.0)
Important Note: there are two releses of JDev 11.1.1.6.0 out. The first one release Feb 2012 (Build 6192.1) and the second one Nov 2012 (Build 6229). Both use the same ‘ADF Runtime Installation’ so there in no new ‘ADF Runtime’ installation available or needed. Read Release Notes for more information on this.
11.1.1.7.0 10.3.5, 10.3.6 Integrated WLS is 10.3.5, stand alone WLS can be 10.3.5 or 10.3.6 (see Chris Muir on adf runtime 11.1.1.6.0)
11.1.2.0.0 10.3.5 + Sherman patch Only available via MOS: patch  #12611176 and  patch #12556632; requires ADF 11.1.2.x patches onto Application Development Runtime 11.1.1.5.x
11.1.2.1.0 10.3.5 + Sherman patch UPDATE1 Only available via MOS: patch #12979653 and patch #12917525; requires ADF 11.1.2.x patches onto Application Development Runtime 11.1.1.5.x
11.1.2.2.0 10.3.5 + Sherman patch UPDATE2; 10.3.6 + Sherman patch UPDATE2 Only available via MOS: patch #13656274 and patch #13656372 (see Patch Numbers for ADF Runtime Libraries Update to 11.1.2.2.0 for more info); running on WLS10.3.5 requires ADF 11.1.2.x patches onto Application Development Runtime 11.1.1.6.x
11.1.2.3.0 10.3.5 + Sherman patch UPDATE3; 10.3.6 + Sherman patch UPDATE3 Only available via MOS: patch #14582286 (ADF) and patch #14582309 (WebCenter); running on WLS10.3.5 requires ADF 11.1.2.x patches onto Application Development Runtime 11.1.1.6.x
11.1.2.4.0 10.3.5 + Sherman patch UPDATE4; 10.3.6 + Sherman patch UPDATE4 Only available via MOS: patch #16546129 (ADF) and patch #16546157 (WebCenter); running on WLS10.3.5 requires ADF 11.1.2.x patches onto Application Development Runtime 11.1.1.6.x
12.1.2.0.0 12.1.2.0.0 WLS 10.3.5+ can be used if no ADF is used in the application!
Running a standalone WLS12.1.2.0.0 needs a Oracle DB 11.1.0.7+, Oracle DB 11.2.0.3+ or Oracle DB 12.1.0.1+
12.1.3.0.0 12.1.3.0.0 WLS 10.3.5+ can be used if no ADF is used in the application!
Running a standalone WLS12.1.3.0.0 needs a Oracle DB 11.1.0.7+, Oracle DB 11.2.0.3+ or Oracle DB 12.1.0.1+

There is no backward or forward compatibility!

You don’t need to try, I’ve tested most but not all combinations and run into trouble whenever I mixed versions.

For my tests I used used a small ADF application based on the HR schema.The UI consists of an af:query with a panelCollection for the result table and abounded task flow for editing a row in a popup.

The application was build on JDeveloper under Window 7, the resulting ear file was deployed (using the WLS console) on the Weblogic Server on a Linux box.

The ADF Runtime  installed on the WLS was downloaded from here. The WLS  installed on the Linux box was downloaded from here. I used the “Oracle WebLogic Server 11gR1 (10.3.5) + Coherence – Package Installer” and installed the WLS without  Coherence. After installing WLS the ADF Runtime installation was applied.