org.bpmscript.integration.internal.memory.MemoryMessageBus.java Source code

Java tutorial

Introduction

Here is the source code for org.bpmscript.integration.internal.memory.MemoryMessageBus.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.bpmscript.integration.internal.memory;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import org.bpmscript.integration.IMessageBus;
import org.bpmscript.integration.internal.IInternalMessage;
import org.bpmscript.integration.internal.IMessageReceiver;
import org.bpmscript.integration.internal.IMessageSender;
import org.bpmscript.integration.internal.IMutableAddressRegistry;
import org.bpmscript.integration.internal.NoopMessageSender;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

/**
 * An in memory message bus
 */
public class MemoryMessageBus implements InitializingBean, DisposableBean, IMessageBus, BeanNameAware {

    private final transient org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
            .getLog(getClass());

    private BlockingQueue<Object[]> queue = new LinkedBlockingQueue<Object[]>();
    private IMutableAddressRegistry addressRegistry = null;
    private AtomicBoolean running = new AtomicBoolean(false);
    private long timeoutMillis = 100;
    private int threadCount = 10;
    private Executor executor = Executors.newFixedThreadPool(threadCount);
    private IMessageSender auditSender = new NoopMessageSender();
    private IMessageSender messageSender;
    private String name;

    /**
     * Send a message to an address
     */
    public void send(String address, IInternalMessage internalMessage) {
        if (log.isDebugEnabled()) {
            log.debug("bus received message " + internalMessage + " for " + address);
        }
        if (address == null) {
            log.warn("address is null for message " + internalMessage);
        }
        if (internalMessage == null) {
            log.warn("message is null for address " + address);
        }

        int indexOfColon = address.indexOf(":");
        if (indexOfColon > 0) {
            String namespace = address.substring(0, indexOfColon);
            if (namespace != name) {
                messageSender.send(address, internalMessage);
            } else {
                auditSender.send(address, internalMessage);
                queue.add(new Object[] { address.substring(indexOfColon + 1), internalMessage });
            }
        } else {
            auditSender.send(name + ":" + address, internalMessage);
            queue.add(new Object[] { address, internalMessage });
        }
    }

    /**
     * Starts up the bus
     */
    public void afterPropertiesSet() throws Exception {
        for (int i = 0; i < threadCount; i++) {
            executor.execute(new Runnable() {

                public void run() {
                    running.set(true);
                    while (running.get()) {
                        try {
                            Object[] addressAndMessage;
                            addressAndMessage = queue.poll(timeoutMillis, TimeUnit.MILLISECONDS);
                            if (addressAndMessage != null) {
                                String address = (String) addressAndMessage[0];
                                // lookup endpoint and send a message to it...
                                IMessageReceiver receiver = addressRegistry.lookup(address);
                                IInternalMessage internalMessage = (IInternalMessage) addressAndMessage[1];
                                if (receiver == null) {
                                    String errorMessage = "no receiver for address " + address
                                            + " not sending message " + internalMessage;
                                    log.error(errorMessage, new Throwable(errorMessage));
                                } else {
                                    if (log.isDebugEnabled()) {
                                        log.debug("bus sending message " + internalMessage + " to " + address);
                                    }
                                    receiver.onMessage(internalMessage);
                                }
                            }
                        } catch (InterruptedException e) {
                            log.warn(e, e);
                        }
                    }
                }

            });
        }
    }

    /**
     * Stops the bus
     */
    public void destroy() throws Exception {
        running.set(false);
    }

    public void setAddressRegistry(IMutableAddressRegistry addressRegistry) {
        this.addressRegistry = addressRegistry;
    }

    public void setTimeoutMillis(long timeoutMillis) {
        this.timeoutMillis = timeoutMillis;
    }

    public void setExecutor(Executor executor) {
        this.executor = executor;
    }

    public void setAuditSender(IMessageSender auditSender) {
        this.auditSender = auditSender;
    }

    public IMessageReceiver lookup(String address) {
        return addressRegistry.lookup(address);
    }

    public void register(String address, IMessageReceiver receiver) {
        addressRegistry.register(address, receiver);
    }

    public void setMessageSender(IMessageSender messageSender) {
        this.messageSender = messageSender;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    /**
     * @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String)
     */
    public void setBeanName(String name) {
        this.name = name;
    }

}