All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.coos.messaging.COOSFactory Maven / Gradle / Ivy

/**
 * 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;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.coos.coosXMLSchema.ChannelMappingType;
import org.coos.coosXMLSchema.ChannelType;
import org.coos.coosXMLSchema.ChannelserverType;
import org.coos.coosXMLSchema.CoosDocument;
import org.coos.coosXMLSchema.CoosType;
import org.coos.coosXMLSchema.CostType;
import org.coos.coosXMLSchema.FilterType;
import org.coos.coosXMLSchema.InlinkType;
import org.coos.coosXMLSchema.OutlinkType;
import org.coos.coosXMLSchema.ProcessorType;
import org.coos.coosXMLSchema.PropertyType;
import org.coos.coosXMLSchema.QosclassType;
import org.coos.coosXMLSchema.RouteralgorithmType;
import org.coos.coosXMLSchema.RouterprocessorType;
import org.coos.coosXMLSchema.SegmentType;
import org.coos.coosXMLSchema.TransportType;
import org.coos.messaging.COContainer;
import org.coos.messaging.Link;
import org.coos.messaging.Processor;
import org.coos.messaging.Transport;
import org.coos.messaging.routing.DirectAlgorithm;
import org.coos.messaging.routing.Router;
import org.coos.messaging.routing.RouterChannel;
import org.coos.messaging.routing.RouterProcessor;
import org.coos.messaging.routing.RouterSegment;
import org.coos.messaging.routing.RoutingAlgorithm;
import org.coos.messaging.transport.DefaultChannelServer;
import org.coos.messaging.util.Log;
import org.coos.messaging.util.LogFactory;

/**
 * Factory for COOS instances
 * 
 * @author Knut Eilif Husa, Tellu AS
 */
public class COOSFactory extends COFactory {

    private static final Log logger = LogFactory.getLog(COOSFactory.class.getName());

    private static Map coosInstances = new ConcurrentHashMap();
    private static String defaultCoosInstanceName = null;

    private COOSFactory() {

    }

    public static COOS getCOOSInstance(String COOSInstanceName) {
        return coosInstances.get(COOSInstanceName);
    }

    /**
     * Default COOS instance for testing.
     * 
     * @return A COOS instance
     */
    public static COOS getDefaultCOOSInstance() {
        if (defaultCoosInstanceName == null) {
            for (String s : coosInstances.keySet()) {
            	defaultCoosInstanceName = s;
                break;
            }
        }
        return coosInstances.get(defaultCoosInstanceName);
    }
    
    public static void clear(){
    	coosInstances.clear();
    	defaultCoosInstanceName = null;
    }

    /**
     * Default COOS instance for testing.
     * 
     * @param coos - a COOS instance
     */
    public static void setDefaultCOOSInstanceName(String coosName) {
        defaultCoosInstanceName = coosName;
    }

    /**
     * Create COOS instance.
     * 
     * @deprecated use createCOOS(InputStream, COContainer)
     * @param config XML configuration
     * @return COOS instance
     * @throws Exception if errors in configuration is found 
     */
    @Deprecated
    public static COOS createCOOS(InputStream config) throws Exception {
        return createCOOS(config, null);
    }

    /** 
     * Create COOS instance.
     * 
     * @param config XML configuration
     * @param container COContainer in which COOS instance is started 
     * @return COOS instance
     * @throws Exception if errors in configuration is found 
     */
    public static COOS createCOOS(InputStream config, COContainer container) throws Exception {

        //XmlOptions options = new XmlOptions();		
        CoosDocument doc = CoosDocument.Factory.parse(config);
        COOS coos = instantiate(doc.getCoos(),container);
        coos.setCoosContainer(container);
        return coos;
    }

    private static COOS instantiate(CoosType model, COContainer container) throws Exception {

        COOS coos = new COOS();

        if (model.getName() == null) {
            throw new Exception("COOS instance has no name. Must be defined!");
        }
        coos.setName(model.getName());
        coosInstances.put(model.getName(), coos);

        if (model.getRouter() == null) {
            throw new Exception("COOS must contain a router. Must be defined!");
        }
        if (model.getRouter().getClass1() == null) {
            throw new Exception("COOS router must have a implementing class. Must be defined!");
        }
        Class cl = COOSFactory.tryClass(container,model.getRouter().getClass1());
        Router router = (Router) cl.newInstance();
        coos.setRouter(router);

        // routerprocessors
        for (int i = 0; i < model.getRouter().getRouterprocessorArray().length; i++) {
            ProcessorType processorType = model.getRouter().getRouterprocessorArray()[i];
            if (processorType.getName() == null || processorType.getClass1() == null) {
                throw new Exception("COOS processors must have a name and a implementing class. Must be defined!");
            }
            String name = processorType.getName();
            String className = processorType.getClass1();
            boolean isShared = processorType.getShared();
            Map props = new HashMap();
            for (int j = 0; j < processorType.getPropertyArray().length; j++) {
                PropertyType propertyType = processorType.getPropertyArray()[j];
                props.put(propertyType.getName(), propertyType.getValue());
            }
            Class processorClass = COOSFactory.tryClass(container,className);
            Processor processor = (Processor) processorClass.newInstance();
            processor.setShared(isShared);
            processor.setProperties(new Hashtable(props));
            coos.addProcessor(name, processor);
        }

        // preProcessors
        for (int i = 0; i < model.getRouter().getPreprocessorArray().length; i++) {
            RouterprocessorType routerprocessorType = model.getRouter().getPreprocessorArray()[i];
            if (coos.getProcessor(routerprocessorType.getRouterprocessor()) == null) {
                throw new Exception("COOS processors with name: " + routerprocessorType.getRouterprocessor()
                        + " is not defined. referenced from router preprocessors!");
            }
            router.addPreProcessor((RouterProcessor) coos.getProcessor(routerprocessorType.getRouterprocessor()));
        }

        // postProcessors
        for (int i = 0; i < model.getRouter().getPostprocessorArray().length; i++) {
            RouterprocessorType routerprocessorType = model.getRouter().getPostprocessorArray()[i];
            if (coos.getProcessor(routerprocessorType.getRouterprocessor()) == null) {
                throw new Exception("COOS processors with name: " + routerprocessorType.getRouterprocessor()
                        + " is not defined. referenced from router postprocessors!");
            }
            router.addPostProcessor((RouterProcessor) coos.getProcessor(routerprocessorType.getRouterprocessor()));
        }

        // qosclass
        for (int i = 0; i < model.getRouter().getQosclassArray().length; i++) {
            QosclassType qosclassType = model.getRouter().getQosclassArray()[i];
            if (qosclassType.getName() == null) {
                throw new Exception("COOS QoS types must have a name. Must be defined!");
            }
            router.addQoSClass(qosclassType.getName(), Boolean.valueOf(qosclassType.getDefault()));
        }

        // segment
        for (int i = 0; i < model.getRouter().getSegmentArray().length; i++) {
            SegmentType segmentType = model.getRouter().getSegmentArray()[i];
            String segmentName = segmentType.getName();
            if (segmentName == null || segmentName.equals("")) {
                segmentName = ".";
            }
            if (segmentName.equals(Router.LOCAL_SEGMENT) || segmentName.equals(Router.DICO_SEGMENT)
                    || segmentName.indexOf('/') != -1 || segmentName.indexOf('\\') != -1
                    || segmentName.indexOf(' ') != -1) {
                throw new Exception("Invalid COOS segment: " + segmentName
                        + " Can not contain: blanks, \\, / or the reserved segment 'localcoos' and 'dico'.");
            }
            String routerUuid = Router.ROUTER_UUID_PREFIX + segmentType.getRouteruuid();
            if (segmentType.getRouteruuid() == null) {
                throw new Exception(
                "COOS Segments must have a segment unique identification of the Router uuid. Must be defined!");
            }
            if (segmentName.equals(".")) {
                routerUuid = segmentName + routerUuid;
            } else {
                routerUuid = segmentName + "." + routerUuid;
            }

            if (segmentType.getRouteruuid() == null) {
                throw new Exception(
                "COOS Segments must have a segment unique identification of the Router uuid. Must be defined!");
            }
            String routerAlgorithm = segmentType.getRouteralgorithm();

            if (segmentType.getRouteralgorithm() == null) {
                throw new Exception("COOS Segments must have a router algorithm. Must be defined!");
            }

            String defaultSegmentStr = segmentType.getDefaultSegment();
            boolean defaultSegment = defaultSegmentStr != null && defaultSegmentStr.equalsIgnoreCase("true");
            for (int j = 0; j < model.getRouter().getRouteralgorithmArray().length; j++) {
                RouteralgorithmType routeralgorithmType = model.getRouter().getRouteralgorithmArray()[j];
                if (routeralgorithmType.getName() == null || routeralgorithmType.getClass1() == null) {
                    throw new Exception(
                    "COOS router algorithms must have a name and a implementing class. Must be defined!");
                }
                if (routerAlgorithm.equals(routeralgorithmType.getName())) {
                    String className = routeralgorithmType.getClass1();
                    Class algorithmClass = COOSFactory.tryClass(container,className);
                    Map props = new HashMap();
                    for (int k = 0; k < routeralgorithmType.getPropertyArray().length; k++) {
                        PropertyType propertyType = routeralgorithmType.getPropertyArray()[k];
                        props.put(propertyType.getName(), propertyType.getValue());
                    }
                    RoutingAlgorithm algorithm = (RoutingAlgorithm) algorithmClass.newInstance();
                    if (segmentType.getLogging() != null) {
                        algorithm.setLoggingEnabled(segmentType.getLogging().equalsIgnoreCase("true"));
                    }
                    algorithm.init(routerUuid, router, props);
                    break;
                }
                if (j == model.getRouter().getRouteralgorithmArray().length) {
                    throw new Exception("COOS router algorithm: " + routeralgorithmType.getName()
                            + " is not defined. Must be defined!");
                }
            }

            coos.addSegment(new RouterSegment(segmentName, routerUuid, defaultSegment));
        }

        // Adding a local segment
        RoutingAlgorithm algorithm = new DirectAlgorithm();
        String routerUuid = Router.LOCAL_SEGMENT + "." + Router.ROUTER_UUID_PREFIX + coos.getName();
        algorithm.init(routerUuid, router, new Hashtable());
        coos.addSegment(new RouterSegment(Router.LOCAL_SEGMENT, routerUuid, false));

        // processors
        for (int i = 0; i < model.getProcessorArray().length; i++) {
            ProcessorType processorType = model.getProcessorArray()[i];
            if (processorType.getName() == null || processorType.getClass1() == null) {
                throw new Exception("COOS processors must have a name and an implementing class. Must be defined!");
            }
            String name = processorType.getName();
            String className = processorType.getClass1();
            boolean isShared = processorType.getShared();
            Map props = new HashMap();
            for (int j = 0; j < processorType.getPropertyArray().length; j++) {
                PropertyType propertyType = processorType.getPropertyArray()[j];
                if (propertyType.getName() == null || propertyType.getValue() == null) {
                    throw new Exception("COOS properties must have a name and a value. Must be defined!");
                }
                props.put(propertyType.getName(), propertyType.getValue());
            }
            Class processorClass = COOSFactory.tryClass(container,className);
            Processor processor = (Processor) processorClass.newInstance();
            processor.setShared(isShared);
            processor.setProperties(new Hashtable(props));
            coos.addProcessor(name, processor);
        }

        // transports
        for (int i = 0; i < model.getTransportArray().length; i++) {
            TransportType transportType = model.getTransportArray()[i];
            if (transportType.getName() == null || transportType.getClass1() == null) {
                throw new Exception("COOS transports must have a name and an implementing class. Must be defined!");
            }
            String name = transportType.getName();
            String className = transportType.getClass1();
            Map props = new HashMap();
            for (int j = 0; j < transportType.getPropertyArray().length; j++) {
                PropertyType propertyType = transportType.getPropertyArray()[j];
                if (propertyType.getName() == null || propertyType.getValue() == null) {
                    throw new Exception("COOS properties must have a name and a value. Must be defined!");
                }
                props.put(propertyType.getName(), propertyType.getValue());
            }
            Class transportClass = COOSFactory.tryClass(container,className);
            Transport transport = (Transport) transportClass.newInstance();
            transport.setProperties(new Hashtable(props));
            transport.setName(name);
            coos.addTransport(name, transport);
        }

        // channels
        for (int i = 0; i < model.getChannelArray().length; i++) {
            ChannelType channelType = model.getChannelArray()[i];
            if (channelType.getName() == null) {
                throw new Exception("COOS channels must have a name. Must be defined!");
            }
            String name = channelType.getName();
            boolean init = channelType.getInit();
            boolean defaultGw = channelType.getDefaultgw();
            String transport = channelType.getTransport();
            RouterChannel channel = new RouterChannel();
            channel.setInit(init);
            channel.setDefaultGw(defaultGw);
            String segment = channelType.getSegment();
            if (init && (segment == null || segment.equals(""))) {
                segment = ".";
            }
            if (segment != null) {
                if (coos.getRouter().getRoutingAlgorithm(segment) == null) {
                    throw new Exception("COOS channel: " + channel + " is defined to connect to segment: " + segment
                            + " which the Coos instance: " + coos.getName() + " does not maintain.");
                }
                channel.setConnectingPartyUuid(coos.getRouter().getRoutingAlgorithm(segment).getRouterUuid());
            }
            channel.setTransport(coos.getTransport(transport));
            channel.setLinkManager(router);

            Link inLink = new Link();
            channel.setInLink(inLink);
            InlinkType inlinkType = channelType.getInlink();
            if (inlinkType != null) {
                for (int j = 0; j < inlinkType.getFilterArray().length; j++) {
                    FilterType filterType = inlinkType.getFilterArray()[j];
                    if (coos.getProcessor(filterType.getProcessor()) == null) {
                        throw new Exception("COOS channel: " + channel + ", inBound link: referenced processor: "
                                + filterType.getProcessor() + " is not defined.");
                    }
                    inLink.addFilterProcessor(coos.getProcessor(filterType.getProcessor()));
                }
            }
            Link outLink = new Link();
            channel.setOutLink(outLink);
            OutlinkType outlinkType = channelType.getOutlink();
            if (outlinkType != null) {
                for (int j = 0; j < outlinkType.getFilterArray().length; j++) {
                    FilterType filterType = outlinkType.getFilterArray()[j];
                    if (coos.getProcessor(filterType.getProcessor()) == null) {
                        throw new Exception("COOS channel: " + channel + ", outBound link: referenced processor: "
                                + filterType.getProcessor() + " is not defined.");
                    }
                    outLink.addFilterProcessor(coos.getProcessor(filterType.getProcessor()));
                }
                for (int j = 0; j < outlinkType.getCostArray().length; j++) {
                    CostType costType = outlinkType.getCostArray()[j];
                    outLink.setCost(costType.getName(), costType.getValue());
                }
            }

            coos.addChannel(name, channel);
        }

        // channel-mapping
        for (int i = 0; i < model.getChannelMappingArray().length; i++) {
            ChannelMappingType channelMappingType = model.getChannelMappingArray()[i];
            if (channelMappingType.getUuid() == null || channelMappingType.getChannel() == null) {
                throw new Exception(
                "COOS channel mappings must define a relation between a uuid regexp pattern and a channel.");
            }
            String uuid = channelMappingType.getUuid();
            String channel = channelMappingType.getChannel();
            if (coos.getChannel(channel) == null) {
                throw new Exception("COOS channel: " + channel + " referenced from channel mappings is not defined.");
            }
            coos.addChannelMap(uuid, coos.getChannel(channel));
        }

        // channelserver

        // Default Channelserver always present
        DefaultChannelServer defaultChannelServer = new DefaultChannelServer();
        defaultChannelServer.setCOOSInstance(coos);
        defaultChannelServer.setLinkManager(router);
        defaultChannelServer.setChannelMappings(new Hashtable(coos.getChannelMap()));
        defaultChannelServer.setSegmentMappings(new Hashtable(coos.getSegmentMap()));
        coos.addChannelServer("default", defaultChannelServer);

        for (int i = 0; i < model.getChannelserverArray().length; i++) {
            ChannelserverType channelserverType = model.getChannelserverArray()[i];
            if (channelserverType.getName() == null || channelserverType.getClass1() == null) {
                throw new Exception("COOS channel servers must have a name and a implementing class. Must be defined!");
            }
            String name = channelserverType.getName();
            String className = channelserverType.getClass1();
            Map props = new HashMap();
            for (int j = 0; j < channelserverType.getPropertyArray().length; j++) {
                PropertyType propertyType = channelserverType.getPropertyArray()[j];
                if (propertyType.getName() == null || propertyType.getValue() == null) {
                    throw new Exception("COOS properties must have a name and a value. Must be defined!");
                }
                props.put(propertyType.getName(), propertyType.getValue());
            }
            Class serverClass = COOSFactory.tryClass(container,className);
            ChannelServer server = (ChannelServer) serverClass.newInstance();
            server.setCOOSInstance(coos);
            server.setProperties(new Hashtable(props));
            server.setLinkManager(router);
            server.setChannelMappings(new Hashtable(coos.getChannelMap()));
            server.setSegmentMappings(new Hashtable(coos.getSegmentMap()));
            coos.addChannelServer(name, server);
        }
        return coos;

    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy