Package org.axonframework.commandhandling.distributed.jgroups

Source Code of org.axonframework.commandhandling.distributed.jgroups.JGroupsConnectorFactoryBean

/*
* Copyright (c) 2010-2014. Axon Framework
*
* Licensed 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.axonframework.commandhandling.distributed.jgroups;

import org.axonframework.commandhandling.CommandBus;
import org.axonframework.commandhandling.CommandHandlerInterceptor;
import org.axonframework.commandhandling.SimpleCommandBus;
import org.axonframework.serializer.Serializer;
import org.jgroups.JChannel;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.SmartLifecycle;

import java.util.List;
import java.util.concurrent.TimeUnit;

/**
* Spring Factory bean that creates a JGroupsConnector and starts it when the application context is started. This bean
* must be defined as a top-level bean.
*
* @author Allard Buijze
* @since 2.0
*/
public class JGroupsConnectorFactoryBean implements FactoryBean, InitializingBean, SmartLifecycle, BeanNameAware,
        ApplicationContextAware {

    private JGroupsConnector connector;
    private Serializer serializer;
    private String configuration = "tcp_mcast.xml";
    private String clusterName;
    private String channelName;
    private CommandBus localSegment;
    private int loadFactor = 100;
    private JChannel channel;
    private int phase = Integer.MAX_VALUE;
    private String beanName;
    private ApplicationContext applicationContext;
    private List<CommandHandlerInterceptor> interceptors;
    private long joinTimeout = -1;

    @Override
    public Object getObject() throws Exception {
        return connector;
    }

    @Override
    public Class<?> getObjectType() {
        return JGroupsConnector.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (localSegment == null) {
            SimpleCommandBus bus = new SimpleCommandBus();
            if (interceptors != null && !interceptors.isEmpty()) {
                bus.setHandlerInterceptors(interceptors);
            }
            localSegment = bus;
        }
        if (serializer == null) {
            serializer = applicationContext.getBean(Serializer.class);
        }
        if (clusterName == null) {
            clusterName = beanName;
        }
        channel = new JChannel(configuration);
        if (channelName != null) {
            channel.setName(channelName);
        }
        connector = new JGroupsConnector(channel, clusterName, localSegment, serializer);
    }

    /**
     * Sets the serializer used to serialize events before they are dispatched to the destination. All members
     * connected to the same channel must use compatible serializers.
     * <p/>
     * Default to an autowired Serializer.
     *
     * @param serializer the serializer to serialize commands with
     */
    public void setSerializer(Serializer serializer) {
        this.serializer = serializer;
    }

    /**
     * Sets the JGroups configuration file to load. Defaults to configuration using TCP with multicast discovery
     * (tcp_mcast.xml).
     *
     * @param configuration the JGroups configuration file
     */
    public void setConfiguration(String configuration) {
        this.configuration = configuration;
    }

    /**
     * Sets the name of the cluster to subscribe to. The Connector will only connect to other instances with the same
     * cluster name. Defaults to the bean name.
     *
     * @param clusterName The name of the cluster to connect to
     */
    public void setClusterName(String clusterName) {
        this.clusterName = clusterName;
    }

    /**
     * Optionally sets the logical channel name of the channel. If not provided JGroups will generate a default name.
     * <p/>
     * Note that each member of a cluster should have a unique channel name.
     *
     * @param channelName The logical name to give to the channel
     */
    public void setChannelName(String channelName) {
        this.channelName = channelName;
    }

    /**
     * Sets the number of milliseconds to wait for this member to join the group. Setting this to a non-negative number
     * will cause the start() method to block for at most the given number of milliseconds. After that timeout,
     * attempts to join the cluster will be performed on the background.
     * <p/>
     * Setting a negative value will cause the {@link #start()} method to wait until the member joined the cluster.
     * <p/>
     * Defaults to -1, which causes the {@link #start()} to wait indefinitely, until the member has joined the cluster.
     *
     * @param joinTimeout The number of milliseconds to wait for the member to join the cluster
     */
    public void setJoinTimeout(long joinTimeout) {
        this.joinTimeout = joinTimeout;
    }

    /**
     * Sets the CommandBus instance on which local commands must be dispatched. Defaults to a SimpleCommandBus.
     *
     * @param localSegment the CommandBus instance to dispatch local messages on
     */
    public void setLocalSegment(CommandBus localSegment) {
        this.localSegment = localSegment;
    }

    /**
     * Sets the interceptor to use in the default local segment (a SimpleCommandBus). When providing a custom local
     * segment ({@link #setLocalSegment(org.axonframework.commandhandling.CommandBus)}), this configuration is ignored.
     *
     * @param interceptors the list of interceptors (in order) for the local segment
     */
    public void setInterceptors(List<CommandHandlerInterceptor> interceptors) {
        this.interceptors = interceptors;
    }

    /**
     * Sets the load factor for this instance of the Distributed Command Bus. This factor described the relative number
     * of Command messages this instance will handle. Defaults to 100.
     *
     * @param loadFactor The load factor for this instance
     */
    public void setLoadFactor(int loadFactor) {
        this.loadFactor = loadFactor;
    }

    @Override
    public void start() {
        try {
            connector.connect(loadFactor);
            if (joinTimeout >= 0) {
                connector.awaitJoined(joinTimeout, TimeUnit.MILLISECONDS);
            } else {
                connector.awaitJoined();
            }
        } catch (Exception e) {
            throw new ConnectionFailedException("Could not start JGroups Connector", e);
        }
    }

    @Override
    public void stop() {
        channel.close();
    }

    @Override
    public boolean isRunning() {
        return channel.isConnected();
    }

    @Override
    public boolean isAutoStartup() {
        return true;
    }

    @Override
    public void stop(Runnable callback) {
        channel.close();
        callback.run();
    }

    @Override
    public int getPhase() {
        // the connector must start last. All other components must be started before participating in the
        // distributed command bus
        return phase;
    }

    /**
     * Sets the phase in which this bean must be started. Defaults to {@code Integer.MAX_VALUE}, which ensures the
     * Connector is started when other beans have been initialized.
     *
     * @param phase the phase in which the JGroups connector must be started.
     * @see SmartLifecycle
     */
    public void setPhase(int phase) {
        this.phase = phase;
    }

    @Override
    public void setBeanName(String name) {
        this.beanName = name;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
TOP

Related Classes of org.axonframework.commandhandling.distributed.jgroups.JGroupsConnectorFactoryBean

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.