
org.coos.messaging.transport.DefaultChannelServer Maven / Gradle / Ivy
The newest version!
/**
* COOS - Connected Objects Operating System (www.connectedobjects.org).
*
* Copyright (C) 2009 Telenor ASA and Tellu AS. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
* You may also contact one of the following for additional information:
* Telenor ASA, Snaroyveien 30, N-1331 Fornebu, Norway (www.telenor.no)
* Tellu AS, Hagalokkveien 13, N-1383 Asker, Norway (www.tellu.no)
*/
package org.coos.messaging.transport;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;
import org.coos.messaging.COOS;
import org.coos.messaging.Channel;
import org.coos.messaging.ChannelServer;
import org.coos.messaging.ConnectingException;
import org.coos.messaging.Link;
import org.coos.messaging.LinkManager;
import org.coos.messaging.Message;
import org.coos.messaging.ProcessorException;
import org.coos.messaging.Transport;
import org.coos.messaging.impl.DefaultChannel;
import org.coos.messaging.impl.DefaultMessage;
import org.coos.messaging.impl.DefaultProcessor;
import org.coos.messaging.routing.Router;
import org.coos.messaging.routing.RouterChannel;
import org.coos.messaging.routing.RouterSegment;
import org.coos.messaging.util.Log;
import org.coos.messaging.util.LogFactory;
import org.coos.messaging.util.UuidGenerator;
import org.coos.messaging.util.UuidHelper;
/**
* @author Knut Eilif Husa, Tellu AS A default channel server
*/
public class DefaultChannelServer implements ChannelServer {
private static final Log logger = LogFactory.getLog(DefaultChannelServer.class.getName());
private Map channelMappings = new HashMap();
protected Hashtable properties = new Hashtable();
private LinkManager linkManager;
private UuidGenerator uuidGenerator = new UuidGenerator();
private COOS coosInstance;
public void setChannelMappings(Hashtable channelMappings) {
this.channelMappings = channelMappings;
}
public void addChannelMapping(String uuid, RouterChannel channel) {
this.channelMappings.put(uuid, channel);
}
public void setCOOSInstance(COOS coosInstance) {
this.coosInstance = coosInstance;
}
public void setLinkManager(LinkManager linkManager) {
this.linkManager = linkManager;
}
public void initializeChannel(Transport transport) {
transport.setChainedProcessor(new InitProcessor(transport));
}
/**
* Starts the service
*
* @throws Exception
* Exception thrown if starting of service fails
*/
public void start() throws Exception {
// To change body of implemented methods use File | Settings | File
// Templates.
}
/**
* Stops the service
*
* @throws Exception
* Exception thrown if stopping of service fails
*/
public void stop() throws Exception {
// To change body of implemented methods use File | Settings | File
// Templates.
}
@SuppressWarnings("unchecked")
public void setProperties(Hashtable properties) {
this.properties = properties;
}
public Hashtable getProperties() {
return properties;
}
public String getProperty(String key) {
return properties.get(key);
}
public void setProperty(String key, String value) {
properties.put(key, value);
}
private class InitProcessor extends DefaultProcessor {
Transport transport;
public InitProcessor(Transport transport) {
this.transport = transport;
}
@SuppressWarnings("unchecked")
public void processMessage(Message msg) throws ProcessorException {
if (msg.getHeader(Message.MESSAGE_NAME).equals(DefaultChannel.CONNECT)) {
String conUuid = msg.getHeader(DefaultChannel.CONNECT_UUID);
String conSeg = msg.getHeader(DefaultChannel.CONNECT_SEGMENT);
String routingAlgName = msg.getHeader(DefaultChannel.ROUTING_ALGORITHM);
Message reply = new DefaultMessage(Channel.CONNECT_ACK);
RouterSegment seg;
RouterChannel channel;
try {
if ((conUuid != null) && (routingAlgName == null)) {
// this happens when endpoints with already allocated uuid connect
conSeg = UuidHelper.getSegmentFromEndpointNameOrEndpointUuid(conUuid);
// the routerUuids for the various segments
seg = linkManager.getSegment(conSeg);
if (seg == null) {
throwUUIDConnectingException(conUuid);
}
reply.setHeader(DefaultChannel.CONNECT_UUID, seg.getRouterUUID());
reply.setHeader(DefaultChannel.CONNECT_ROUTER_UUID, seg.getRouterUUID());
} else if ((conUuid != null) && (routingAlgName != null)) {
conSeg = UuidHelper.getSegmentFromEndpointNameOrEndpointUuid(conUuid);
// this happens when routers connect
// the routerUuids for the various segments
seg = linkManager.getSegment(conSeg);
if (seg == null) {
// parentsegment must be present and static
String parentSeg = UuidHelper.getParentSegment(conSeg);
seg = linkManager.getSegment(parentSeg);
if (seg == null) {
throwSegmentConnectingException(conUuid, routingAlgName);
}
linkManager.addDynamicSegment(conSeg, routingAlgName);
seg = linkManager.getSegment(conSeg);
} else {
if (!seg.getRoutingAlgorithmName().equals(routingAlgName)) {
throwSegmentConnectingException(conUuid, routingAlgName);
}
}
reply.setHeader(DefaultChannel.CONNECT_UUID, seg.getRouterUUID());
reply.setHeader(DefaultChannel.CONNECT_ROUTER_UUID, seg.getRouterUUID());
} else {
// This happens when endpoint attach to the bus and gets
// uuid allocated
if ((conSeg == null) || conSeg.equals("") || conSeg.equals(Router.LOCAL_SEGMENT) || conSeg.equals(Router.DICO_SEGMENT)) {
// If no segment id specified we pick the default from the
// segment mapping
for (RouterSegment rs : linkManager.getSegmentMap().values()) {
if (rs.isDefaultSegment()) {
conSeg = UuidHelper.getSegmentFromEndpointNameOrEndpointUuid(rs.getRouterUUID());
break;
}
}
}
seg = linkManager.getSegment(conSeg);
if (seg == null) {
throwSegmentConnectingException(conSeg, "n/a");
}
if (!conSeg.equals(".")) {
conSeg = new StringBuilder(conSeg).append(".").toString();
}
conUuid = new StringBuilder().append(conSeg).append(uuidGenerator.generateId()).toString();
reply.setHeader(DefaultChannel.CONNECT_ALLOCATED_UUID, conUuid);
reply.setHeader(DefaultChannel.CONNECT_ROUTER_UUID, seg.getRouterUUID());
}
Channel prototypeChannel = null;
for (String key : channelMappings.keySet()) {
if (conUuid.matches(key)) {
prototypeChannel = channelMappings.get(key);
logger.debug("Matched channel with key: " + key + " to channel: " + prototypeChannel.getName());
}
}
if (prototypeChannel == null) {
logger.debug("Allocating new channel!");
prototypeChannel = new RouterChannel();
}
channel = (RouterChannel) prototypeChannel.copy();
if (coosInstance != null) {
coosInstance.addChannel(conUuid, channel);
}
channel.getOutLink().setChainedProcessor(transport);
transport.setChannel(channel);
transport.setChainedProcessor(channel.getInLink());
channel.getInLink().setChainedProcessor(linkManager.getDefaultProcessor()); // The
// router
channel.getInLink().setDestinationUuid(seg.getRouterUUID());
channel.setLinkManager(linkManager);
channel.setTransport(transport);
linkManager.addLink(conUuid, channel.getOutLink());
// Retrieve the aliases
// They are not set on the link directly since we want to handle aliases
// a common way whether they arrive at registration or at later stages
Hashtable props = msg.getBodyAsProperties();
if (props != null) {
Vector aliases = (Vector) props.get(Link.ALIASES);
linkManager.setLinkAliases(aliases, channel.getOutLink());
}
} catch (Exception e) {
logger.warn("Exception caught. Removing link " + conUuid, e);
linkManager.removeLink(conUuid);
transport.setChainedProcessor(null);
coosInstance.removeChannel(conUuid);
reply.setHeader(Message.MESSAGE_NAME, Channel.CONNECT_NACK);
reply.setHeader(Message.TYPE, Message.TYPE_ERROR);
reply.setHeader(Message.ERROR_REASON, e.getMessage());
transport.processMessage(reply);
return;
}
transport.processMessage(reply);
channel.setConnected(true);
} else {
throw new ProcessorException("ChannelServer: Cannot process message: " + msg.toString());
}
}
private void throwUUIDConnectingException(String conUuid) throws ConnectingException {
Iterator iter = linkManager.getSegmentMap().keySet().iterator();
String segmentListStr = "";
while (iter.hasNext()) {
segmentListStr += iter.next();
segmentListStr += ", ";
}
String s = "Connection to endpoint/coos instance with uuid: " + conUuid + " failed. " +
"This coos instance is declared to only connect to endpoints/coos instances in segment(s):" + segmentListStr;
logger.error(s);
throw new ConnectingException(s);
}
private void throwSegmentConnectingException(String conSeg, String routingAlg) throws ConnectingException {
Iterator iter = linkManager.getSegmentMap().keySet().iterator();
String segmentListStr = "";
while (iter.hasNext()) {
RouterSegment seg = linkManager.getSegmentMap().get(iter.next());
segmentListStr += seg.getName() + ":" + seg.getRoutingAlgorithmName();
segmentListStr += ", ";
}
String s = "Connection to endpoint/coos instance with segment: '" + conSeg + ", routingAlgorithm: " + routingAlg + "' failed. " +
"This coos instance is declared to only connect to endpoints/coos instances in segment(s):" + segmentListStr;
logger.error(s);
throw new ConnectingException(s);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy