Friday, May 30, 2014

API Gateway How to condition a result based on some JSON data


problem:

We need to develop the policy routing flow based on the incoming message What is the way to do the content based routing and condition based routing in OAG. 

For example I have two (may be more) types of JSON message response from a service . I want to set the message based on the JSON response from service . What is the way to develop in this in OAG. . 

Here is the two JOSN response from service that OAG is calling . 

JSOA Type-1 
========================================== 
{"soapenv:Envelope":{"@xmlns:soapenv":"http://schemas.xmlsoap.org/soap/envelope/","env:Header":{"@xmlns:env":"http://schemas.xmlsoap.org/soap/envelope/","wsse:Security":{"@xmlns:wsse":"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"}},"env:Body":{"@xmlns:env":"http://schemas.xmlsoap.org/soap/envelope/","mes:createUserAccountResponse":{"@xmlns:mes":"http://celgene.com/security/messages_v2","mes:createUserAccountOutput":{"mes:status":"SUCCESS"}}}}} 

JSON Type-2 
========================================== 
{"soapenv:Envelope": {"@xmlns:soapenv": "http://schemas.xmlsoap.org/soap/envelope/", "env:Header": {"@xmlns:env": "http://schemas.xmlsoap.org/soap/envelope/"}, "env:Body": {"@xmlns:env": "http://schemas.xmlsoap.org/soap/envelope/", "env:Fault": {"@xmlns:xs": "http://www.w3.org/2001/XMLSchema", "@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance", "faultcode": "soapenv:Server", "faultstring": null, "detail": {"java:UserAlreadyExistsException": {"@xmlns:java": "http://celgene.com/security/exceptions_v2", "java:message": "UserAlreadyExists" }}}}} 


For JSON Msg 1 I want to set the message 
========================================== 
{"Message": "User Created successfully"} 

For JSON Msg 2 I want to set the message 
========================================== 
{"Message": "UserAlreadyExists"} 
SOLUTION:


We can implement this using the Scripting Language filter as follows: 

function invoke(msg) { 

// get the body as JsonNode 
var node = com.vordel.mime.JSONBody.getJSON(msg); 

// get the root 
var root = node.path("soapenv:Envelope"); 

// get the value of reference from body 
var envBody = root.path("env:Body"); 

// get the value of reference from Fault 
var envFault = envBody.path("env:Fault"); 

if (envFault .size() != 0) 
// Follow the line for the message with error 
// get the value of reference from detail 
var detail = envFault.path("detail"); 

// get the value of reference from UserAlreadyExistsException 
var javaUser = detail.path("java:UserAlreadyExistsException"); 

// get the value of reference from message 
var javaMessage = javaUser.path("java:message"); 

// get the text value 
var message = javaMessage.getTextValue(); 

// put the data in the result 
msg.put("message", "UserAlreadyExists"); 
return true; 

// get the value of reference from createUserAccountResponse 
var mesCreateUserAccountResponse = envBody.path("mes:createUserAccountResponse"); 
if (mesCreateUserAccountResponse .size() !=0) 
// Follow the line for the Success 


// get the value of reference from mesCreateUserAccountResponse 
var mesCreateUserAccountOutput = mesCreateUserAccountResponse.path("mes:createUserAccountOutput"); 

// get the value of reference from mesCreateUserAccountOutput 
var mesStatus = mesCreateUserAccountOutput.path("mes:status"); 

// get the text value 
var message = mesStatus.getTextValue(); 

// put the data in the result 
msg.put("message", "User Created successfully"); 

return true; 




Friday, May 16, 2014

How to convert file format from ASCII to UTF


How to convert file format from ASCII to UTF

#1 : Check the file format
$file input.txt

#2
use the iconv command
iconv -f   <<Source Format >>    -t      <<Target Format>>   < input.txt   > output.txt

iconv -f ASCII  -t UTF8   < input.txt   > output.txt

#3 #1 : Check the file format
$file output.txt

Tuesday, May 13, 2014

Error -ora-28267: invalid namespace -ADF With Jdeveloper


There was a requirement to validated the Local Entity Attribute value against the Remote Database. For this we set-up the DB link. Local DB is 11g and remote is 10g.
During the query validation in JDEV we go the issue."ora-28267: invalid namespace" .

To Fix this in JDV.

Replaced the jar file  (ojdbc6dms.jar) with ojdbc6.jar in below loaction in Jdeveloper..

"C:\Oracle\Middleware11.1.1.7.0\oracle_common\modules\oracle.jdbc_11.1.1\"

You can find ojdbc6.jar in  C:\Oracle\Middleware11.1.1.7.0\wlserver_10.3\server\lib

C:\Oracle\Middleware11.1.1.7.0\=Middleware Home

Thursday, January 23, 2014

WebLogic Server : Node Manager

Issue Reported : On Admin server "Servers" link was not loading the servers page. I tail the nohup.out but logs are not flowing . All other links were working fine  except "Servers" link.
Did a thread dump found SSL was not established.

[ACTIVE] ExecuteThread: '9' for queue: 'weblogic.kernel.Default (self-tuning)'" daemon prio=10 tid=0x00007f6d34011000 nid=0x1cfc runnable [0x00007f6d268e4000]
   java.lang.Thread.State: RUNNABLE
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.read(SocketInputStream.java:129)
        at weblogic.utils.io.ChunkedInputStream.read(ChunkedInputStream.java:159)
        at java.io.InputStream.read(InputStream.java:85)
        at com.certicom.tls.record.ReadHandler.readFragment(Unknown Source)
        at com.certicom.tls.record.ReadHandler.readRecord(Unknown Source)
        at com.certicom.tls.record.ReadHandler.readUntilHandshakeComplete(Unknown Source)
        at com.certicom.tls.interfaceimpl.TLSConnectionImpl.completeHandshake(Unknown Source)
        - locked <0x00007f6d9ad86ac8> (a com.certicom.tls.interfaceimpl.TLSConnectionImpl)
        at com.certicom.tls.record.WriteHandler.write(Unknown Source)
        at com.certicom.io.OutputSSLIOStreamWrapper.write(Unknown Source)
        at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
        at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
        at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276)
        at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122)
        - locked <0x00007f6d9ad86c20> (a java.io.OutputStreamWriter)
        at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212)
        at java.io.BufferedWriter.flush(BufferedWriter.java:236)
        - locked <0x00007f6d9ad86c20> (a java.io.OutputStreamWriter)
        at weblogic.nodemanager.common.DataFormat.writeCommand(DataFormat.java:247)
        at weblogic.nodemanager.client.NMServerClient.sendCmd(NMServerClient.java:318)
        at weblogic.nodemanager.client.NMServerClient.sendHello(NMServerClient.java:128)
        at weblogic.nodemanager.client.NMServerClient.connect(NMServerClient.java:239)
        at weblogic.nodemanager.client.NMServerClient.checkConnected(NMServerClient.java:200)
        at weblogic.nodemanager.client.NMServerClient.getState(NMServerClient.java:37)
        - locked <0x00007f6d9ad86cd8> (a weblogic.nodemanager.client.SSLClient)
        at weblogic.nodemanager.mbean.NodeManagerRuntime.getState(NodeManagerRuntime.java:438)
        at weblogic.nodemanager.mbean.NodeManagerRuntime.getState(NodeManagerRuntime.java:457)
        at weblogic.server.ServerLifeCycleRuntime.getStateNodeManager(ServerLifeCycleRuntime.java:752)
        at weblogic.server.ServerLifeCycleRuntime.getState(ServerLifeCycleRuntime.java:584)

Wednesday, January 8, 2014

OAG - Oracle API Gateway- How to turn off Host name verification


Issue :
While consuming the HTTPS services sometime the certificate presented by the Remote Host has  identity  does not match with the host name or IP given in the service URL. In this case OAG will throw the below error

host name 'services.harish.com' in request does not match server's certificate subject { subject: /C=US/ST=NJ/L=Hillsborough/O=SOA/OU=IT/CN=Harish }.
ERROR  1/8/14 16:56:52.601                 [SSL alert write 0x22a, 0x1131]: bad certificate [fatal] { subject: /C=US/ST=NJ/L=Hillsborough/O=SOA/OU=IT/CN=Harish }.
ERROR  1/8/14 16:56:52.601                 [SSL_connect, 0x1131]: error - certificate rejected { subject:/C=US/ST=NJ/L=Hillsborough/O=SOA/OU=IT/CN=Harish }.
ERROR  1/8/14 16:56:52.601                 [SSL_connect, 0x1131]: error - certificate rejected.
ERROR  1/8/14 16:56:52.601                 transient failure connecting to remote: SSL protocol error
ERROR  1/8/14 16:56:52.601         The message [Id-3faba97a52cdc9a40f000000] logged Failure at 01.08.2014 16:56:52,601 with log description: Failed to route request to endpoint.
ERROR  1/8/14 16:56:52.602         Filter that caused failure: Connect to URL
ERROR  1/8/14 16:56:52.602         Policy '/harish/try.asmx' {


 Solution :

Navigate to " Remote Host Settings" Dialog box  (Remote Host name ->Edit)
Unchecked the check box - for   "Verify Server's Certificate matches requested hostname" . This is selected by default.


This is the screenshot for OAG-11.1.2.1.0's policy studio.


Sunday, January 5, 2014

Data Source Configuration For ADF application

I developed the ADF application and this was working fine  . Then I decided to point the application to other database environment and this i was trying to update the Data source configuration that get craeted on wEBlOGIC SERVER by jdeveloper. But this was throwing error.

JDBCDriverParams/Properties/Properties[user]) due to 'Unable to remove bean since not defined in plan'. The remover should first check to see if the bean is removable in the deployment plan prior to removing it
Steps to resolve the issue:

1) Right Click to Application Module in Jdev->Configurations..>Select the ModuleLocal->Select the property "JDBCDataSource" and click Edit. -> In the "Edit Business Configuration Components" Diaglog box select the Connection Typer JDBC DataSource and enter the JNDI Data source name..
Please note this Data source needs to be created before you deploy your application.
2) Now deploy you application from Jdeveloper and your application will connect via JNDI datsource you configure.
The data source modue that is bundled will have the JDDI data source but they will be in shutdown state.

3) Now you can edit your JNDI data source without any issue for other environmnet.




SOAP Version Mismatch between Consumer and Publisher


While consuming the SOAP service I got the below error . This took me couple of minutes to figure out so thought of sharing may be this can save some minutes .


Error 1:

 <?xml version="1.0" encoding="UTF-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap:Body>
<pnd:ConvertPNG2PDFResponse xmlns:pnd="http://mycompany.com/middleware/utility/conversion/pnd2pdf"><ser:ResponseHeader xmlns:ser="http://mycompany.com/middleware/schemas/servicemetadata_v1"><ser:StatusCode>1</ser:StatusCode><ser:Status>ERROR</ser:Status><ser:MessageCode>OSB-UNREG-ERR</ser:MessageCode><ser:Message>
This error is not registered in the system. Please Contact system administrator.BEA-382032-The message must be an instance of: {http://www.w3.org/2003/05/soap-envelope}Envelope
</ser:Message>
</ser:ResponseHeader>
</pnd:ConvertPNG2PDFResponse>
</soap:Body></soap:Envelope>

Error 2:

Response SOAP Message = <?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><soapenv:Fault><faultcode>soapenv:VersionMismatch</faultcode><faultstring>BEA-382032: The message must be an instance of: {http://schemas.xmlsoap.org/soap/envelope/}Envelope</faultstring><detail><con:fault xmlns:con="http://www.bea.com/wli/sb/context"><con:errorCode>BEA-382032</con:errorCode><con:reason>
The message must be an instance of: {http://schemas.xmlsoap.org/soap/envelope/}Envelope</con:reason><con:details><err:InvalidEnvelope xmlns:err="http://www.bea.com/wli/sb/errors"><err:localpart>Envelope</err:localpart><err:namespace>http://www.w3.org/2003/05/soap-envelope</err:namespace></err:InvalidEnvelope></con:details><con:location><con:path>request-pipeline</con:path></con:location></con:fault></detail></soapenv:Fault></soapenv:Body></soapenv:Envelope>

Solution : while creating the MessageFactory object please use the correct arguments based on the published service if this is SOAP 1.1 or 1.2

Please refer the below for more information
Open Declaration

A factory for creating SOAPMessage objects.
A SAAJ client can create a MessageFactory object using the method newInstance, as shown in the following lines of code.
       MessageFactory mf = MessageFactory.newInstance();
       MessageFactory mf12 = MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
 
All MessageFactory objects, regardless of how they are created, will produce SOAPMessage objects that have the following elements by default:
  • A SOAPPart object
  • A SOAPEnvelope object
  • A SOAPBody object
  • A SOAPHeader object
In some cases, specialized MessageFactory objects may be obtained that produce messages prepopulated with additional entries in the SOAPHeader object and the SOAPBody object. The content of a new SOAPMessage object depends on which of the two MessageFactory methods is used to create it.
  • createMessage()
    This is the method clients would normally use to create a request message.
  • createMessage(MimeHeaders, java.io.InputStream) -- message has content from the InputStream object and headers from the MimeHeaders object
    This method can be used internally by a service implementation to create a message that is a response to a request.  

JAVA Code To Consume the HTTPS SOAP Service - Certificate Based Client Authentication



JAVA Code To Consume the HTTPS SOAP Service - Certificate Based Client Authentication 



Step 1 : Create the keys for the client  and generate the certificate . This way you will have your identity .This way you will present your certificate to server and server will authenticate based on client certificate.  You must supply your certificate as server will have your certificate in its trust.
Step 2: Store the server certificate in trust keystore.  This way you will trust the server.

Step 3: Set the below arguments in client JVM 
-Djavax.net.debug=ssl
-Djavax.net.ssl.keyStoreType=JKS
-Djavax.net.ssl.keyStore=C:/identity/identity/laptopIdentity.jks
-Djavax.net.ssl.keyStorePassword=xxxxx
-Djavax.net.ssl.trustStoreType=jks
-Djavax.net.ssl.trustStore=C:/identity/identitytruststore.jks


Step 4 : customize the below java code as per your WSDL.

WSDL URL : //https://myhost/ServiceProxy?wsdl


package com.test;

import java.net.URL;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;
import javax.xml.soap.*;
import javax.xml.transform.*;
import javax.xml.transform.stream.*;

public class SOAPJavaClient {

/**
* Starting function to test the soap service
*/
public static void main(String args[]) {
              // Service URL ,Remove "?wsdl" from the WSDL URL.
String https_url = "https://myhost/ServiceProxy";

URL url;

try {
// Create SOAP Connection
SOAPConnectionFactory soapConnectionFactory = SOAPConnectionFactory
.newInstance();
SOAPConnection soapConnection = soapConnectionFactory
.createConnection();

// Send SOAP Message to SOAP Server

url = new URL(https_url);
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
                      //Use below (2 lines) if Host name verification needs to turned off
MyHostnameVerifier HostVerifier = new MyHostnameVerifier();
con.setHostnameVerifier(HostVerifier);
con.connect();

SOAPMessage response = soapConnection.call(createRequest(),url);


// Print the  SOAP Response
printResponse (response );

soapConnection.close();
} catch (Exception e) {
System.err
.println("Error occurred while sending SOAP Request to Server");
e.printStackTrace();
}
}

private static SOAPMessage createRequest() throws Exception {
// SOAP 1.1 Services
MessageFactory messageFactory = MessageFactory.newInstance();
// For SOAP 1.2 services
// MessageFactory messageFactory =
// MessageFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);

SOAPMessage soapMessage = messageFactory.createMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();

// String serverURI = "myhost";

// SOAP Envelope
SOAPEnvelope envelope = soapPart.getEnvelope();

envelope.addNamespaceDeclaration("ns1",
"https://myhost/ServiceProxy");

SOAPBody soapBody = envelope.getBody();
SOAPElement soapBodyElem = soapBody.addChildElement(
"OperationRequest", "ns1");

SOAPElement soapBodyElem1 = soapBodyElem
.addChildElement("ID");

soapBodyElem1.addTextNode("1");

MimeHeaders headers = soapMessage.getMimeHeaders();
headers.addHeader("SOAPAction",
"http://myhost/Operation");

soapMessage.saveChanges();

/* Print the request message */
System.out.print("Request SOAP Message = ");
soapMessage.writeTo(System.out);
System.out.println();
return soapMessage;
}

/**
* Method used to print the SOAP Response
*/
private static void printResponse(SOAPMessage soapResponse)
throws Exception {
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
Source sourceContent = soapResponse.getSOAPPart().getContent();
System.out.print("\nResponse SOAP Message = ");
StreamResult result = new StreamResult(System.out);
transformer.transform(sourceContent, result);
}

}
//  This code is used when the server certificate 's CN is different than host name or IP.
class MyHostnameVerifier implements HostnameVerifier {
public boolean verify(String hostname, SSLSession session) {
if (hostname.equals("hostame or IP of the from WSDL"))
return true;
else
return false;
}
}


Let me know if you have any issue .