/*
* 2012-3 Red Hat Inc. and/or its affiliates and other contributors.
*
* 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.overlord.rtgov.epn;
import java.text.MessageFormat;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* This class represents an Event Processor Network.
*
*/
public class Network implements NetworkMBean {
private String _name=null;
private String _version=null;
private java.util.List<Subscription> _subscriptions=new java.util.ArrayList<Subscription>();
private java.util.List<Node> _nodes=new java.util.ArrayList<Node>();
private java.util.Map<String,Node> _namedNodes=new java.util.HashMap<String,Node>();
private java.util.Map<String,java.util.List<Node>> _subjectNodes=
new java.util.HashMap<String,java.util.List<Node>>();
private long _lastAccessed=0;
private boolean _preinitialized=false;
private ClassLoader _contextClassLoader=null;
private static final Logger LOG=Logger.getLogger(Network.class.getName());
/**
* The default constructor.
*/
public Network() {
}
/**
* This method returns the name of the network. This can be used
* to locate the network by name.
*
* @return The name of the network
*/
public String getName() {
return (_name);
}
/**
* This method sets the name of the network.
*
* @param name The name of the network
*/
public void setName(String name) {
_name = name;
}
/**
* This method returns the version associated with the network.
*
* @return The version
*/
public String getVersion() {
return (_version);
}
/**
* This method sets the version associated with the network.
*
* @param version The version
*/
public void setVersion(String version) {
_version = version;
}
/**
* This method returns the timestamp the network was
* last accessed.
*
* @return When the network was last accessed
*/
protected long lastAccessed() {
return (_lastAccessed);
}
/**
* This method returns the date/time the network was
* last accessed.
*
* @return When the network was last accessed
*/
public java.util.Date getLastAccessed() {
return (new java.util.Date(_lastAccessed));
}
/**
* This method sets the timestamp the network was
* last accessed.
*
* @param timestamp When the network was last accessed
*/
protected void lastAccessed(long timestamp) {
_lastAccessed = timestamp;
}
/**
* This method returns the list of subscriptions that the network will subscribe
* to for events.
*
* @return The list of subscriptions
*/
public java.util.List<Subscription> getSubscriptions() {
return (_subscriptions);
}
/**
* This method sets the list of subscriptions that the network will subscribe
* to for events.
*
* @param subscriptions The list of subscriptions
*/
public void setSubscriptions(java.util.List<Subscription> subscriptions) {
_subscriptions = subscriptions;
}
/**
* This method returns the list of nodes associated with the specified
* subject.
*
* @param subject The subject
* @return The list of nodes, or null if none associated with the subject
*/
public java.util.List<Node> getNodesForSubject(String subject) {
return (_subjectNodes.get(subject));
}
/**
* This method returns the set of subjects that this network
* subscribes to.
*
* @return The set of subscription subjects
*/
public java.util.Set<String> subjects() {
return (_subjectNodes.keySet());
}
/**
* This method returns the event processor nodes.
*
* @return The event processor nodes
*/
public java.util.List<Node> getNodes() {
return (_nodes);
}
/**
* This method sets the event processor nodes.
*
* @param nodes The event processor nodes
*/
public void setNodes(java.util.List<Node> nodes) {
_nodes = nodes;
}
/**
* This method returns the node associated with the
* supplied name.
*
* @param name The name
* @return The node, or null if not found
*/
public Node getNode(String name) {
return (_namedNodes.get(name));
}
/**
* This method is called on occasions where the network's
* event processors need to be initialized in a different
* classloader context to the container related configuration
* (i.e. channels between nodes).
*
* @throws Exception Failed to pre-initialize the network
*/
protected void preInit() throws Exception {
if (!_preinitialized) {
_preinitialized = true;
for (Node node : _nodes) {
// Initialize the node
node.init();
}
// Cache context classloader for use deserializing
// events in this context
_contextClassLoader = Thread.currentThread().getContextClassLoader();
if (LOG.isLoggable(Level.FINEST)) {
LOG.finest("Pre-initialized '"+_name+"/"+_version+"': classloader="+_contextClassLoader);
}
}
}
/**
* This method returns the context class loader
* in which the network was pre-initialized.
*
* @return The context classloader, or null if not relevant
*/
protected ClassLoader contextClassLoader() {
return (_contextClassLoader);
}
/**
* This method initializes the name to node map.
*
*/
protected void initNameMap() {
// Initialize mapping from name to node
for (Node node : _nodes) {
_namedNodes.put(node.getName(), node);
}
}
/**
* This method initializes the network.
*
* @param container The container
* @throws Exception Failed to initialize the network
*/
protected void init(EPNContainer container) throws Exception {
initNameMap();
for (Node node : _nodes) {
// Initialize channels
if (node.getSourceNodes() != null) {
for (String nodeName : node.getSourceNodes()) {
Node sourceNode=getNode(nodeName);
if (sourceNode == null) {
LOG.severe(MessageFormat.format(java.util.PropertyResourceBundle.getBundle(
"epn-core.Messages").getString("EPN-CORE-2"),
getName(), getVersion(), node.getName(), nodeName));
} else {
sourceNode.getChannels().add(container.getChannel(this, nodeName, node.getName()));
}
}
}
// If results should be notified, then add a channel to be sent the results
if (container != null) {
for (Notification no : node.getNotifications()) {
if (no.getType().equals(NotificationType.Results)) {
node.getChannels().add(container.getNotificationChannel(this,
no.getSubject()));
}
}
}
if (node.getDestinationSubjects() != null) {
for (String subject : node.getDestinationSubjects()) {
node.getChannels().add(container.getChannel(subject));
}
}
if (!_preinitialized) {
// Initialize the node
node.init();
}
// Associate the container with the node
node.setContainer(container);
}
// Initialize subject/node mapping
for (Subscription sub : _subscriptions) {
Node node=getNode(sub.getNodeName());
if (node == null) {
throw new Exception("Network '"+getName()+"' version '"+getVersion()
+"' subscription has unknown node name '"+sub.getNodeName()+"'");
} else {
java.util.List<Node> nodes=_subjectNodes.get(sub.getSubject());
if (nodes == null) {
nodes = new java.util.ArrayList<Node>();
_subjectNodes.put(sub.getSubject(), nodes);
}
nodes.add(node);
}
}
// If classloader not set, then use current one
if (_contextClassLoader == null) {
_contextClassLoader = Thread.currentThread().getContextClassLoader();
}
}
/**
* This method closes the network.
*
* @param container The container
* @throws Exception Failed to close the network
*
* @deprecated Use the 'close' method without the container parameter
*/
protected void close(EPNContainer container) throws Exception {
close();
}
/**
* This method closes the network.
*
* @throws Exception Failed to close the network
*/
protected void close() throws Exception {
for (Node node : _nodes) {
node.close();
}
}
}