/*******************************************************************************
* Copyright © 2012-2015 eBay Software Foundation
* This program is dual licensed under the MIT and Apache 2.0 licenses.
* Please see LICENSE for more information.
*******************************************************************************/
package com.ebay.jetstream.application.dataflows;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.NamedBean;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStartedEvent;
import org.springframework.jmx.export.annotation.ManagedResource;
import com.ebay.jetstream.config.AbstractNamedBean;
import com.ebay.jetstream.event.EventSink;
import com.ebay.jetstream.event.EventSource;
import com.ebay.jetstream.event.channel.InboundChannel;
import com.ebay.jetstream.management.Management;
import com.ebay.jetstream.xmlser.XSerializable;
/**
* It will capture the flows of data within one application. It should be put
* within the JetStream application spring container.
*
* @author weijin
*
*/
@ManagedResource(objectName = "Event/DataFlows", description = "data flow")
public class DataFlows extends AbstractNamedBean implements BeanFactoryAware,
InitializingBean, ApplicationListener, XSerializable {
private Map<String, Set<String>> graph;
private DefaultListableBeanFactory beanFactory;
public Map<String, Set<String>> getGraph() {
populateGraph();
return graph;
}
public void setGraph(Map<String, Set<String>> graph) {
this.graph = graph;
}
public DataFlows() {
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = (DefaultListableBeanFactory) beanFactory;
}
public void popuateGraph(String beanName,
DefaultListableBeanFactory beanFactory, DirectedGraph<String> dg) {
Object object = beanFactory.getBean(beanName);
if (object instanceof EventSource) {
Collection<EventSink> eventSinks = ((EventSource) object)
.getEventSinks();
for (EventSink eventSink : eventSinks) {
if (eventSink != null) {
boolean isNodeNotExistsed = dg.addNode(eventSink
.getBeanName());
dg.addEdge(beanName, eventSink.getBeanName());
if (isNodeNotExistsed) {
popuateGraph(eventSink.getBeanName(), beanFactory, dg);
}
}
}
} else if (object instanceof NamedBean) {
dg.addNode(beanName);
} else {
throw new RuntimeException("should not happen!!");
}
}
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ContextStartedEvent) {
populateGraph();
}
}
@Override
public void afterPropertiesSet() throws Exception {
Management.addBean(getBeanName(), this);
}
private void populateGraph() {
try {
String[] inputBeanNames = beanFactory
.getBeanNamesForType(InboundChannel.class);
DirectedGraph<String> dg = new DirectedGraph<String>();
for (String beanName : inputBeanNames) {
dg.addNode(beanName);
popuateGraph(beanName, beanFactory, dg);
}
graph = dg.getMap();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}