Thursday, October 25, 2012

importing OSB projects into Eclipse

Sometimes our OSB Eclipse projects get corrupted, or sometimes you need to create new workspace from existing source code (from project source code control).

Here are steps I use:

I'll assume your entire OSB source is under a folder call "c:/osb".

0. back up your osb folder (if you used it for an existing workspace), e.g. rename it osb.bak
1. create new folder "c:/osb"
2. check out your source files under "c:/osb", e.g. ("my config proj", "my proj1", "my proj2")
    or copy your backed project files if you backed them in step 0
3. fire up eclipse, switch to OSB pespective, and create a new workspace under "c:/osb"
4. select "file", "import", "general", then "existing projects into workspace"
5. pick your "c:/osb" folder, check and uncheck the projects you want
6. import them
7. it may whine about your .svn, or .vss files, you can ignore them, or you can google it up, i believe there is way to mask off those warnings in Eclipse preference, i just don't remember how
8. if you happen to see one of the projects showing error saying it doesn't have an associated OSB configuration project, just drag that project in Eclipse "project explorer" panel, and drop it into your OSB configuration project.

hope that takes care of everything.

Friday, October 19, 2012

PGP and SOA

My environment:
      SOA 11.1.1.6
      Java 1.6.x
Goal:
      sftp adapter to grab a PGP encrypted file, then decrypt the file in the SOA composite then process the data. You will be supplied with a PGP private key file (binary key ring, or ascii key), and pass phrase to decode the file.

My solution:
     use java embedding to decrypt PGP file. In essence, it's a Java solution.

Java part:

Here is how to do it in Java:
1. go to Bounce Castle to download the latest jars


Download
 bcpg-jdk15on-147.jar 
bcprov-jdk15on-147.jar 

2. online resource to use the package to encrypt/decrypt:


3. I added a simple main() to the above PGPFileProcessor class:

public static void main(String args[]) throws Exception
{
   PGPFileProcessor pgp = new PGPFileProcessor();

   //pgp.setAsciiArmored(true); // if you want dump ascii file
   // hard code for my test
   pgp.setInputFileName("c:/pgp/java/sample_file.txt");
   pgp.setOutputFileName("c:/pgp/java/sample_file.txt.pgp");
   pgp.setPublicKeyFileName("c:/pgp/java/mypgp-pub.key"); //can be either binary or text key
   pgp.encrypt();

// decrypt the same file
   pgp.setInputFileName("c:/pgp/java/sample_file.txt.pgp");
   pgp.setOutputFileName("c:/pgp/java/sample_file-decrypted.txt");
   pgp.setSecretKeyFileName("c:/pgp/java/mypgp-pri.key"); // can be either binary or text key
   pgp.setPassphrase("mypassword");
   pgp.decrypt();
}

3. set your class path to include the jars in step 1, and compile java files from step 2

4. if you get java exceptions like:
PGPKeyRingTest: exception: java.security.InvalidKeyException: Illegal key size

You may need to download

Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6


save the jars to “C:\java\jdk1.6.0_31\jre\lib\security”. Backup local_policy.jar, and US_export_policy.jar first!


5. package the compiled classes into a jar, let's call it mypgp.jar

Add Java to the composite:

1. copy  bcpg-jdk15on-147.jar, bcprov-jdk15on-147.jar and mypgp.jar (you just generated) to two locations (you need to figure out your own soa environment)
C:\Oracle\Middleware\Oracle_SOA1\soa\modules\oracle.soa.ext_11.1.1
and
C:\Oracle\Middleware\user_projects\domains\soa_domain\lib


For the first copied location, there is build.xml in that directory already, you need to run "ant" command in that directory. If you don't want to run "ant" command, you can also unjar your files into the "classes:" sub directory.
After you finish that, you need to bounce the entire SOA suite (including weblogic server).

2. code embedded java:
            <![CDATA[System.out.println("**********new pgp");      
pgp.test.com.PGPFileProcessor pgp = new pgp.test.com.PGPFileProcessor();      
      
System.out.println("*end *********new pgp");      
     
XMLElement srcElem = (XMLElement) getVariableData("inputVariable", "payload", "/client:myReqeust/client:srcFile");    
String srcFile = srcElem.getTextContent();    
String tgtFile = srcFile.substring(0, srcFile.lastIndexOf(".pgp"));    
      
args[0] = ;      
args[1] = ;      
      
      
pgp.setInputFileName(new String("/soaIntegration/pgp/receive/") + srcFile);      
pgp.setOutputFileName(new String("/soaIntegration/pgp/process/") + tgtFile);      
pgp.setSecretKeyFileName("/soaIntegration/pgp/pri-key.key");      
pgp.setPassphrase("mypassword");      
      
try {      
pgp.decrypt();      
}      
catch(Exception e)      
{      
  System.out.println("###PGP decryption failed:"+e.getMessage());      
}]]>

Additional: generate your own key pairs for test or for fun

What if you want to generate your own key pairs for test?  Here is what I did:
download "bcpg-jdk15on-147.zip" with source, then find this file PGPKeyRingTest.java in package org.bouncycastle.openpgp.test.

I modify generatetest() like below:
    public void generateTest()         throws Exception
    {
System.out.println("********* intercepted ********");
        char[]              passPhrase = "hello".toCharArray();
        KeyPairGenerator    dsaKpg = KeyPairGenerator.getInstance("DSA", "BC");
        dsaKpg.initialize(512);
...
PGPPublicKeyRing        pubRing = keyRingGen.generatePublicKeyRing();
        PGPPublicKey            vKey = null;
        PGPPublicKey            sKey = null;

  byte[] b = null;
            ByteArrayOutputStream baos = null;
            ArmoredOutputStream aos = null;
            try {
                    baos = new ByteArrayOutputStream();
                    aos = new ArmoredOutputStream(baos);
                    // get public key
                    pubRing.encode(aos);
                    aos.flush();
                    baos.flush();
                    aos.close() ;
                    b = baos.toByteArray();
                    System.out.println(new String(b));

                    baos = new ByteArrayOutputStream();
                    aos = new ArmoredOutputStream(baos);
                    // get private key
                    keyRing.encode(aos);
                    aos.flush();
                    baos.flush();
                    aos.close() ;
                    b = baos.toByteArray();
                    System.out.println(new String(b));

            } catch (Exception e) {
                    System.out.println("Exception caught while exporting SecretKeyRing"+ e);
            } finally {
                    aos.close();
                    baos.close();
            }
of course, i modified performTest() only to run generatetest().

you need to add bctest-jdk15on-147.jar to the classpath to run the above class. 

If you get java exceptions compiling or running, check step 4 above in the Java section.

There you go, you'll get your own public and private keys to play with (remember your password is "hello" in the above code, you can change it if you like).

PGP Command Line

BTW, if you happen to have the PGP command line from old PGP Corporation (currently owned by Symatec), you can generate your own keys, and test encryption and decryption from the command line.

To generate key:
   pgp --gen-key "foo@bar.com" --key-type rsa --bits 2048 --passphrase car

export the key:
     pgp --export-key-pair foo

To test encryption/decryption:
  pgp -e test.txt --recipient foo (or pgp -e test.txt --recipient foo --armor)

  pgp --decrypt test.txt.pgp  --passphrase "car"--output foo.txt

if you wonder where pgp command line stores key ring files, they are under here on windows: C:\Documents and Settings\yourUserName\My Documents\PGP. I was using the binary key rings initially before I figured out the export commands.

That's all

I assumed anyone reading this post has the basic idea how PGP works. What I demonstrated is how to use Java to decrypt a PGP file, and add the java solution to SOA composite. 





Thursday, October 11, 2012

OSB alert and report activities

I normally use "alert" to trace my message flows. Occasionally, I use "report".

Here is my personal view of pros and cons.

with "alert", you can drill down to the detail in 2 clicks. Once on the main "home" or "pipeline alerts" tab on the main console, then click on the actual alert. However, the "alert" title can't show any variable values. If you have 20 calls coming in, you have an "alert" that shows "id", then the subject of all those alerts will all show "id". You have to drill down to see the detail.

With report, you can put a key value, and report main page will show the entry with the actual value of the "id" from your payload. The good thing is you can see multiple entries with different ID's. However, in order to see the detail, you have to drill it twice more. Click on the "id" entry, then click on the "details" to see more.

Here is an example of my report entry:

I have a payload body looks like:


<ins:CisPidsRtCollection xmlns:ins="http://xmlns.oracle.com/pcbpel/adapter/db/top/insertRTPids">
     <ins:CisPidsRt>
        <ins:pid>123</ins:pid>
    </ins:CisPidsRt>
</ins:CisPidsRtCollection>

in my report, I can add expression like $body, then above payload will show in the "detail" link. I can also add a key "pid". Look closely, "pid" is an actual element inside the payload, then in the value section, i put in path as "ins:CisPidsRtCollection/ins:CisPidsRt/ins:pid", and variable as "body", then the report entry will show "pid=123".

OSB "publish" activity

Long story short, here is how I made my "publish" to work.

Assign "body" with this


<soapenv:Body xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <myBizPayload xmlns="blah">
        <blah>and</blah>
    <myBizPayload >
</soapenv:Body>

where <myBizPayload>...</myBizPayload> is the actual payload when you invoke your business service. You can find the biz service payload by popping up the OSB debug console on the Biz service, it will fill in a default payload for you.

Make sure you include soap <Body> as the wrapper, no more and no less. If you assign the wrong payload, OSB won't spit out a clue anywhere, it simply ignores your call and move on to the next activity!!!

Keep in mind that all variables inside "publish" block are local. You can make changes to any variable: body, inbound, outbound etc, they are all local copies. Any changes you make do not affect the variables outside "publish".

It's simple but very important to remember, you "publish" with the "body" variable. It beats why Oracle (or BEA doc for that matter) doesn't mention that anywhere. I had to figure out it trial and errors for hours: twice and a few years apart. Hence, this post. And I don't want to relearn this again.