Package com.espertech.esper.dataflow.core

Source Code of com.espertech.esper.dataflow.core.RealizationFactoryInterface

/*
* *************************************************************************************
*  Copyright (C) 2008 EsperTech, Inc. All rights reserved.                            *
*  http://esper.codehaus.org                                                          *
*  http://www.espertech.com                                                           *
*  ---------------------------------------------------------------------------------- *
*  The software in this package is published under the terms of the GPL license       *
*  a copy of which has been included with this distribution in the license.txt file.  *
* *************************************************************************************
*/

package com.espertech.esper.dataflow.core;

import com.espertech.esper.client.annotation.AuditEnum;
import com.espertech.esper.client.dataflow.EPDataFlowExceptionHandler;
import com.espertech.esper.client.dataflow.EPDataFlowInstantiationOptions;
import com.espertech.esper.client.dataflow.EPDataFlowSignal;
import com.espertech.esper.core.service.EPServicesContext;
import com.espertech.esper.core.service.StatementContext;
import com.espertech.esper.dataflow.annotations.DataFlowContext;
import com.espertech.esper.dataflow.interfaces.EPDataFlowEmitter;
import com.espertech.esper.dataflow.util.*;
import com.espertech.esper.util.JavaClassHelper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.*;

public class RealizationFactoryInterface {

    private static final Log log = LogFactory.getLog(RealizationFactoryInterface.class);

    public static DataflowStartDesc realize(String dataFlowName,
                                         Map<Integer, Object> operators,
                                         Map<Integer, OperatorMetadataDescriptor> operatorMetadata,
                                         Set<Integer> operatorBuildOrder,
                                         List<LogicalChannelBinding> bindings,
                                         DataFlowSignalManager dataFlowSignalManager,
                                         EPDataFlowInstantiationOptions options,
                                         EPServicesContext services,
                                         StatementContext statementContext) {


        // First pass: inject runtime context
        Map<Integer, EPDataFlowEmitter> runtimeContexts = new HashMap<Integer, EPDataFlowEmitter>();
        OperatorStatisticsProvider statisticsProvider = null;
        if (options.isOperatorStatistics()) {
            statisticsProvider = new OperatorStatisticsProvider(operatorMetadata);
        }

        boolean audit = AuditEnum.DATAFLOW_OP.getAudit(statementContext.getAnnotations()) != null;
        for (int producerOpNum : operatorBuildOrder) {
            String operatorPrettyPrint = operatorMetadata.get(producerOpNum).getOperatorPrettyPrint();
            if (log.isDebugEnabled()) {
                log.debug("Generating runtime context for " + operatorPrettyPrint);
            }
           
            // determine the number of output streams
            Object producingOp = operators.get(producerOpNum);
            int numOutputStreams = operatorMetadata.get(producerOpNum).getOperatorSpec().getOutput().getItems().size();
            List<ObjectBindingPair>[] targets = getOperatorConsumersPerStream(numOutputStreams, producerOpNum, operators, operatorMetadata, bindings);

            EPDataFlowEmitter runtimeContext = generateRuntimeContext(statementContext.getEngineURI(), statementContext.getStatementName(), audit, dataFlowName, producerOpNum, operatorPrettyPrint, dataFlowSignalManager, targets, options);

            if (options.isOperatorStatistics()) {
                runtimeContext = new EPDataFlowEmitterWrapperWStatistics(runtimeContext, producerOpNum, statisticsProvider, options.isCpuStatistics());
            }

            JavaClassHelper.setFieldForAnnotation(producingOp, DataFlowContext.class, runtimeContext);
            runtimeContexts.put(producerOpNum, runtimeContext);
        }

        // Second pass: hook punctuation such that it gets forwarded
        for (int producerOpNum : operatorBuildOrder) {
            String operatorPrettyPrint = operatorMetadata.get(producerOpNum).getOperatorPrettyPrint();
            if (log.isDebugEnabled()) {
                log.debug("Handling signals for " + operatorPrettyPrint);
            }

            // determine consumers that receive punctuation
            Set<Integer> consumingOperatorsWithPunctuation = new HashSet<Integer>();
            for (LogicalChannelBinding binding : bindings) {
                if (!binding.getLogicalChannel().getOutputPort().isHasPunctuation() || binding.getLogicalChannel().getOutputPort().getProducingOpNum() != producerOpNum) {
                    continue;
                }
                consumingOperatorsWithPunctuation.add(binding.getLogicalChannel().getConsumingOpNum());
            }

            // hook up a listener for each
            for (int consumerPunc : consumingOperatorsWithPunctuation) {
                final EPDataFlowEmitter context = runtimeContexts.get(consumerPunc);
                if (context == null) {
                    continue;
                }
                dataFlowSignalManager.addSignalListener(producerOpNum, new DataFlowSignalListener() {
                    public void processSignal(EPDataFlowSignal signal) {
                        context.submitSignal(signal);
                    }
                });
            }
        }

        return new DataflowStartDesc(statisticsProvider);
    }

    private static List<ObjectBindingPair>[] getOperatorConsumersPerStream(int numOutputStreams, int producingOperator, Map<Integer, Object> operators, Map<Integer, OperatorMetadataDescriptor> operatorMetadata, List<LogicalChannelBinding> bindings) {
        List<LogicalChannelBinding> channelsForProducer = LogicalChannelUtil.getBindingsConsuming(producingOperator, bindings);
        if (channelsForProducer.isEmpty()) {
            return null;
        }

        List<ObjectBindingPair>[] submitTargets = new List[numOutputStreams];
        for (int i = 0; i < numOutputStreams; i++) {
            submitTargets[i] = new ArrayList<ObjectBindingPair>();
        }
       
        for (LogicalChannelBinding binding : channelsForProducer) {
            int consumingOp = binding.getLogicalChannel().getConsumingOpNum();
            Object operator = operators.get(consumingOp);
            int producingStreamNum = binding.getLogicalChannel().getOutputPort().getStreamNumber();
            List<ObjectBindingPair> pairs = submitTargets[producingStreamNum];
            OperatorMetadataDescriptor metadata = operatorMetadata.get(consumingOp);
            pairs.add(new ObjectBindingPair(operator, metadata.getOperatorPrettyPrint(), binding));
        }
        return submitTargets;
    }

    private static SignalHandler getSignalHandler(int producerNum, Object target, LogicalChannelBindingMethodDesc consumingSignalBindingDesc) {
        if (consumingSignalBindingDesc == null) {
            return SignalHandlerDefault.INSTANCE;
        }
        else {
            if (consumingSignalBindingDesc.getBindingType() instanceof LogicalChannelBindingTypePassAlong) {
                return new SignalHandlerDefaultWInvoke(target, consumingSignalBindingDesc.getMethod());
            }
            else if (consumingSignalBindingDesc.getBindingType() instanceof LogicalChannelBindingTypePassAlongWStream) {
                LogicalChannelBindingTypePassAlongWStream streamInfo = (LogicalChannelBindingTypePassAlongWStream) consumingSignalBindingDesc.getBindingType();
                return new SignalHandlerDefaultWInvokeStream(target, consumingSignalBindingDesc.getMethod(), streamInfo.getStreamNum());
            }
            else {
                throw new IllegalStateException("Unrecognized signal binding: " + consumingSignalBindingDesc.getBindingType());
            }
        }
    }

    private static SubmitHandler getSubmitHandler(String engineURI, String statementName, boolean audit, String dataflowName, int producerOpNum, String operatorPrettyPrint, DataFlowSignalManager dataFlowSignalManager, ObjectBindingPair target, EPDataFlowExceptionHandler optionalExceptionHandler) {
        SignalHandler signalHandler = getSignalHandler(producerOpNum, target.getTarget(), target.getBinding().getConsumingSignalBindingDesc());

        int receivingOpNum = target.getBinding().getLogicalChannel().getConsumingOpNum();
        String receivingOpPretty = target.getBinding().getLogicalChannel().getConsumingOpPrettyPrint();
        String receivingOpName = target.getBinding().getLogicalChannel().getConsumingOpName();
        EPDataFlowEmitterExceptionHandler exceptionHandler = new EPDataFlowEmitterExceptionHandler(engineURI, statementName, audit, dataflowName, receivingOpName, receivingOpNum, receivingOpPretty, optionalExceptionHandler);

        LogicalChannelBindingType bindingType = target.getBinding().getConsumingBindingDesc().getBindingType();
        if (bindingType instanceof LogicalChannelBindingTypePassAlong) {
            return new EPDataFlowEmitter1Stream1TargetPassAlong(producerOpNum, dataFlowSignalManager, signalHandler, exceptionHandler, target);
        }
        else if (bindingType instanceof LogicalChannelBindingTypePassAlongWStream) {
            LogicalChannelBindingTypePassAlongWStream type = (LogicalChannelBindingTypePassAlongWStream) bindingType;
            return new EPDataFlowEmitter1Stream1TargetPassAlongWStream(producerOpNum, dataFlowSignalManager, signalHandler, exceptionHandler, target, type.getStreamNum());
        }
        else if (bindingType instanceof LogicalChannelBindingTypeUnwind) {
            return new EPDataFlowEmitter1Stream1TargetUnwind(producerOpNum, dataFlowSignalManager, signalHandler, exceptionHandler, target);
        }
        else {
            throw new UnsupportedOperationException("TODO");
        }
    }

    private static EPDataFlowEmitter generateRuntimeContext(String engineURI,
                                                            String statementName,
                                                            boolean audit,
                                                            String dataflowName,
                                                            int producerOpNum,
                                                            String operatorPrettyPrint,
                                                            DataFlowSignalManager dataFlowSignalManager,
                                                            List<ObjectBindingPair>[] targetsPerStream,
                                                            EPDataFlowInstantiationOptions options) {
        // handle no targets
        if (targetsPerStream == null) {
            return new EPDataFlowEmitterNoTarget(producerOpNum, dataFlowSignalManager);
        }

        // handle single-stream case
        if (targetsPerStream.length == 1) {
            List<ObjectBindingPair> targets = targetsPerStream[0];

            // handle single-stream single target case
            if (targets.size() == 1) {
                ObjectBindingPair target = targets.get(0);
                return getSubmitHandler(engineURI, statementName, audit, dataflowName, producerOpNum, operatorPrettyPrint, dataFlowSignalManager, target, options.getExceptionHandler());
            }

            SubmitHandler[] handlers = new SubmitHandler[targets.size()];
            for (int i = 0; i < handlers.length; i++) {
                handlers[i] = getSubmitHandler(engineURI, statementName, audit, dataflowName, producerOpNum, operatorPrettyPrint, dataFlowSignalManager, targets.get(i), options.getExceptionHandler());
            }
            return new EPDataFlowEmitter1StreamNTarget(producerOpNum, dataFlowSignalManager, handlers);
        }
        // handle multi-stream case
        else {
            SubmitHandler[][] handlersPerStream = new SubmitHandler[targetsPerStream.length][];
            for (int streamNum = 0; streamNum < targetsPerStream.length; streamNum++) {
                SubmitHandler[] handlers = new SubmitHandler[targetsPerStream[streamNum].size()];
                handlersPerStream[streamNum] = handlers;
                for (int i = 0; i < handlers.length; i++) {
                    handlers[i] = getSubmitHandler(engineURI, statementName, audit, dataflowName, producerOpNum, operatorPrettyPrint, dataFlowSignalManager, targetsPerStream[streamNum].get(i), options.getExceptionHandler());
                }
            }
            return new EPDataFlowEmitterNStreamNTarget(producerOpNum, dataFlowSignalManager, handlersPerStream);
        }
    }
}
TOP

Related Classes of com.espertech.esper.dataflow.core.RealizationFactoryInterface

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.