CallMeBack.java

package com.infor.cloverleaf.javadriver.samples.callback;
...
public class CallMeBack extends ToCloverleafLink {
    private boolean runningB = true;
    private Thread startThread = null;
    @Override
    public void doStart(String userS) throws Exception{
        int idx = 0;
        // debugger test for exception handling.  To use this, set a wait in the driver control ini file, start the process, attach debugger
        if (idx == 1) throw new Exception("debug test");
        // this process just starts up and runs forever kicking off messages every 10 seconds
        startThread = Thread.currentThread();
        // create a "red" and "blue" callback handler
        CallbackInterface redCallback = new CallbackInterface() {
            public List<ToCloverleafMessage> doCallback(FromCloverleafMessage fromCloverleafMessage) throws BadDataException, RetryException {
                System.out.println("RED callback executed at '" + (new Date()).toString() + "'and received message: " +
                        fromCloverleafMessage.getMessage());
                return null;
            }
        };
        CallbackInterface blueCallback = new CallbackInterface() {
            public List<ToCloverleafMessage> doCallback(FromCloverleafMessage fromCloverleafMessage) throws BadDataException, RetryException {
                System.out.println("BLUE callback executed at '" + (new Date()).toString() + "'and received message: " +
                        fromCloverleafMessage.getMessage());
                return null;
            }
        };
        // now register them as callback handlers
        registerACallbackHandler("red", redCallback);
        registerACallbackHandler("blue", blueCallback);
        // loop and send out messages
        while(runningB){
            // send the message to cloverleaf, don't use recoverydb since this is just for testing
            try{
                Thread.sleep(10000);
                // create a message to send
                idx++;
                // copy the int for the callback to remember (to demonstrate unique callback classes)
                // A more realistic example of this need is in the CJDRequestServer where the callback
                // has to remember the HttpResponse object to write back on (a stream essentially)
                final int callbackInt = idx;
                // create a unique callback to invoke for just this one message
                CallbackInterface callback = new CallbackInterface() {
                    public List<ToCloverleafMessage> doCallback(FromCloverleafMessage fromCloverleafMessage) throws BadDataException, RetryException {
                        System.out.println("java callback " + callbackInt + " executed at '" + (new Date()).toString() + "'and received message: " +
                                fromCloverleafMessage.getMessage());
                        return null;
                    }
                };
                ToCloverleafMessage toCloverleafMessage = new ToCloverleafMessage(null, "", MessageTypeEnum.DATA, null, null, "callmeback message " + idx + " at " + (new Date()).toString());
                sendToCloverleafWithUniqueCallback(callback, true, toCloverleafMessage);
                /* now send a message to RED or BLUE registered callbacks, depending if idx is even or odd
                 * Whereas the unique callback can store any java object for later processing specific to the
                 * individual message (which is appropriate for stream and other temporary object handling), this
                 * mechanism should be used when processes could be long running or it is
                 * required that the messages should survive the thread being shut down and started
                 * up again later.  For example, an asynchronous SOAP server could use something like this.
                 * You could add the message id and callback url into the driver control and extract that
                 * info in the callback handler for processing.  Different services may need different
                 * handling which is why you might want to register different handlers and use them as needed.
                 * As long as the handlers are registered again when the server starts up after a shutdown, no
                 * messages will be lost.
                 */
                if (idx % 2 == 0){
                    toCloverleafMessage = new ToCloverleafMessage(null, "", MessageTypeEnum.DATA, null, null, "RED message " + idx + " at " + (new Date()).toString());
                    sendToCloverleafWithRegisteredCallback("red", true, toCloverleafMessage);
                }else{
                    toCloverleafMessage = new ToCloverleafMessage(null, "", MessageTypeEnum.DATA, null, null, "BLUE message " + idx + " at " + (new Date()).toString());
                    sendToCloverleafWithRegisteredCallback("blue", true, toCloverleafMessage);
                }
                /* finally, send a message with automated callback handling.  This demonstrates
                 * a manual callback where the callback is processed on another thread.  The usage
                 * scenarios are similar to the registered callbacks but this lets you use another
                 * thread to handle the callbacks.  You need to pass all the information the callback
                 * handler will need in the driver control or message body so your thread on the other
                 * side will know what to do with the message.  Using the asynchronous soap server as
                 * an example again, you would pass the message id and the callback url in driver control
                 * here, then pull them out in the callback handling thread and use it to execute your
                 * response message to the waiting client.
                 * Technically the code here has no idea a "callback" type of scenario is even in play,
                 * as this thread just knows that it's dumping messages into the Cloverleaf engine.  Your
                 * code will just process the driver control data appropriately to make it happen.  Here
                 * we're just making up some arbitrary driver control data for the other side to use.  The
                 * bounce thread is just looking for this data in the driver control to know where to send
                 */
                toCloverleafMessage = new ToCloverleafMessage(null, "MYCALLBACK " + idx + " messageid " + idx*17 + " url http://www.example.com:8080/callbackserver", MessageTypeEnum.DATA, null, null, "BLUE message " + callbackInt + " at " + (new Date()).toString());
                sendMessagesToCloverleaf(true, toCloverleafMessage);
            }catch (Exception e){
                System.out.println("caught exception trying to sendToCloverleafWithCallback: " + e.getLocalizedMessage());
            }
        }
    }