Monday, September 16, 2013

How to fix " Problem: failed to create task or type if" when building ant on Middleware/Oracle_SOA1/soa/modules/oracle.soa.ext_11.1.1


Download the code from http://sourceforge.net/projects/ant-contrib/files/

Finally add the following lines to the task files

<taskdef resource="net/sf/antcontrib/antcontrib.properties">
  <classpath>
    <pathelement location="[downloaded path]/ant-contrib-1.0b3.jar"/>
  </classpath>
</taskdef>



Execute ant and issue will be fixed

Thursday, September 12, 2013

Add file name to Instance name using composites (mediator)


Sometimes is required to have the file name that we are pooling in our composite, we can achive that with a simple assign function in the mediator

1. Create an assign element

2. Add the following "expression" to from

med:setCompositeInstanceTitle($in.property.jca.file.FileName)

3. In the "properties "to add the following:

tracking.compositeInstanceTitle

Note: this properties is not shown in the list


Thursday, September 5, 2013

Create a PGP decryption pipeline Valve in Oracle SOA suite 11g




 SOA suite provides a way to do file preprocessing. In this particular scenario we will create a valve that uses PGP private key to decrypt an encrypted file.
               If you required additional information about oracle pipelines please review the following link
              
We are going to use bouncy castle as main PGP library
And this code as reference

A.     Java Valve code


1.      1. Create a new project in JDev adding the following libraries


Bpm-infra should be on your SOA Suite installation ./Oracle_OSB1/soa/modules/oracle.soa.fabric_11.1.1/bpm-infra.jar
Bcpg-jdk15on-19.jar, bcprov-ext-jdk15on-149.jar and bcprov-jdk15on-149.jar you can download them from bouncy castle website.
2.     2.  Create a properties file that will indicate where your key and passphrase are, add it to Jdev

#properties file for PGP decrypt file
privatekey=/home/oracle/work/aaronkey.gpg
passphrase=welcome1

3.      3. Create the following code

package something;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import java.util.Properties;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

import oracle.tip.pc.services.pipeline.AbstractValve;
import oracle.tip.pc.services.pipeline.InputStreamContext;
import oracle.tip.pc.services.pipeline.PipelineException;

public class DecryptPGPValve extends AbstractValve {
    public DecryptPGPValve() {
        super();
    }


    public InputStreamContext execute(InputStreamContext inputStreamContext) throws PipelineException,
                                                                                    IOException {
        Properties props = new Properties();
        try {
            props.load(DecryptPGPValve.class.getResourceAsStream("/resource.properties"));
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        PGPFileProcessor pgp = new PGPFileProcessor();

        pgp.setSecretKeyFileName(props.getProperty("privatekey")); // can be either binary or text key
        pgp.setPassphrase(props.getProperty("passphrase"));


        byte[] encrypted = null;

        try {
            encrypted = pgp.decrypt(inputStreamContext.getInputStream());
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        inputStreamContext.setInputStream(new ByteArrayInputStream(encrypted));

        return inputStreamContext;
    }

    public void finalize(InputStreamContext inputStreamContext) {
    }

    public void cleanup() throws PipelineException, IOException {
    }
}
   

4.      4. From the code provided by bouncy castle modify the decrypt method to return bytes
Something like this (check lines in red)

    /**
     * decrypt the passed in message stream
     */
    @SuppressWarnings("unchecked")
        public static byte[] decryptFileBytes(InputStream in, InputStream keyIn, char[] passwd)
        throws Exception
    {
    
        byte[] encrypted = null;
        Security.addProvider(new BouncyCastleProvider());

        in = org.bouncycastle.openpgp.PGPUtil.getDecoderStream(in);

        PGPObjectFactory pgpF = new PGPObjectFactory(in);
        PGPEncryptedDataList enc;

        Object o = pgpF.nextObject();
        //
        // the first object might be a PGP marker packet.
        //
        if (o instanceof  PGPEncryptedDataList) {
            enc = (PGPEncryptedDataList) o;
        } else {
            enc = (PGPEncryptedDataList) pgpF.nextObject();
        }

        //
        // find the secret key
        //
        Iterator<PGPPublicKeyEncryptedData> it = enc.getEncryptedDataObjects();
        PGPPrivateKey sKey = null;
        PGPPublicKeyEncryptedData pbe = null;

        while (sKey == null && it.hasNext()) {
            pbe = it.next();

            sKey = findPrivateKey(keyIn, pbe.getKeyID(), passwd);
        }

        if (sKey == null) {
            throw new IllegalArgumentException("Secret key for message not found.");
        }

        InputStream clear = pbe.getDataStream(new BcPublicKeyDataDecryptorFactory(sKey));

        PGPObjectFactory plainFact = new PGPObjectFactory(clear);

        Object message = plainFact.nextObject();

        if (message instanceof  PGPCompressedData) {
            PGPCompressedData cData = (PGPCompressedData) message;
            PGPObjectFactory pgpFact = new PGPObjectFactory(cData.getDataStream());

            message = pgpFact.nextObject();
        }


        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        final DataOutputStream dos = new DataOutputStream( baos );
              

        if (message instanceof  PGPLiteralData) {
            PGPLiteralData ld = (PGPLiteralData) message;

            InputStream unc = ld.getInputStream();
            int ch;

            while ((ch = unc.read()) >= 0) {
                //out.write(ch);
                dos.write(ch);
            }
           
            dos.close();
            encrypted = baos.toByteArray();
            baos.close();
                       
        } else if (message instanceof  PGPOnePassSignatureList) {
            throw new PGPException("Encrypted message contains a signed message - not literal data.");
        } else {
            throw new PGPException("Message is not a simple encrypted file - type unknown.");
        }

        if (pbe.isIntegrityProtected()) {
            if (!pbe.verify()) {
                throw new PGPException("Message failed integrity check");
            }
        }
        System.out.println("decode:" + encrypted);
        return encrypted;
    }
5.    5.  Compress your files in a JAR file and place them in
/home/oracle/Oracle/Middleware/Oracle_SOA1/soa/modules/oracle.soa.ext_11.1.1
/home/oracle/Oracle/Middleware/user_projects/domains/base_domain/lib

Directories might change

6.      6. Add bouncy castle libraries as well
Bcpg-jdk15on-19.jar, bcprov-ext-jdk15on-149.jar and bcprov-jdk15on-149.jar in the following directories

/home/oracle/Oracle/Middleware/Oracle_SOA1/soa/modules/oracle.soa.ext_11.1.1
/home/oracle/Oracle/Middleware/user_projects/domains/base_domain/lib

7. Bounce your server and let’s continue working on the composite

b. Composites


Our idea is to create a composite that will read a file from file system and will decode it another directory. This can be easily replace with FTP adapter and work as well.




1.      1. Create a PollFile adapter
a.      Is important to uncheck the Use file streaming option
b.      Use native format opaque
2.    2.    Create a “filePipeline.xml” file in Jdeveloper as following

<?xml version="1.0"?>
<pipeline xmlns="http://www.oracle.com/adapter/pipeline">
<valves>
        <valve>us.myvalve.com.ebs.encryption.gpg.DecryptPGPValve</valve>
</valves>
</pipeline>

3.      3. Open the poll jca file and add the pipeline property

<adapter-config name="PollFile" adapter="File Adapter" wsdlLocation="PollFile.wsdl" xmlns="http://platform.integration.oracle/blocks/adapter/fw/metadata">
 
  <connection-factory location="eis/FileAdapter" UIincludeWildcard="test*.pgp"/>
  <endpoint-activation portType="Read_ptt" operation="Read">
    <activation-spec className="oracle.tip.adapter.file.inbound.FileActivationSpec">
      <property name="DeleteFile" value="true"/>
      <property name="MinimumAge" value="0"/>
      <property name="PhysicalDirectory" value="/home/oracle/work/files"/>
      <property name="Recursive" value="false"/>
      <property name="PollingFrequency" value="10"/>
      <property name="PhysicalArchiveDirectory" value="/home/oracle/work/archive"/>
      <property name="IncludeFiles" value="test.*\.pgp"/>
      <property name="UseHeaders" value="false"/>
      <property name="PipelineFile" value="filePipeline.xml"/>
    </activation-spec>
  </endpoint-activation>

</adapter-config>

4.     4.  Create a write sync operation file


Your decryption should be ready to test 

Tuesday, September 3, 2013

How to fix "wsm 02120 unable to connect ot the policy access service" on UCM

1. Connect to /console
2. Follow the navigation
Environment >> Servers >>  [UCM Server] >> Configuration >> Listen Address
3. Add host of OWSM.
4. Bounce the node


Friday, August 23, 2013

Connect OSB to UCM using OWSM




For this example we are using basic header security to make the connection

11. Open EM, you need to add the proper credentials.



2. Click on "add a Key" using a user name and password from UCM (as an example weblogic)




3.      On Service bus create a new business service pointing to the URL

4.      On  the policies tab add “oracle/wss_username_token_client_policy” policy



5.      Finally on the security tab add the credential that was added in step 2



6.      Finally you should be able and connect to UCM from OSB.

Wednesday, August 21, 2013

Oracle eBusiness Custom Business Events Setup

Frequently integrations between Oracle eBusiness and any other partners are made old school. The following explanation shows how how to push Oracle BES (Business Events) into a custom queue and from there any Middleware technology could pick it up.

As an example we are creating a custom BES labeled as salamanderinc.apps.glcode.update.

Steps to accomplish this are as follow
1 - Create custom Oracle AQ where custom events land
2 - Create custom package/procedure to generate event payload and post to custom Oracle AQ
3 - Within eBusiness console and with workflow admin rights do
3.1 - Create custom event such as

3.2 - Create group and assign previous event to the group



3.3 - Create agent

3.4 - Create subscription for the event group


3.5 - Test the event within the console









Friday, August 16, 2013

Cisco integration and Oracle UWQ using OSB

Cisco and UWQ both work with http messages. Basically an interchange of POST between the platforms. Cisco Agent Descktop and Oracle UWQ.

1. First we are going to create a business service that will be in charge of posting messages to UWQ
Define the  following characteristics in our business service

General >> Service Type: Messaging Service
Messaging >> Request : Text
                      Response: None
Transport >> http
HTTP Transport >> Please make sure that use chunked streaming Mode is unchecked (it will not POST otherwise)


2. We are going to configure Cisco Workflow Administrator to raise an action every time the agent answers the phone.

Using the following parameters
protocol: http
method: POST
host: [host name of you OSB instance]
pot: [port of you OSB server, default is 8011]
path: [full path of the proxy we will create in step 3, example /CiscoIntegration/CiscoUWQHandler]

3. Create a proxy in Service Bus with the following information

General >> Service Type= Messaging Service
Messaging >> Request = Text
                       Response = Text
Transport >> Get All Headers = Yes

First We are going to create a pipeline and add an stage in the request side

Assign this a query to a variable called "sendData"

<CCTSDK>
<event name="{ fn:tokenize( (fn:tokenize($CiscoMessage, '&amp;')[2]) , '=')[2]}">
<data name="occtSourceID" value="1"/>
<data name="occtANI" value="{ fn:tokenize( (fn:tokenize($CiscoMessage, '&amp;')[1]) , '=')[2]}"/>
</event>
</CCTSDK>

This will transform the cisco post in a message that UWQ will understand


Now you need to capture the address of he Cisco Agent desktop assign the following variable to "clientAddress"

$inbound/ctx:transport/ctx:request/http:client-address/text()

Create a publish to the business created in step 2 adding the following

Routing Options to the uri previously captured fn:concat('http://',$clientAddress,':8888//')

and replace the body with the variable sendData, using Repalce node contents