com.hazelcast.simulator.protocol.connector.WorkerConnector.java Source code

Java tutorial

Introduction

Here is the source code for com.hazelcast.simulator.protocol.connector.WorkerConnector.java

Source

/*
 * Copyright (c) 2008-2015, Hazelcast, Inc. All Rights Reserved.
 *
 * 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 com.hazelcast.simulator.protocol.connector;

import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.simulator.protocol.core.ConnectionManager;
import com.hazelcast.simulator.protocol.core.ResponseFuture;
import com.hazelcast.simulator.protocol.core.SimulatorAddress;
import com.hazelcast.simulator.protocol.core.TestProcessorManager;
import com.hazelcast.simulator.protocol.exception.ExceptionLogger;
import com.hazelcast.simulator.protocol.exception.FileExceptionLogger;
import com.hazelcast.simulator.protocol.exception.RemoteExceptionLogger;
import com.hazelcast.simulator.protocol.handler.ConnectionListenerHandler;
import com.hazelcast.simulator.protocol.handler.ConnectionValidationHandler;
import com.hazelcast.simulator.protocol.handler.ExceptionHandler;
import com.hazelcast.simulator.protocol.handler.MessageConsumeHandler;
import com.hazelcast.simulator.protocol.handler.MessageEncoder;
import com.hazelcast.simulator.protocol.handler.MessageTestConsumeHandler;
import com.hazelcast.simulator.protocol.handler.ResponseEncoder;
import com.hazelcast.simulator.protocol.handler.ResponseHandler;
import com.hazelcast.simulator.protocol.handler.SimulatorFrameDecoder;
import com.hazelcast.simulator.protocol.handler.SimulatorProtocolDecoder;
import com.hazelcast.simulator.protocol.operation.SimulatorOperation;
import com.hazelcast.simulator.protocol.processors.OperationProcessor;
import com.hazelcast.simulator.protocol.processors.TestOperationProcessor;
import com.hazelcast.simulator.protocol.processors.WorkerOperationProcessor;
import com.hazelcast.simulator.worker.Worker;
import com.hazelcast.simulator.worker.WorkerType;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.group.ChannelGroup;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import static com.hazelcast.simulator.protocol.core.AddressLevel.WORKER;
import static com.hazelcast.simulator.protocol.exception.ExceptionType.WORKER_EXCEPTION;

/**
 * Connector which listens for incoming Simulator Agent connections and manages Simulator Test instances.
 */
public class WorkerConnector extends AbstractServerConnector {

    private final OperationProcessor processor;

    private final SimulatorAddress localAddress;
    private final int addressIndex;

    private final ConnectionManager connectionManager;
    private final TestProcessorManager testProcessorManager;
    private final ConcurrentMap<String, ResponseFuture> futureMap;

    WorkerConnector(ConcurrentMap<String, ResponseFuture> futureMap, SimulatorAddress localAddress, int port,
            boolean useRemoteLogger, WorkerType type, HazelcastInstance hazelcastInstance, Worker worker,
            ConnectionManager connectionManager) {
        super(futureMap, localAddress, port);

        ExceptionLogger exceptionLogger = createExceptionLogger(localAddress, useRemoteLogger);
        this.processor = new WorkerOperationProcessor(exceptionLogger, type, hazelcastInstance, worker,
                localAddress);

        this.localAddress = localAddress;
        this.addressIndex = localAddress.getAddressIndex();

        this.connectionManager = connectionManager;
        this.testProcessorManager = new TestProcessorManager(localAddress);
        this.futureMap = futureMap;
    }

    @Override
    void configureServerPipeline(ChannelPipeline pipeline, ServerConnector serverConnector) {
        pipeline.addLast("connectionValidationHandler", new ConnectionValidationHandler());
        pipeline.addLast("connectionListenerHandler", new ConnectionListenerHandler(connectionManager));
        pipeline.addLast("responseEncoder", new ResponseEncoder(localAddress));
        pipeline.addLast("messageEncoder", new MessageEncoder(localAddress, localAddress.getParent()));
        pipeline.addLast("frameDecoder", new SimulatorFrameDecoder());
        pipeline.addLast("protocolDecoder", new SimulatorProtocolDecoder(localAddress));
        pipeline.addLast("messageConsumeHandler", new MessageConsumeHandler(localAddress, processor));
        pipeline.addLast("testProtocolDecoder", new SimulatorProtocolDecoder(localAddress.getChild(0)));
        pipeline.addLast("testMessageConsumeHandler",
                new MessageTestConsumeHandler(testProcessorManager, localAddress));
        pipeline.addLast("responseHandler",
                new ResponseHandler(localAddress, localAddress.getParent(), futureMap, addressIndex));
        pipeline.addLast("exceptionHandler", new ExceptionHandler(serverConnector));
    }

    @Override
    void connectorShutdown() {
        processor.shutdown();
    }

    @Override
    ChannelGroup getChannelGroup() {
        connectionManager.waitForAtLeastOneChannel();
        return connectionManager.getChannels();
    }

    /**
     * Creates a {@link WorkerConnector} instance.
     *
     * @param parentAddressIndex the index of the parent Simulator Agent
     * @param addressIndex       the index of this Simulator Worker
     * @param port               the port for incoming connections
     * @param type               the {@link WorkerType} of this Simulator Worker
     * @param hazelcastInstance  the {@link HazelcastInstance} for this Simulator Worker
     * @param worker             the {@link Worker} instance of this Simulator Worker
     */
    public static WorkerConnector createInstance(int parentAddressIndex, int addressIndex, int port,
            WorkerType type, HazelcastInstance hazelcastInstance, Worker worker) {
        return createInstance(parentAddressIndex, addressIndex, port, type, hazelcastInstance, worker, false);
    }

    /**
     * Creates a {@link WorkerConnector} instance.
     *
     * @param parentAddressIndex the index of the parent Simulator Agent
     * @param addressIndex       the index of this Simulator Worker
     * @param port               the port for incoming connections
     * @param type               the {@link WorkerType} of this Simulator Worker
     * @param hazelcastInstance  the {@link HazelcastInstance} for this Simulator Worker
     * @param worker             the {@link Worker} instance of this Simulator Worker
     * @param useRemoteLogger    determines if the {@link RemoteExceptionLogger} or {@link FileExceptionLogger} should be used
     */
    public static WorkerConnector createInstance(int parentAddressIndex, int addressIndex, int port,
            WorkerType type, HazelcastInstance hazelcastInstance, Worker worker, boolean useRemoteLogger) {
        ConcurrentMap<String, ResponseFuture> futureMap = new ConcurrentHashMap<String, ResponseFuture>();
        SimulatorAddress localAddress = new SimulatorAddress(WORKER, parentAddressIndex, addressIndex, 0);
        ConnectionManager connectionManager = new ConnectionManager();

        return new WorkerConnector(futureMap, localAddress, port, useRemoteLogger, type, hazelcastInstance, worker,
                connectionManager);
    }

    /**
     * Gets a Simulator Test.
     *
     * @param testIndex the index of the Simulator Test
     * @return the {@link TestOperationProcessor} which processes incoming
     * {@link com.hazelcast.simulator.protocol.operation.SimulatorOperation} for this test
     */
    public TestOperationProcessor getTest(int testIndex) {
        return testProcessorManager.getTest(testIndex);
    }

    /**
     * Adds a Simulator Test.
     *
     * @param testIndex the index of the Simulator Test
     * @param processor the {@link TestOperationProcessor} which processes incoming
     *                  {@link com.hazelcast.simulator.protocol.operation.SimulatorOperation} for this test
     */
    public void addTest(int testIndex, TestOperationProcessor processor) {
        testProcessorManager.addTest(testIndex, processor);
    }

    /**
     * Removes a Simulator Test.
     *
     * @param testIndex the index of the remote Simulator Test
     */
    public void removeTest(int testIndex) {
        testProcessorManager.removeTest(testIndex);
    }

    /**
     * Submits a {@link SimulatorOperation} to a {@link SimulatorAddress}.
     *
     * The {@link SimulatorOperation} is put on a queue. The {@link com.hazelcast.simulator.protocol.core.Response} is not
     * returned.
     *
     * @param testAddress the {@link SimulatorAddress} of the sending test
     * @param destination the {@link SimulatorAddress} of the destination
     * @param operation   the {@link SimulatorOperation} to send
     * @return a {@link ResponseFuture} to wait for the result of the operation
     */
    public ResponseFuture submitFromTest(SimulatorAddress testAddress, SimulatorAddress destination,
            SimulatorOperation operation) {
        return submit(testAddress, destination, operation);
    }

    /**
     * Returns the size of the internal message queue used by {@link #submit(SimulatorAddress, SimulatorOperation)}.
     *
     * @return the message queue size
     */
    public int getMessageQueueSize() {
        return super.getMessageQueueSize();
    }

    public OperationProcessor getProcessor() {
        return processor;
    }

    private ExceptionLogger createExceptionLogger(SimulatorAddress localAddress, boolean useRemoteLogger) {
        if (useRemoteLogger) {
            return new RemoteExceptionLogger(localAddress, WORKER_EXCEPTION, this);
        } else {
            return new FileExceptionLogger(localAddress, WORKER_EXCEPTION);
        }
    }
}