/**
* Copyright 2015 Otto (GmbH & Co KG)
*
* 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.ottogroup.bi.spqr.pipeline;
import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import com.ottogroup.bi.spqr.metrics.MetricsHandler;
import com.ottogroup.bi.spqr.pipeline.component.MicroPipelineComponent;
import com.ottogroup.bi.spqr.pipeline.component.emitter.EmitterRuntimeEnvironment;
import com.ottogroup.bi.spqr.pipeline.component.operator.DelayedResponseOperatorRuntimeEnvironment;
import com.ottogroup.bi.spqr.pipeline.component.operator.DirectResponseOperatorRuntimeEnvironment;
import com.ottogroup.bi.spqr.pipeline.component.source.SourceRuntimeEnvironment;
import com.ottogroup.bi.spqr.pipeline.queue.StreamingMessageQueue;
/**
* Provides a runtime container for {@link MicroPipelineComponent} instances interconnected
* through {@link StreamingMessageQueue} instances.
* @author mnxfst
* @since Mar 5, 2015
*/
public class MicroPipeline {
private static final Logger logger = Logger.getLogger(MicroPipeline.class);
/** unique pipeline identifier - must be unique within the whole cluster */
private final String id;
/** configuration */
private final MicroPipelineConfiguration configuration;
/** references to source runtime environments */
private final Map<String, SourceRuntimeEnvironment> sources = new HashMap<>();
/** references to direct response operator runtime environments */
private final Map<String, DirectResponseOperatorRuntimeEnvironment> directResponseOperators = new HashMap<>();
/** references to delayed response operator runtime environments */
private final Map<String, DelayedResponseOperatorRuntimeEnvironment> delayedResponseOperators = new HashMap<>();
/** references to emitter runtime environments */
private final Map<String, EmitterRuntimeEnvironment> emitters = new HashMap<>();
/** references to queues interconnecting the components */
private final Map<String, StreamingMessageQueue> queues = new HashMap<>();
/** stats collector */
private MetricsHandler metricsHandler = null;
/**
* Initializes the micro pipeline instance using the provided input
* @param id
* @param configuration
*/
public MicroPipeline(final String id, final MicroPipelineConfiguration configuration) {
this.id = id;
this.configuration = configuration;
}
/**
* Attaches the referenced {@link ComponentMetricsHandler} to this micro pipeline
* @param metricsHandler
*/
public void attachComponentMetricsHandler(final MetricsHandler metricsHandler) {
this.metricsHandler = metricsHandler;
}
/**
* Adds a new {@link SourceRuntimeEnvironment}
* @param id
* @param sourceRuntimeEnvironment
* TODO test
*/
public void addSource(final String id, final SourceRuntimeEnvironment sourceRuntimeEnvironment) {
this.sources.put(id, sourceRuntimeEnvironment);
if(logger.isDebugEnabled())
logger.debug("Source [id="+id+"] successfully attached to pipeline [id="+this.id+"]");
}
/**
* Adds a new {@link DirectResponseOperatorRuntimeEnvironment}
* @param id
* @param operatorRuntimeEnvironment
* TODO test
*/
public void addOperator(final String id, final DirectResponseOperatorRuntimeEnvironment operatorRuntimeEnvironment) {
this.directResponseOperators.put(id, operatorRuntimeEnvironment);
if(logger.isDebugEnabled())
logger.debug("Direct response operator [id="+id+"] successfully attached to pipeline [id="+this.id+"]");
}
/**
* Adds a new {@link DelayedResponseOperatorRuntimeEnvironment}
* @param id
* @param operatorRuntimeEnvironment
* TODO test
*/
public void addOperator(final String id, final DelayedResponseOperatorRuntimeEnvironment operatorRuntimeEnvironment) {
this.delayedResponseOperators.put(id, operatorRuntimeEnvironment);
if(logger.isDebugEnabled())
logger.debug("Delayed response operator [id="+id+"] successfully attached to pipeline [id="+this.id+"]");
}
/**
* Adds a new {@link EmitterRuntimeEnvironment}
* @param id
* @param emitterRuntimeEnvironment
* TODO test
*/
public void addEmitter(final String id, final EmitterRuntimeEnvironment emitterRuntimeEnvironment) {
this.emitters.put(id, emitterRuntimeEnvironment);
if(logger.isDebugEnabled())
logger.debug("Emitter [id="+id+"] successfully attached to pipeline [id="+this.id+"]");
}
/**
* Adds a new {@link StreamingMessageQueue}
* @param id
* @param queue
* TODO test
*/
public void addQueue(final String id, final StreamingMessageQueue queue) {
this.queues.put(id, queue);
if(logger.isDebugEnabled())
logger.debug("Queue [id="+id+"] successfully attached to pipeline [id="+this.id+"]");
}
/**
* Returns the {@link StreamingMessageQueue} referenced by the given id
* @param id
* @return
* TODO test
*/
public StreamingMessageQueue getQueue(final String id) {
return this.queues.get(id);
}
/**
* Returns true in case a {@link StreamingMessageQueue} exists for the given id
* @param id
* @return
* TODO test
*/
public boolean hasQueue(final String id) {
return this.queues.containsKey(id);
}
/**
* Returns true in case any {@link MicroPipelineComponent} exists for the given id
* @param id
* @return
* TODO test
*/
public boolean hasComponent(final String id) {
return (this.sources.containsKey(id) || this.directResponseOperators.containsKey(id) || this.delayedResponseOperators.containsKey(id) || this.emitters.containsKey(id));
}
/**
* Shuts down the micro pipeline by first calling {@link MicroPipelineComponent#shutdown()} followed
* by {@link StreamingMessageQueue#shutdown()}
* TODO test
*/
public void shutdown() {
//////////////////////////////////////////////////////////////////////////////////////////
// shutting down the metrics collector
if(this.metricsHandler != null)
this.metricsHandler.shutdown();
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// shutting down runtime environments: sources, operators, emitters
for(final String srcId : this.sources.keySet()) {
SourceRuntimeEnvironment srcEnv = this.sources.get(srcId);
try {
srcEnv.shutdown();
if(logger.isDebugEnabled())
logger.debug("Source runtime environment shut down [id="+srcId+"]");
} catch(Exception e) {
logger.error("Failed to shut down source runtime environment [id="+srcId+"]. Reason: " + e.getMessage());
}
}
for(final String operatorId : this.directResponseOperators.keySet()) {
DirectResponseOperatorRuntimeEnvironment operatorEnv = this.directResponseOperators.get(operatorId);
try {
operatorEnv.shutdown();
if(logger.isDebugEnabled())
logger.debug("Direct response operator runtime environment shut down [id="+operatorId+"]");
} catch(Exception e) {
logger.error("Failed to shut down direct response operator runtime environment [id="+operatorId+"]. Reason: " + e.getMessage());
}
}
for(final String operatorId : this.delayedResponseOperators.keySet()) {
DelayedResponseOperatorRuntimeEnvironment operatorEnv = this.delayedResponseOperators.get(operatorId);
try {
operatorEnv.shutdown();
if(logger.isDebugEnabled())
logger.debug("Delayed response operator runtime environment shut down [id="+operatorId+"]");
} catch(Exception e) {
logger.error("Failed to shut down delayed response operator runtime environment [id="+operatorId+"]. Reason: " + e.getMessage());
}
}
for(final String emitterId : this.emitters.keySet()) {
EmitterRuntimeEnvironment emitterEnv = this.emitters.get(emitterId);
try {
emitterEnv.shutdown();
if(logger.isDebugEnabled())
logger.debug("Emitter runtime environment shut down [id="+emitterId+"]");
} catch(Exception e) {
logger.error("Failed to shut down emitter runtime environment [id="+emitterId+"]. Reason: " + e.getMessage());
}
}
//
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// shutting down queues
for(String queueId : this.queues.keySet()) {
StreamingMessageQueue queue = this.queues.get(queueId);
try {
queue.shutdown();
if(logger.isDebugEnabled())
logger.debug("Queue shut down [id="+queueId+"]");
} catch(Exception e) {
logger.error("Failed to shut down queue [id="+queueId+"]. Reason: " + e.getMessage());
}
}
//
//////////////////////////////////////////////////////////////////////////////////////////
if(logger.isDebugEnabled())
logger.debug("Micro pipeline [id="+id+"] successfully shut down");
}
public String getId() {
return id;
}
public Map<String, SourceRuntimeEnvironment> getSources() {
return sources;
}
public Map<String, DelayedResponseOperatorRuntimeEnvironment> getDelayedResponseOperators() {
return delayedResponseOperators;
}
public Map<String, EmitterRuntimeEnvironment> getEmitters() {
return emitters;
}
public Map<String, DirectResponseOperatorRuntimeEnvironment> getDirectResponseOperators() {
return directResponseOperators;
}
public Map<String, StreamingMessageQueue> getQueues() {
return queues;
}
public MetricsHandler getMetricsHandler() {
return metricsHandler;
}
public MicroPipelineConfiguration getConfiguration() {
return configuration;
}
}