Monday 10 March 2014

oracle.fabric.common.FabricException

oracle.fabric.common.FabricException: oracle.fabric.common.FabricInvocationException: Exception [TOPLINK-4002] (Oracle TopLink - 11g Release 1 (11.1.1.6.0) (Build 111018)): oracle.toplink.exceptions.DatabaseException
Internal Exception: weblogic.jdbc.extensions.PoolDisabledSQLException: weblogic.common.resourcepool.ResourceDisabledException: Pool SOALocalTxDataSource is Suspended, cannot allocate resources to applications..
Error Code: 0: Exception [TOPLINK-4002] (Oracle TopLink - 11g Release 1 (11.1.1.6.0) (Build 111018)): oracle.toplink.exceptions.DatabaseException
Internal Exception: weblogic.jdbc.extensions.PoolDisabledSQLException: weblogic.common.resourcepool.ResourceDisabledException: Pool SOALocalTxDataSource is Suspended, cannot allocate resources to applications..
Error Code: 0


Whenever you receive oracle.fabric.common.FabricException in SOA check that your database is running or that tablespace is good.

Because SOA BPEL is stateful in won't work without database.


Monday 10 February 2014

How to add sequence numbers in XSLT for EBS AP_Invoice_Interface and AP_Invoice_Lines

Create a valid data-source connection to your database. I have used the EBS Application Adapter to create the sequence number for my InvoiceId.

        <top:invoiceId>
          <xsl:value-of select='oraext:sequence-next-val("AP_INVOICES_INTERFACE_S","jdbc/soa/ebsdev")'/>
        </top:invoiceId>

              <top:invoiceLineId>
                <xsl:value-of select='oraext:sequence-next-val("AP_INVOICE_LINES_INTERFACE_S","jdbc/soa/ebsdev")'/>
              </top:invoiceLineId>

As seen above, you can create the sequence number within xslt pointing it to the data-source configured on your weblogic

Monday 28 October 2013

How to decode a URL image link to a Base64 image string

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import sun.misc.BASE64Encoder;

public class DecodeLinkURL {
    public DecodeLinkURL() {
        super();
    }


  public static String getBase64FromLink(String inputURL) throws Exception{
 
  try {
     
    DefaultHttpClient client = new DefaultHttpClient();
    HttpGet request = new HttpGet(inputURL);
    HttpResponse response;
    response = client.execute(request);

    // Get the response
    BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent());
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
   
    byte[] chunk = new byte[1024];
    int read;
    do {
      read = bis.read(chunk);
        if (read >= 0) {
          bos.write(chunk, 0, read);
        }
    } while (read >= 0);
   
    BASE64Encoder encoder = new BASE64Encoder();
    String output = encoder.encode(bos.toByteArray());
   
    System.out.println(output);
   
    bos.close();
    bis.close();
     
    return output;
     
  } catch (Exception e) {
      e.printStackTrace();
      throw e;
  }
 
}

    public static void main(String[] args) throws Exception {
        DecodeLinkURL decodeLink = new DecodeLinkURL();
        String stringURL = "www.seedsindia.org/pdf_file/1008904462sample.pdf?";
        String Base64Out = decodeLink.getBase64FromLink(stringURL);
        System.out.println("Base64 String; " + Base64Out);
       
    }
}

Friday 18 October 2013

Convert Base64 to Bytes and convert Bytes to String

import java.io.IOException;

import sun.misc.BASE64Decoder;

public class ConvertorFactory {
    public ConvertorFactory() {
        super();
    }
   

public static void main(String[] args) {


       
            try {  

           String someBase64String = "<paste base64 coded string here>";
           BASE64Decoder decoder = new BASE64Decoder();
            byte[] byte= decoder.decodeBuffer(someBase64String);
   
            ConvertorFactory enc = new ConvertorFactory();
            String myMessage = enc.bytesToStringUTFCustom(byte);
            System.out.println("myDecodedString: " +myMessage);

           
        } catch (IOException e) {
        }
    }



    public static String bytesToStringUTFCustom(byte[] bytes) {
        char[] buffer = new char[bytes.length >> 1];
        for (int i = 0; i < buffer.length; i++) {
            int bpos = i << 1;
            char c = (char)(((bytes[bpos] & 0x00FF) << 8) + (bytes[bpos + 1] & 0x00FF));
            buffer[i] = c;
        }
        return new String(buffer);

    }

Convert string to Bytes

How to convert string to Bytes

 public static byte[] stringToBytesUTFCustom(String str) {
        byte[] b = new byte[str.length() << 1];
        for (int i = 0; i < str.length(); i++) {
            char strChar = str.charAt(i);
            int bpos = i << 1;
            b[bpos] = (byte)((strChar & 0xFF00) >> 8);
            b[bpos + 1] = (byte)(strChar & 0x00FF);
        }
        return b;

    }

Monday 14 October 2013

How to create MDB that listens on JMS Queue

I recently needed to do a project like this and found the information out there wasn't good enough, especially when you want to create something which uses Oracle WebLogic.

Hope this is helpfull:

I have broken this up into two sections - a JMS creation section and a code snippet which will listen on the queue you'll create on WebLogic



JMS Creation:

For EJB Message Driven Beans to listen and retrieve messages from queue, you need to cerate a queue on WebLogic

I created a project that basically receives messages from external systems. My service is exposed on OSB and will publish the message to my created EmailQueue

1. Log into WebLogic
2. Create JMS Server - Navigate to Services>Messaging>JMS Servers and click new (I called mine EmailJMSServer)
3. Create JMS Module - Navigate to Services>Messaging>JMS Modules and click new
4. Open your Module and create a EmailConnectionFactory and EmailQueue - Note that both must use the same subDeployment

See my JNDI Names below:



5. Restart WebLogic or Managed Server if you have targeted anything else

Code to listen on JMS
Now that you have completed your JMS setup, now you can begin with the MDB to listen on the queue. I used JDeveloper.

1.Create New>All Technologies>EJB>Message Driven Bean

2.Select EJB 3 and click next
3.Name your EJB MDB and select Container, then also chnage the Mapped Name to jms/EmailQueue
4.Go next and Finish

the below Code listens for message on JMS, takes the message which is xml and parses it to SAX to get normal Java Object, it then goes and calls a normal Java jar to email the result.

Code:

package com.ifc.email.model;


import com.ifc.email.SendEmailEngineHelper;
import com.ifc.xml.EmailInfo;
import com.ifc.xml.XMLSaxHandlerParser;

import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;

import javax.ejb.MessageDrivenContext;

import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

@MessageDriven(name = "EmailQueue", description = "EmailMDBQueue",
               mappedName = "jms/EmailQueue",
               messageListenerInterface = MessageListener.class,
               activationConfig =
               { @ActivationConfigProperty(propertyName = "destinationType",
                                           propertyValue = "javax.jms.Queue"),
                 @ActivationConfigProperty(propertyName = "destination",
                                           propertyValue = "queue/MyQueue") })
public class EmailNotificationMDBBean implements MessageListener {


    private MessageDrivenContext context;

    // --------------------------------------------------------------
    // EJB Methods from MessageDrivenBean interface
    // --------------------------------------------------------------

    public void ejbCreate() {
        System.out.println("EmailMDB: ejbCreate called");
    }

    public void ejbRemove() {
        System.out.println("EmailMDB: ejbRemove called");
    }

    public void setMessageDrivenContext(MessageDrivenContext context) {
        System.out.println("setMessageDrivenContext called");
        this.context = context;
    }

    public void onMessage(Message message) {
        try {
            TextMessage textMessage = (TextMessage)message;


            System.out.println("New message received: " +
                               textMessage.toString());

            String xmlString = textMessage.getText().toString();
            System.out.println("XMLString " + xmlString);

            XMLSaxHandlerParser sp = new XMLSaxHandlerParser();
            EmailInfo email = sp.getXml(textMessage.getText());


            String fromAddress = email.getFromAddress();
            System.out.println("FROM " + fromAddress);
            String[] toAddress = email.getToAddress();
            System.out.println("TO " + toAddress);
            String[] ccAddress = email.getCCAddress();
            System.out.println("CC " + ccAddress);
            String[] bccAddress = email.getBCCAddress();
            System.out.println("BCC " + bccAddress);
            String subject = email.getSubject();
            System.out.println("FROM " + subject);
            String body = email.getBody();
            System.out.println("BODY " + body);
            String attachementName = email.getAttachmentName();
            System.out.println("attachementName " + attachementName);
            String attachementBase64 = email.getAttachmentBase64();
            System.out.println("attachementBase64 " + attachementBase64);


            SendEmailEngineHelper sendMail = new SendEmailEngineHelper();

            sendMail.SendMailer(fromAddress, toAddress, ccAddress, bccAddress,
                                subject, body, attachementName,
                                attachementBase64);

        } catch (JMSException e) {
            e.printStackTrace();
        } catch (Exception e) {
        }

    }
}




OSB (Acting as the client)
I used OSB as a client tester to publish messages to my Queue and is quite easy top do. Create a wsdl and xsd to define a schema that you'd like to publish to your queue.

1 - The business Service will publish messages
2 - Proxy Service will expose wsdl contract
3 I have an artifact folder from my wsdl and xsd



If you don't have something to test your queue with yet - use the below code to publish to the queue:

package com.ifc.email.client;

import java.util.Hashtable;

import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;

import javax.jms.QueueSender;
import javax.jms.QueueSession;

import javax.jms.TextMessage;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;


public class JMSSender {
   private static InitialContext ctx = null;
   private static QueueConnectionFactory qcf = null;
   private static QueueConnection qc = null;
   private static QueueSession qsess = null;
   private static Queue q = null;
   private static QueueSender qsndr = null;
   private static TextMessage message = null;
   // NOTE: The next two lines set the name of the Queue Connection Factory
   //       and the Queue that we want to use.
   private static final String QCF_NAME = "jms/EmailConnectionFactory";
   private static final String QUEUE_NAME = "jms/EmailQueue";
   public JMSSender() {
       super();
   }
   public static void sendMessage(String messageText) {
       // create InitialContext
       Hashtable properties = new Hashtable();
       properties.put(Context.INITIAL_CONTEXT_FACTORY,
                      "weblogic.jndi.WLInitialContextFactory");
       // NOTE: The port number of the server is provided in the next line,
       //       followed by the userid and password on the next two lines.
       properties.put(Context.PROVIDER_URL, "t3://localhost:7001");
       properties.put(Context.SECURITY_PRINCIPAL, "weblogic");
       properties.put(Context.SECURITY_CREDENTIALS, "weblogic1");
     
     
       try {
           ctx = new InitialContext(properties);
       } catch (NamingException ne) {
           ne.printStackTrace(System.err);
           System.exit(0);
       }
       System.out.println("Got InitialContext " + ctx.toString());
       // create QueueConnectionFactory
       try {
           qcf = (QueueConnectionFactory)ctx.lookup(QCF_NAME);
       }
       catch (NamingException ne) {
           ne.printStackTrace(System.err);
           System.exit(0);
       }
       System.out.println("Got QueueConnectionFactory " + qcf.toString());
       // create QueueConnection
       try {
           qc = qcf.createQueueConnection();
       }
       catch (JMSException jmse) {
           jmse.printStackTrace(System.err);
           System.exit(0);
       }
       System.out.println("Got QueueConnection " + qc.toString());
       // create QueueSession
       try {
           qsess = qc.createQueueSession(false, 0);
       }
       catch (JMSException jmse) {
           jmse.printStackTrace(System.err);
           System.exit(0);
       }
       System.out.println("Got QueueSession " + qsess.toString());
       // lookup Queue
       try {
           q = (Queue) ctx.lookup(QUEUE_NAME);
       }
       catch (NamingException ne) {
           ne.printStackTrace(System.err);
           System.exit(0);
       }
       System.out.println("Got Queue " + q.toString());
       // create QueueSender
       try {
           qsndr = qsess.createSender(q);
       }
       catch (JMSException jmse) {
           jmse.printStackTrace(System.err);
           System.exit(0);
       }
       System.out.println("Got QueueSender " + qsndr.toString());
       // create TextMessage
       try {
           message = qsess.createTextMessage();
       }
       catch (JMSException jmse) {
           jmse.printStackTrace(System.err);
           System.exit(0);
       }
       System.out.println("Got TextMessage " + message.toString());
       // set message text in TextMessage
       try {
           message.setText(messageText);
       }
       catch (JMSException jmse) {
           jmse.printStackTrace(System.err);
           System.exit(0);
       }
       System.out.println("Set text in TextMessage " + message.toString());
       // send message
       try {
           qsndr.send(message);
       }
       catch (JMSException jmse) {
           jmse.printStackTrace(System.err);
           System.exit(0);
       }
       System.out.println("Sent message ");
       // clean up
       try {
           message = null;
           qsndr.close();
           qsndr = null;
           q = null;
           qsess.close();
           qsess = null;
           qc.close();
           qc = null;
           qcf = null;
           ctx = null;
       }
       catch (JMSException jmse) {
           jmse.printStackTrace(System.err);
       }
       System.out.println("Cleaned up and done.");
   }
   public static void main(String args[]) {
       sendMessage("Hello Justin How are you?");
       sendMessage("hahahahahah?");
   }
}

Friday 30 August 2013

Dynamically write information with File/FTP Adapter using BPEL

I came across this today on OTN Community Forum:

Basically this user wanted to dynamically create folders by using the File Adapter and was asking if BPEL could do it. After I tried it could not, but the following work around worked for me.


Create the different Year&Month folders on your destination from Jan to Dec:
201301
201302
201303
201304
201305
201306
201307
201308
201309
201310
201311
201312
(You can actually create as many as you want going to 2090 if you want... 

Add the below config to your JCA File:

<adapter-config name="FW" adapter="File Adapter" wsdlLocation="FW.wsdl" xmlns="http://platform.integration.oracle/blocks/adapter/fw/metadata">

  <connection-factory location="eis/FileAdapter"/>
  <endpoint-interaction portType="Write_ptt" operation="Write">
    <interaction-spec className="oracle.tip.adapter.file.outbound.FileInteractionSpec">
      <property name="PhysicalDirectory" value="C:\Archive"/>
      <property name="Append" value="false"/>
      <property name="FileNamingConvention" value="%yyyy.MM%\filename"/>
      <property name="NumberMessages" value="1"/>
    </interaction-spec>
  </endpoint-interaction>
</adapter-config>

This will allow the files to be dynamically created in the correct directories.