Tuesday, June 24, 2014

Change JDK used by JDeveloper

You can change JDK used by JDeveloper.
The JDK configuration for JDeveloper is defined in the jdev.conf which located in your Jdeveloper folder JDeveloper\jdeveloper\jdev\bin.

Open the file and find the item:  SetJavaHome.  Change its value to your new JDK folder.

In the below example I switch JDK from JDK 7 to JDK 6 by commenting out JDK 7 and adding a new item for JDK 6. 

#SetJavaHome C:\Java\jdk1.7.0_06
SetJavaHome C:\Program Files\Java\jdk1.6.0_45

After saving the changes restart JDeveloper and it will use the new JDK set in jdev,conf.

You can check JDK used in JDeveloper from JDeveloper.   From JDeveloper goes to Help->About.  Then select the tab Properties and will find java.home properties now is set to the JDK specified in jdev.conf.


Monday, June 9, 2014

Set the composite name using function ora:setCompositeInstanceTitle()

ora:setCompositeInstanceTitle() can be used to set the name of the composite instance.  It is very useful because you can set the name of the composite instance using the values with business meaning.  It would be convenient for the support people to search for a particular instance by the business value.

It is can be done in either BPEL component or Mediator component.

Within BPEL component what needs to be done is set one variable using ora:setCompositeInstanceTitle() which can be found from Advanced Functions.  


<variable name="CompositeTitle" type="xsd:string"/>
<assign name="SetInstanceName">
      <copy>
        <from expression="ora:setCompositeInstanceTitle(concat('Test   :', ora:getCompositeInstanceId()) )"/>
        <to variable="CompositeTitle"/>
      </copy>        
</assign>





Within Mediator component it is done by setting one property using ora:setCompositeInstanceTitle().   Clicking on Assign Values button in the below diagram will start to set the value to the property.



In Assign Value popup window To type is selected as property and the property value is select as: tracking.compositeInstanceId.

From type is selected as expression. In the expression Builder select ora:setCompositeInstanceTitle() which can be found from Mediator Expression Functions.



Now the property is assigned which will set the composite title in Mediator.


Sunday, May 25, 2014

Sending email with attachments in Oracle SOA 11g

Here I show one generic BPLE service which will send the email with attachment.  


Generic Email Service Interface


The service interface is defined by the below xsd file.  In the request message apart from email to, from, subject and body elements there is one array of attachment elements which are sent with the email.

<element name="NotificationRequest">
 <complexType>
  <sequence>
   <element name="From" type="string" minOccurs="0"/>
   <element name="To" type="string"/>
   <element name="CC" type="string" minOccurs="0"/>
   <element name="Subject" type="string"/>
   <element name="Body" type="string" minOccurs="0"/>
   <element name="Attachment" type="tns:AttachmentType" minOccurs="0" maxOccurs="unbounded"/>
  </sequence>
 </complexType>
</element>
<complexType name="AttachmentType">
 <sequence>
  <element name="MimeType" type="string"/>
  <element name="AttachmentContent" type="anyType"/>
  <element name="AttachmentName" type="string"/>
  <element name="ContentEncoding" type="string"/>
 </sequence>
</complexType> 



Oracle Notification Service


This service will use Notification service provided by Oracle SOA 11g. Notification service uses Oracle User Messaging Service to send email, SMS, IM and etc. notification to the recipients.   Notification service can be invoked from BPEL process.   From JDeveloper you can choose the different notification channels.  For sending email you need to choose Email as below.


After dragging and dropping Email into BPEL process, NotificationService.wsdl and NotificationService.xsd are added to the project.  These wsdl and xsd files define the interface to Oracle User Messaging Service.  For request message which sends email is defined as EmailPayloadType.  The key to send the email with attachments is to populate the appropriate values in EmailPayload.

EmailPayloadType defines the request message for invoking Oracle Notification service to send the email.  
<xsd:complexType name="ContentType">
 <xsd:sequence>
  <xsd:element name="MimeType" type="xsd:string" default="text/plain" minOccurs="0"/>
  <xsd:element name="ContentBody" type="xsd:anyType" nillable="true"/>
  <xsd:element name="ContentEncoding" type="xsd:string" nillable="true"/>
 </xsd:sequence>
</xsd:complexType>

ContentType defines the email content.  Note here that ContentBody is defined as anyType.  In order to include the attachments in email there are two things needed to be done:

  • MimeType should be set as: multipart/mixed.   
  • ContentBody will use MultiPartType.


<xsd:complexType name="MultiPartType">
 <xsd:sequence>
  <xsd:element name="BodyPart" type="BodyPartType" maxOccurs="unbounded"/>
 </xsd:sequence>
</xsd:complexType>

The MultiPartType is an array of BodyPartType.  First element in thus array is the email body itself and the subsequent elements are the attachments for the email.
<xsd:complexType name="BodyPartType">
 <xsd:sequence>
  <xsd:element name="MimeType" type="xsd:string" default="text/plain" minOccurs="0"/>
  <xsd:element name="ContentBody" type="xsd:anyType" nillable="true"/>
  <xsd:element name="BodyPartName" type="xsd:string"/>
  <xsd:element name="Disposition" type="dispositionEnum" default="inline" minOccurs="0"/>
  <xsd:element name="ContentId" type="xsd:string" minOccurs="0"/>
  <xsd:element name="ContentEncoding" type="contentEncodingEnum" nillable="true"/>
  <xsd:element name="AttachmentContentEnclosed" type="xsd:boolean" default="true" minOccurs="0"/>
 </xsd:sequence>
</xsd:complexType>

BodyPartType defines the email body and attachment for the email.   MimeType specifies the type of data in email.   If the email body is HTML email the MimeType of email body(first Body Part) would be: "text/html; charset=UTF-8".   Depending on the attachments with the email the MimeType in BodyParts for attachments can be set the values of proper Mime type.   
Some of such values are shown below:
image/tiff;            - tiff image file
image/jpeg;            - jpeg image file   
application/pdf;       - PDF file
application/xml;       - XML file  
application/msword;    - MS Word file

ContentBody in BodyPartType will be the actual data for email body and attachment.  For the attachment the ContentEncoding will be set as base64. BodyPartName will be set as the file name for the attachment.

The below is one example of EmailPayload message which are populated with the data.  The email will have one attachment of .tiff image file whose name is Testing.tif.
<EmailPayload xsi:type="def:EmailPayloadType">
 <FromAccountName>Default</FromAccountName>
 <To>Mark_ke_chen@yahoo.com</To>
 <ReplyToAddress/>
 <Subject>Tesyimg email with one attachement</Subject>
 <Content>
  <ns:MimeType>multipart/mixed</ns:MimeType>
  <ns:ContentBody>
   <ns:MultiPart>
    <ns:BodyPart>
     <ns:MimeType>text/html; charset=UTF-8</ns:MimeType>
     <ns:ContentBody>
      ......  Email body here
     </ns:ContentBody>
     <ns:BodyPartName/>
     <Disposition>inline</Disposition>
    </ns:BodyPart>
    <ns:BodyPart>
     <ns:MimeType>image/tiff;</ns:MimeType>
     <ns:ContentBody>
      .... Tiff image data
     </ns:ContentBody>
     <ns:BodyPartName>Testing.tif</ns:BodyPartName>
     <ns:ContentEncoding>base64</ns:ContentEncoding>
     <Disposition>attachment</Disposition>
    </ns:BodyPart>
   </ns:MultiPart>
  </ns:ContentBody>
 </Content>
 <Cc/>
 <Bcc/>
 <NotificationContext/>
</EmailPayload>

Here use xlst transformation to populate the Content element.
<copy>
 <from expression="ora:processXSLT('xsl/EmailContentBodyTransform.xsl', $NotificationRequest.payload)"/>

 <to variable="varNotificationReq"
  part="EmailPayload"
  query="/EmailPayload/ns1:Content"/>
</copy>

The below is the snippet of XSLT transformation.
<ns:Content>
 <ns:MimeType>multipart/mixed</ns:MimeType>
 <ns:ContentBody>
  <ns:MultiPart>
   <ns:BodyPart>
    <ns:MimeType >text/html; charset=UTF-8</ns:MimeType>
    <ns:ContentBody>
     <xsl:value-of select="/*[local-name()='NotificationRequest']/*[local-name()='Body']"/>
    </ns:ContentBody>
    <ns:BodyPartName/>
   </ns:BodyPart>
   <xsl:for-each select="/*[local-name()='NotificationRequest']/*[local-name()='Attachment']">
    <ns:BodyPart >
     <ns:MimeType>
      <xsl:value-of select="./*[local-name()='MimeType']"/>
     </ns:MimeType>
     <ns:ContentBody >
      <xsl:value-of select="./*[local-name()='AttachmentContent']"/>
     </ns:ContentBody>
     <ns:BodyPartName>
      <xsl:value-of select="./*[local-name()='AttachmentName']"/>
     </ns:BodyPartName>
     <ns:ContentEncoding>
      <xsl:value-of select="./*[local-name()='ContentEncoding']"/>
     </ns:ContentEncoding>
    </ns:BodyPart>
   </xsl:for-each>
  </ns:MultiPart>
 </ns:ContentBody>
</ns:Content>


Testing Email service with attachments


In order to test this generic email service I have another BPEL service which will populate email body and attachment and then invoke the generic email service.  The below shows the two assign activities used in the BPEL to set the email body and email attachment.

<assign name="AssignEmailBody">
  <copy>
 <from expression="ora:toCDATA(  ora:processXSLT('xsl/TransformHTMLEmailBody.xsl', $Request.request, bpws:getVariableData('Parameters')) )"/>
 <to variable="EmailNotificationRequest" part="payload"
  query="/ns4:NotificationRequest/ns4:Body"/>
  </copy>
</assign>

<assign name="AssignEmailAttachment">
  <copy>
 <from expression="ora:readFile( $ImageFileName) )"/>
 <to variable="EmailNotificationRequest" part="payload"
  query="/ns4:NotificationRequest/ns4:Attachment/ns4:AttachmentContent"/>
  </copy>
</assign>

One assign is used to set the email body. Since the email is HTML format the assign activity uses ora:toCDATA to wrap the html content.   
Another assign activity uses orad:readFile function to read the physical file which is going to attach in the email.

Tuesday, May 20, 2014

Setting and Getting Configuration Property and Preference Variable in Oracle SOA Suite 11g

Configuration property and preference variable can be set in composite.xml.  The advantage of using these is that the values can be set in the design time, deployment time and run time.

Define the Properties and Preference Variables


The configuration property and preference variable is defined in composite.xml
In the component of the example composite one configuration property: ConfigVar is defined.  Its value is set Value123 initially. One preference varaible PrefVar is also defined and its value is set to Value789 initially.



In the reference of the example composite one configuration property: OUT_FILE_PATH is defined.  This property is set when configuring the logical file path for File adpter.   This property value is also defined in .jca file.


Retrive the Values of  the Properties and Preference Variables

The component is the example composite is BPEL process where the configuration properties and preference variables can be retrived from winthin BPEL.  The retrival can be done by using BPEL XPath Extension Functions: ora:getPreference() and ora: 

View and Midify the Values in Enterprise Manager


These values of the configuration properties and preference variables can be viewed and modified in run time with Enterprise Manager.   



After login into EM navigate into the domain and right click on the domain to invoke System MBean Browser.  From System MBean Browser navigate to Application Defined MBeans/oracle.soa.config/Server: SOA_server1/SCAComposite.   Expand it and expand SCAComposite: ConfigPreferenceProject[1.0].  



To view or modify the values defined for BPEL: select SCAComposite.SCAComponent and then click on BPELProcess1.  Then click on properties in Attribute tab.  All the configuration properties and preference variables defined in the BPEL are shown now.  





In order to change the value of one variable or property just type in the new value and then click on Apply button.

To view or modify the property values defined for reference: select SCAComposite.SCARefernce.  All other steps are the same as the above.



Similarily if there is any configuration property defined in SCAComposite.SCAService select SCAComposite,SCAService in order to view or modify the property values. 




Test the Composite with the Modified Values 

When testing the SCA composite using EM testing utility, the response will show the values of configuration and preference variable in BPEL process as :Value123   Value789".(This BPEL process simply concatenate these two values as the response for the process.) 


Next modify the value of configuration property to 123Value and preference value to 789Value and apply these changes.  Then run the testing again.   This time the response will show as the new values:


Deploy the Composite with Environment Specific Values

With configuration properties and preference variables in the component, service and references in SCA composite different deployment plans can be generated for various environments.  In each deployment plan the values for these properties and variables are environment specific.


Monday, May 12, 2014

Develop and Deploy Jersey RESTful service using JDeveloper in Weblogic

Jersey is one of reference implementations of JAX-WS specification which is to describe how REST should be implemented using annotation-driven POJO in Java. Jersey is the one that is most widely used in development and production. WebLogic Server ships with a set of pre-built shared libraries, packaged as Web applications. Jesery is one of these and it is required to run applications that are based on the Jersey JAX-RS RI. The version of Jsersey in weblogic 10.3 is 1.9 which implements JAX-RS 1.1.

This jersey war file is located in:  $Middleware/wlserver_10.3/common/deployable-libraries/jersey-bundle-1.9.war.


Register Jersey as the shared library in Weblogic server 


Before the REST application can be deployed and run on Weblogic the Jersey JAX-RS RI shared libraries needs to be registered in Weblogic Servcre instance. It can be done via Weblogic Console. 
Login into Weblogic Console Click on Deployments in Domain Structure
Click on Lock & Edit button to enable Install button and then click on Install button


The path should be:  /u01/app/fmwsodev/Middleware/wlserver_10.3/common/deployable-libraries
Select jersey-bundle-1.9.war and click on Next button

Select Install this deployment as a library and click on Next button

Select target and click on Next button


Select target and click on Next button


Confirm the library name, version and implementation version as below and click on Finish button



Now Jersey JAX-RS RI is registered as shared library in Weblogic server.  Any application deployed on the server can use this library for implementation of REST service using Jersey.



Develop Jersey REST service using JDeveloper


Create a generic project in JDeveloper




In order to develop Java codes which use Jersey to implement RESTful service, two jar files are needed to add into User Managed Libraries in JDeveloper.


First jar is jersey-bundle-1.9.jar which can be downloaded from:

http://repo1.maven.org/maven2/com/sun/jersey/jersey-bundle/1.9/jersey-bundle-1.9.jar


Since jersey-bundle-1.9.jar doesn't include JAX-RS API classes.  So JAX-RS API jar is also needed.   The jar file can be found from Weblogic server installation folder: $Middleware/modules/javax.ws.rs_1.0.0.0_1-1-1.jar


After two jar files are added into the libraries use these two libaries in the project: RESTProject by using Add Library in Libraries and Classpath from Project Properties... menu item.


Now create a POJO which will implement the service:

The source codes of Java class: RESTService are as below:


package com.toic.rest;

import com.toic.model.Folder;

import java.util.logging.Logger;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;


@Path("/folders")
public class RESTService {
    
    private Logger logger = Logger.getLogger(RESTService.class.getName());
    
    public RESTService() {
        super();
    }
    
    @GET
    @Path("/guid/{folderguid}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response getFoldersByGUID(@PathParam("folderguid") String folderguid) {
        
        Folder folder = Folder.makeFolders();
        
        return Response.status(Response.Status.OK).entity(folder).build();
    }
}
The below is one domain class Folder which is used in RESTService class.


package com.toic.model;

import java.util.ArrayList;
import java.util.List;

public class Folder {
    
    private String folderName;
    
    private String owner;
    
    private String folderGUID;
    
    private String folderType;
    
    private List childFolders = new ArrayList();
    
    
    public Folder() {
        super();
    }

    public String getFolderName() {
        return folderName;
    }

    public void setFolderName(String folderName) {
        this.folderName = folderName;
    }

    public String getOwner() {
        return owner;
    }

    public void setOwner(String owner) {
        this.owner = owner;
    }

    public String getFolderGUID() {
        return folderGUID;
    }

    public void setFolderGUID(String folderGUID) {
        this.folderGUID = folderGUID;
    }

    public String getFolderType() {
        return folderType;
    }

    public void setFolderType(String folderType) {
        this.folderType = folderType;
    }

    public List getChildFolders() {
        return childFolders;
    }

    public void addChildFolder(Folder childFolder) {
        this.childFolders.add(childFolder);
    }
    
    public static Folder makeFolders() {
        Folder rootFolder = new Folder();
        
        rootFolder.setFolderName("Root Folder");
        rootFolder.setOwner("Mark");
        rootFolder.setFolderGUID("123456");
        rootFolder.setFolderType("NATIVE");
        
        Folder childFolder1 = new Folder();
        
        childFolder1.setFolderName("Folder1");
        childFolder1.setOwner("Mark");
        childFolder1.setFolderGUID("100234");
        childFolder1.setFolderType("NATIVE");
        
        Folder childFolder2 = new Folder();
        
        childFolder2.setFolderName("Folder2");
        childFolder2.setOwner("Mark");
        childFolder2.setFolderGUID("200234");
        childFolder2.setFolderType("NATIVE");

        rootFolder.addChildFolder(childFolder1);
        
        rootFolder.addChildFolder(childFolder2);
        
        return rootFolder;
    }
}


In RESTService.java editor click on Quick Fix to configure web.xml for this service.



web.xml is created under WEB-INF.


Update url-pattern to *


Then create Weblogic Deployment Descriptor


weblogic.xml file is created under WEB-INF as shown as below:


In run time the deployed service will use the shared library of Weblogic.  Here in weblogic.xml the library reference should be created as below:


Next step is to update the deployment profile of the service which is deployed as web application,


The service is called RESTService.


Update the context root as: Demo.



Deploy Jersey REST service and test the service


After all is done the service is ready to deploy to Weblogic server from JDeveloper.



If the deployment is successful RESTService will appear in the deployments of Weblogic Console.


Click on RESTService and click on Testing tab



Click on the Test Point URL to start browser and type in the url as: http://weblogicserverhost:8001/Demo/folders/guid/123456 and the service will respond as below:

















Sunday, April 20, 2014

Using Oracle AQ with Oracle SOA 11g & OSB 11g

Oracle Advanced Queuing(AQ) is Oracle Database message queuing mechanism which acts as the queuing infrastructure.  With AQ the different applications can communicate and exchange the message via Oracle database queues.  Oracle AQ provides the API to enqueue and dequeue the messages to and from the queues in Oracle database.

Oracel AQ is the integral part of Oracle database already.  In this tutorial Oracle XE 10g is used.   Oracle AQ is available from two built-in PL/SQL packages in Oracle database:
 DBMS_AQADM and DBMS_AQ.

DBMS_AQADM
 package provides PL/SQL procedures to manage the AQ configuration and administration.  Some basic functionality in DBMS_AQADM are like: Create the queue table, create the queue, start the queue, stop queue.

DBMS_AQ
 package provides the interface to other applications to AQ.  DEQUEUE and ENQUEUE are two procedures for enqeuing and deqeuing the AQ queue.

After one AQ queue is created and started the application such as PL/SQL procedures can enqueue the message  into the queue and other application such as one SOA component can dequeue the message from this queue.

The below are the steps showing how one AQ queue is created from the scratch and how a message is enqueued in the queue and etc.  After these the steps of creating one SOA component to dequeue the message from AQ queue.


Setup AQ queue in Oracle XE 10g


There are several steps in setting up one AQ queue in Oracle database:


1.     Create one user in database.  This user will be granted with the roles: AQ_ADMINISTRATOR_ROLE, AQ_USER_ROLE.  Log into Oracle XE 10g as the sysdba and then create one user called EVENT_USER and then grant certain privileges to this user.

sqlplus sys@localhost:1521/xe as sysdba
create user EVENT_USER identified by oracle;
grant create session, resource, AQ_ADMINISTRATOR_ROLE,AQ_USER_ROLE to EVENT_USER;
grant execute on DBMS_AQADM to EVENT_USER;
grant execute on DBMS_AQ to EVENT_USER;

2.     Create a queue table.  Before one type called invoice_type is created.  This type is used as the payload type of the message in AQ queue.   


create or replace type invoice_type as object(
      invoice_id number,
      invoice_number varchar2(60),
      vendor_id number
);
/

exec DBMS_AQADM.CREATE_QUEUE_TABLE ( 
              queue_table => 'EVENT_USER.invoice_queue_table', 
              queue_payload_type => 'EVENT_USER.invoice_type');

SELECT queue_table,type,object_type,recipients FROM USER_QUEUE_TABLES;
3.     After the queue table is created create a queue
exec DBMS_AQADM.CREATE_QUEUE (
          queue_name =>'EVENT_USER.invoice_queue',              
          queue_table=>'EVENT_USER.invoice_queue_table'); 

select name, queue_table, queue_type from user_queues;
After the execution of above PL/SQL scripts some database objects are created for this AQ queue as shown below. 



4.     Last step is to start the queue.  It can be done by executing the below procedure from DBMS_AQADM.
exec DBMS_AQADM.START_QUEUE('EVENT_USER.invoice_queue');


Enqueue AQ queue with PL/SQL package
Now the queue is ready to enqueue a message in the AQ queue just created and started. In this example one PL/SQL procedure from DBMS_AQ package is used to enqueue the AQ queue.

DECLARE
  enqueue_options    dbms_aq.enqueue_options_t;
  message_properties       dbms_aq.message_properties_t;
  message_handle     RAW(16);
  message           invoice_type ;
  message_id         NUMBER;
BEGIN

 message := invoice_type (10, 'ABCD123', 80);
 enqueue_options.VISIBILITY := DBMS_AQ.ON_COMMIT;
  enqueue_options.SEQUENCE_DEVIATION := null;
  message_properties.EXPIRATION := DBMS_AQ.NEVER;

    DBMS_AQ.ENQUEUE (
    queue_name => 'invoice_queue',
    enqueue_options => enqueue_options,
    message_properties => message_properties,
    payload => message,
    msgid => message_handle);
    
  COMMIT;
END;
/

The message just enqueued can be browsed using the below query:
SELECT count(*) FROM aq$invoice_queue_table

SELECT user_data FROM   aq$invoice_queue_table;


Consume the message in AQ queue from Oracle SOA component
Oracle SOA component(BPEL and Mediator) can  consume the message from AQ queue(dequeue) or produce the message into the queue(enqueue). It is done by using Oracle SOA uses JCA adapter for AQ.

In order to use AQ adapter some configurations need to be done.
1.     Create the data source in Weblogic console via Domain Structure->Services->Data Sources.  
This data source will point to the Oracle database where AQ queue resides on.  In this example it is Oracle XE 10g running on local machine. Here AQEvent data source is created and its JNDI name is set as jdbc/AQEvent



2.     Create AQAdpater instance in Weblogic console via Domain Structure->Deployments->Deployments->AQAdapter.  
An new AQ adapter instance is created as eis/AQ/LocalEventConnection whose XADataSourceName is set as: jdbc/AQEvent.



3.     Use AQAdapter in JDeveloper
Here the AQAdapter will be used as the service to consume the message from the AQ queue specified in adapter jca file.  This jca file also specifies the AQ connection factory which is configured as eis/AQ/LocalEventConnection in the above step.


<adapter-config adapter="AQ Adapter" name="AQEventService" wsdllocation="AQEventService.wsdl" xmlns="http://platform.integration.oracle/blocks/adapter/fw/metadata">
  
  <connection-factory location="eis/AQ/LocalEventConnectionen" uiconnectionname="LocalEventConnectionen">
  <endpoint-activation operation="Dequeue" porttype="Dequeue_ptt">
    <activation-spec classname="oracle.tip.adapter.aq.inbound.AQDequeueActivationSpec">
      <property name="SchemaValidation" value="false">
      <property name="QueueName" value="INVOICE_QUEUE">
      <property name="DatabaseSchema" value="EVENT_USER">
    </property></property></property></activation-spec>
  </endpoint-activation>

</connection-factory>
</adapter-config>



After the SOA project is deployed to the server, the AQAdapter will start to poll the message in AQInvoice queue.


Consume the message in AQ queue from OSB
In OSB JCA adapter is also used to poll the message in AQ queue.  Here the AQ JCA used in SOA will be used to generate one proxy service.   Also assume that the same data source and AQAdapter instance are configured in OSB server.

Create one OSB project as AQTestProject.
Copy the below files from JDeveloper to the OSB project:
                  AQEventService_aq.jca
                  AQEventService.wsdl
                  xsd/EVENT_USER_INVOICE_TYPE.xsd



From .jca file to generate the OSB proxy service.


The generated proxy service will be as the below:




Design the message flow as below:


After the OSB project is deployed on the server it will start to consume the message in AQ.