Package org.apache.tuscany.sca.domain.impl

Source Code of org.apache.tuscany.sca.domain.impl.SCADomainImpl

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.apache.tuscany.sca.domain.impl;

import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.namespace.QName;

import org.apache.tuscany.sca.assembly.AssemblyFactory;
import org.apache.tuscany.sca.assembly.Component;
import org.apache.tuscany.sca.assembly.ComponentService;
import org.apache.tuscany.sca.assembly.Composite;
import org.apache.tuscany.sca.assembly.CompositeService;
import org.apache.tuscany.sca.assembly.SCABinding;
import org.apache.tuscany.sca.assembly.SCABindingFactory;
import org.apache.tuscany.sca.assembly.xml.Constants;
import org.apache.tuscany.sca.contribution.Contribution;
import org.apache.tuscany.sca.contribution.DeployedArtifact;
import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
import org.apache.tuscany.sca.contribution.service.ContributionService;
import org.apache.tuscany.sca.core.assembly.ActivationException;
import org.apache.tuscany.sca.core.context.ServiceReferenceImpl;
import org.apache.tuscany.sca.domain.DomainException;
import org.apache.tuscany.sca.domain.DomainManagerInitService;
import org.apache.tuscany.sca.domain.SCADomainSPI;
import org.apache.tuscany.sca.domain.model.Domain;
import org.apache.tuscany.sca.domain.model.DomainModelFactory;
import org.apache.tuscany.sca.domain.model.Node;
import org.apache.tuscany.sca.domain.model.Service;
import org.apache.tuscany.sca.domain.model.impl.DomainModelFactoryImpl;
import org.apache.tuscany.sca.host.embedded.impl.ReallySmallRuntime;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
import org.apache.tuscany.sca.node.NodeManagerService;
import org.apache.tuscany.sca.node.NodeFactoryImpl;
import org.apache.tuscany.sca.runtime.RuntimeComponent;
import org.apache.tuscany.sca.runtime.RuntimeComponentContext;
import org.apache.tuscany.sca.runtime.RuntimeComponentReference;
import org.osoa.sca.CallableReference;
import org.osoa.sca.ServiceReference;
import org.osoa.sca.ServiceRuntimeException;

/**
* The SCA domain implementation. In Tuscany we currently have a model of the
* SCA Domain that relies on a central domain manager this class provides that
* central manager.
*
* @version $Rev: 552343 $ $Date: 2007-09-09 23:54:46 +0100 (Sun, 09 Sep 2007) $
*/
public class SCADomainImpl implements SCADomainSPI  {
 
    private final static Logger logger = Logger.getLogger(SCADomainImpl.class.getName());
      
    // class loader used to get the runtime going
    private ClassLoader domainClassLoader;
   
    // management runtime
    private ReallySmallRuntime domainManagementRuntime;
    private ContributionService domainManagementContributionService;
    private Composite domainManagementComposite;
    private DomainManagerNodeImpl domainManagerNode;
   
    // management services
    private DomainManagerInitService domainManagerInitService;
         
    // The domain model
    private DomainModelFactory domainModelFactory = new DomainModelFactoryImpl();
    private Domain domainModel;
    private HashMap<String, Contribution> contributions = new HashMap<String, Contribution>();
    
    
    /**
     * Create a domain giving the URI for the domain.
     *
     * @param domainUri - identifies what host and port the domain service is running on, e.g. http://localhost:8081
     * @throws ActivationException
     */
    public SCADomainImpl(String domainURI) throws DomainException {
        this.domainModel = domainModelFactory.createDomain();
        this.domainModel.setDomainURI(domainURI);
        this.domainClassLoader = SCADomainImpl.class.getClassLoader();
        init();
    }   
      
    /**
     * Create the domain management runtime etc
     */
    private void init() throws DomainException {
        try {
            // check whether domain uri is a url
            URI tmpURI;
            try {
                tmpURI = new URI(domainModel.getDomainURI());
                if (tmpURI.isAbsolute()){
                    domainModel.setDomainURL(tmpURI.toURL().toExternalForm());
                }
            } catch(Exception ex) {
                throw new ActivationException("domain uri " +
                                              domainModel.getDomainURI() +
                                              "must be a valid url");
            }
               
            // create a runtime for the domain management services to run on
            domainManagementRuntime = new ReallySmallRuntime(domainClassLoader);
            domainManagementRuntime.start();
           
            // Create an in-memory domain level management composite
            AssemblyFactory assemblyFactory = domainManagementRuntime.getAssemblyFactory();
            domainManagementComposite = assemblyFactory.createComposite();
            domainManagementComposite.setName(new QName(Constants.SCA10_NS, "domainManagement"));
            domainManagementComposite.setURI(domainModel.getDomainURI() + "/Management");           
           
            // Set up the domain so that we can push in the node endpoint before we
            // call a node
            domainManagerNode = new DomainManagerNodeImpl(this);
            ModelFactoryExtensionPoint factories = domainManagementRuntime.getExtensionPointRegistry().getExtensionPoint(ModelFactoryExtensionPoint.class);
            NodeFactoryImpl domainFactory = new NodeFactoryImpl(domainManagerNode);
            factories.addFactory(domainFactory);           
           
            // Find the composite that will configure the domain
            String domainCompositeName = "domain.composite";
            URL contributionURL = SCADomainUtil.findContributionFromComposite(domainClassLoader, domainCompositeName);
           
            if ( contributionURL != null ){
                logger.log(Level.INFO, "Domain management configured from " + contributionURL);
                          
                // add node composite to the management domain
                domainManagementContributionService = domainManagementRuntime.getContributionService();
                Contribution contribution = null;

                contribution = domainManagementContributionService.contribute(domainModel.getDomainURI(),
                                                                              contributionURL,
                                                                              false);

                Composite composite = null;
                for (DeployedArtifact artifact: contribution.getArtifacts()) {
                    if (domainCompositeName.equals(artifact.getURI())) {
                        composite = (Composite)artifact.getModel();
                    }
                }
               
                if (composite != null) {
               
                    domainManagementComposite.getIncludes().add(composite);
                    domainManagementRuntime.getCompositeBuilder().build(composite);
                   
                    // TODO fix up the domain manager URI to match the provided
                    //      domain uri

                    domainManagementRuntime.getCompositeActivator().activate(composite);
                    domainManagementRuntime.getCompositeActivator().start(composite);
               
                    // get the management components out of the domain so that they
                    // can be configured/used.
                    domainManagerInitService = getService(DomainManagerInitService.class,
                                                          "DomainManagerComponent/DomainManagerInitService",
                                                          domainManagementRuntime,
                                                          domainManagementComposite);
                    domainManagerInitService.setDomain((SCADomainSPI)this);
                   
                       
                } else {
                    throw new ActivationException("Domain management contribution " +
                                                  contributionURL +
                                                  " found but could not be loaded");
                }
            } else {
                throw new ActivationException("Domain management contribution " +
                                              domainCompositeName +
                                              " not found on the classpath");
            }      
           
        } catch(Exception ex) {
            throw new DomainException(ex);
        }
    }  
   
    public Component getComponent(String componentName) {
        for (Composite composite: domainManagementComposite.getIncludes()) {
            for (Component component: composite.getComponents()) {
                if (component.getName().equals(componentName)) {
                    return component;
                }
            }
        }
        return null;
    }      
   
    // SCADomain SPI methods
   
    public Domain getDomainModel(){       
        return domainModel;
    }   
   
    public String addNode(String nodeURI, String nodeURL){
        // try and remove it first just in case it's already registered
        removeNode(nodeURI);
       
        Node node = domainModelFactory.createNode();
        node.setNodeURI(nodeURI);
        node.setNodeURL(nodeURL);
        domainModel.getNodes().put(nodeURI, node);    
       
        logger.log(Level.INFO, "Registered node: " +
                               nodeURI +
                               " at endpoint " +
                               nodeURL);

        return "DummyReturn";
    }
   
    public String removeNode(String nodeURI){
       
        domainModel.getNodes().remove(nodeURI);
              
        logger.log(Level.INFO, "Removed node: " + nodeURI);
       
        return "DummyReturn";
    }
   

    public void registerContribution(String nodeURI, String contributionURI, String contributionURL){
        try {
            if ( domainModel.getContributions().containsKey(contributionURI) == false ){
                // add the contribution information to the domain model
                org.apache.tuscany.sca.domain.model.Contribution contributionModel =
                    parseContribution(contributionURI, contributionURL);
            }

       
            // assign the contribution to the referenced node
        } catch (Exception ex) {
            logger.log(Level.SEVERE, "Exception when registering contribution " +
                                     contributionURI +
                                     ex.toString() );
        }
       
    }
   

    public void unregisterContribution(String contributionURI){
        // TODO
       
    }
   
    public String  registerServiceEndpoint(String domainURI, String nodeURI, String serviceName, String bindingName, String URL){
        // if the service name ends in a "/" remove it
        String modifiedServiceName = null;
        if ( serviceName.endsWith("/") ) {
            modifiedServiceName = serviceName.substring(0, serviceName.length() - 1);
        } else {
            modifiedServiceName = serviceName;
        }
       
        // collect the service info
        Service service = domainModelFactory.createService();
        service.setServiceURI(modifiedServiceName);
        service.setServiceURL(URL);
        service.setServiceBinding(bindingName);
       
        // find the node
        Node node = domainModel.getNodes().get(nodeURI);
       
        if (node != null){
            //store the service
            node.getServices().put(serviceName+bindingName, service);
            logger.log(Level.INFO, "Registered service: " + modifiedServiceName);
        } else {
            logger.log(Level.WARNING, "Trying to register service: " +
                                      modifiedServiceName +
                                      " for a node " +
                                      nodeURI +
                                      "that isn't registered");
        }
       
        return "";
    }
    
    public String  removeServiceEndpoint(String domainUri, String nodeURI, String serviceName, String bindingName){
        Node node = domainModel.getNodes().get(nodeURI);
        node.getServices().remove(serviceName + bindingName);
        logger.log(Level.INFO, "Removed service: " +  serviceName );    
       
        return "";
    }
  
    public String findServiceEndpoint(String domainUri, String serviceName, String bindingName){
        logger.log(Level.INFO, "Finding service: [" +
                               domainUri + " " +
                               serviceName + " " +
                               bindingName +
                               "]");
       
        String url = "";
        String serviceKey = serviceName + bindingName;
       
        for (Node node : domainModel.getNodes().values()){
            Service service = node.getServices().get(serviceKey);
           
            if (service != null){
                url = service.getServiceURL();
                //url = replacePort(url, "8085", "8086");
                logger.log(Level.INFO, "Found service url: " + url);
                break;
            }
        }
              
        return url;
    }
   
    /**
     * Converts a port number to something else to allow for debugging using a
     * HTTP sniffer
     * @param url
     * @param fromPort the port to look for
     * @param toPort the port to replace it with
     * @return the new url
     */
    private String replacePort(String url, String fromPort, String toPort) {
        return url.replace(fromPort, toPort);
    }
       
       
    // SCADomain API methods
   
    public void start() throws DomainException {
        // TODO    
    }


    public void stop() throws DomainException {
        try {
            // Stop the node
            domainManagementRuntime.stop();
                       
        } catch(ActivationException ex) {
            throw new DomainException(ex);
        }        
       
    }   
    public String getURI(){
        return domainModel.getDomainURI();
    }
   
    private org.apache.tuscany.sca.domain.model.Contribution parseContribution(String contributionURI, String contributionURL) throws DomainException {
        // add the contribution information to the domain model
        org.apache.tuscany.sca.domain.model.Contribution contributionModel = domainModelFactory.createContribution();
        contributionModel.setContributionURI(contributionURI);
        contributionModel.setContributionURL(contributionURL);
        domainModel.getContributions().put(contributionURI, contributionModel);
       
        // read the assembly model objects.     
        try {
            // Create a local model from the contribution. Using the contribution
            // processor from the domain management runtime just because we already have it
            Contribution contribution =  domainManagementContributionService.contribute(contributionURI,
                                                                                        new URL(contributionURL),
                                                                                        false);
           
            // store the contribution
            contributions.put(contributionURI, contribution);
           
            // add the composite info to the domain model
            for (DeployedArtifact artifact : contribution.getArtifacts()) {
                if (artifact.getModel() instanceof Composite) {
                    Composite composite = (Composite)artifact.getModel();
                    org.apache.tuscany.sca.domain.model.Composite compositeModel =
                        domainModelFactory.createComposite();
                    compositeModel.setCompositeQName(composite.getName());
                    contributionModel.getComposites().put(compositeModel.getCompositeQName(), compositeModel);
                   
                }
            }           
           
            // add all composites into the domain model
            for (Composite composite : contribution.getDeployables()) {
                org.apache.tuscany.sca.domain.model.Composite compositeModel =
                    domainModelFactory.createComposite();
                compositeModel.setCompositeQName(composite.getName());
                contributionModel.getComposites().put(compositeModel.getCompositeQName(), compositeModel);
            }           
           
            // add the deployable composite info to the domain model
            for (Composite composite : contribution.getDeployables()) {
                org.apache.tuscany.sca.domain.model.Composite compositeModel =
                    contributionModel.getComposites().get(composite.getName());
                contributionModel.getDeployableComposites().put(compositeModel.getCompositeQName(), compositeModel);
                domainModel.getDeployedComposites().put(compositeModel.getCompositeQName(), compositeModel);
            }
           
        } catch(Exception ex) {
            throw new DomainException(ex);
        }
       
        return contributionModel;
    }
   
    private void assignContributionToNode(org.apache.tuscany.sca.domain.model.Contribution contributionModel) throws DomainException {
        // Find a node to run the contribution.
        // TODO - add some more sophisticated algorithm here
        // find a node without a contribution and add it to it. There is no deployment
        // step here we just assume the contribution is available.
       
        boolean foundFreeNode = false;
       
        for(Node node : domainModel.getNodes().values()) {
            if ( node.getContributions().isEmpty()){
                foundFreeNode = true;
                node.getContributions().put(contributionModel.getContributionURI(), contributionModel);
                break;
            }
        }     
       
        if (foundFreeNode == false){
            throw new DomainException("No free node available for contribution " +
                                      contributionModel.getContributionURI());
        }
    }
   
    public void addContribution(String contributionURI, URL contributionURL) throws DomainException {
        // add the contribution information to the domain model
        org.apache.tuscany.sca.domain.model.Contribution contributionModel =
            parseContribution(contributionURI, contributionURL.toExternalForm());

        assignContributionToNode(contributionModel);
    }

    public void removeContribution(String uri) throws DomainException {
       
        // TODO
    }
   
    public void addDeploymentComposite(String contributionURI, String compositeXML) throws DomainException {
        // TODO
    }
   
    public void addToDomainLevelComposite(QName compositeName) throws DomainException {
        // find the nodes with this composite and add the composite as a deployable composite
        for ( Node node : domainModel.getNodes().values()) {
            for (org.apache.tuscany.sca.domain.model.Contribution contribution : node.getContributions().values()){
                org.apache.tuscany.sca.domain.model.Composite composite =
                    contribution.getComposites().get(compositeName);
                if (composite != null) {
                    contribution.getDeployableComposites().put(compositeName, composite);
                    domainModel.getDeployedComposites().put(compositeName, composite);
                }
            }
        }
    }
     
    public void removeFromDomainLevelComposite(QName qname) throws DomainException {
        // TODO
    }
     
    public void startComposite(QName compositeName) throws DomainException {
        for (Node node : domainModel.getNodes().values()){
            boolean startNode = false;
           
            for (org.apache.tuscany.sca.domain.model.Contribution contribution : node.getContributions().values()){
                org.apache.tuscany.sca.domain.model.Composite composite =
                    contribution.getDeployableComposites().get(compositeName);
                if (composite != null) {
                    startNode = true;
                    break;
                }
            }
           
            if (startNode == true){
                // get the endpoint of the node in question and set it into the
                // domain manager node in order to flip the node reference to
                // the correct endpoint
                String nodeURL = node.getNodeURL();
                domainManagerNode.setNodeEndpoint(nodeURL);
               
               
                // get a node manager service reference. This will have to have its
                // physical endpoint set by the domain node manage we have just
                // configured
                NodeManagerService nodeManagerService = getService(NodeManagerService.class,
                                                        "NodeManagerComponent/NodeManagerService",
                                                        domainManagementRuntime,
                                                        domainManagementComposite);               
               
                // add contributions
                for (org.apache.tuscany.sca.domain.model.Contribution contribution : node.getContributions().values()){
                    nodeManagerService.addContribution(contribution.getContributionURI(),
                                                       contribution.getContributionURL().toString());
                }

                // deploy composite
                nodeManagerService.deployComposite(compositeName.toString());
               
                // start node
                nodeManagerService.start();
               
                // TODO
                // somewhere we need to add the deployed composites into the node model
               
                // reset the endpoint setting function
                domainManagerNode.setNodeEndpoint(null);
            }       
        }   
    }
     
    public void stopComposite(QName qname) throws DomainException {
        // TODO
    }
            
    public <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException {
        return (R)cast(target, domainManagementRuntime);
    }
   
    private <B, R extends CallableReference<B>> R cast(B target, ReallySmallRuntime runtime) throws IllegalArgumentException {
        return (R)runtime.getProxyFactory().cast(target);
    }

    public <B> B getService(Class<B> businessInterface, String serviceName) {
        return getService( businessInterface, serviceName, domainManagementRuntime, null);
    }
   
    private <B> B getService(Class<B> businessInterface, String serviceName, ReallySmallRuntime runtime, Composite domainComposite) {
       
        ServiceReference<B> serviceReference = getServiceReference(businessInterface, serviceName, runtime, domainComposite);
        if (serviceReference == null) {
            throw new ServiceRuntimeException("Service not found: " + serviceName);
        }
        return serviceReference.getService();
    }

    private <B> ServiceReference<B> createServiceReference(Class<B> businessInterface, String targetURI) {
        return createServiceReference(businessInterface, targetURI, domainManagementRuntime, null);
    }

   
    private <B> ServiceReference<B> createServiceReference(Class<B> businessInterface, String targetURI, ReallySmallRuntime runtime, Composite domainComposite) {
        try {
         
            AssemblyFactory assemblyFactory = runtime.getAssemblyFactory();
            Composite composite = assemblyFactory.createComposite();
            composite.setName(new QName(Constants.SCA10_TUSCANY_NS, "default"));
            RuntimeComponent component = (RuntimeComponent)assemblyFactory.createComponent();
            component.setName("default");
            component.setURI("default");
            runtime.getCompositeActivator().configureComponentContext(component);
            composite.getComponents().add(component);
            RuntimeComponentReference reference = (RuntimeComponentReference)assemblyFactory.createComponentReference();
            reference.setName("default");
            ModelFactoryExtensionPoint factories =
                runtime.getExtensionPointRegistry().getExtensionPoint(ModelFactoryExtensionPoint.class);
            JavaInterfaceFactory javaInterfaceFactory = factories.getFactory(JavaInterfaceFactory.class);
            InterfaceContract interfaceContract = javaInterfaceFactory.createJavaInterfaceContract();
            interfaceContract.setInterface(javaInterfaceFactory.createJavaInterface(businessInterface));
            reference.setInterfaceContract(interfaceContract);
            component.getReferences().add(reference);
            reference.setComponent(component);
            SCABindingFactory scaBindingFactory = factories.getFactory(SCABindingFactory.class);
            SCABinding binding = scaBindingFactory.createSCABinding();
            binding.setURI(targetURI);
            reference.getBindings().add(binding);      
            return new ServiceReferenceImpl<B>(businessInterface, component, reference, binding, runtime
                .getProxyFactory(), runtime.getCompositeActivator());
        } catch (Exception e) {
            throw new ServiceRuntimeException(e);
        }
    }



    public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, String name) {
        return getServiceReference(businessInterface, name, domainManagementRuntime, null);
    }

       
    private <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, String name, ReallySmallRuntime runtime, Composite domainComposite) {
       
        // Extract the component name
        String componentName;
        String serviceName;
        int i = name.indexOf('/');
        if (i != -1) {
            componentName = name.substring(0, i);
            serviceName = name.substring(i + 1);

        } else {
            componentName = name;
            serviceName = null;
        }

        // Lookup the component
        Component component = null;
        
        if ( domainComposite != null ) {
            for (Composite composite: domainComposite.getIncludes()) {
                for (Component compositeComponent: composite.getComponents()) {
                    if (compositeComponent.getName().equals(componentName)) {
                        component = compositeComponent;
                    }
                }
            }   
        }
      
        if (component == null) {
            // The component is not local in the partition, try to create a remote service ref
            return createServiceReference(businessInterface, name, runtime, domainComposite);
        }
        RuntimeComponentContext componentContext = null;

        // If the component is a composite, then we need to find the
        // non-composite component that provides the requested service
        if (component.getImplementation() instanceof Composite) {
            for (ComponentService componentService : component.getServices()) {
                if (serviceName == null || serviceName.equals(componentService.getName())) {
                    CompositeService compositeService = (CompositeService)componentService.getService();
                    if (compositeService != null) {
                        if (serviceName != null) {
                            serviceName = "$promoted$." + serviceName;
                        }
                        componentContext =
                            ((RuntimeComponent)compositeService.getPromotedComponent()).getComponentContext();
                        return componentContext.createSelfReference(businessInterface, compositeService
                            .getPromotedService());
                    }
                    break;
                }
            }
            // No matching service is found
            throw new ServiceRuntimeException("Composite service not found: " + name);
        } else {
            componentContext = ((RuntimeComponent)component).getComponentContext();
            if (serviceName != null) {
                return componentContext.createSelfReference(businessInterface, serviceName);
            } else {
                return componentContext.createSelfReference(businessInterface);
            }
        }
    }

}
TOP

Related Classes of org.apache.tuscany.sca.domain.impl.SCADomainImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.