/* * 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.workspace.configuration.impl; import java.net.InetAddress; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.net.UnknownHostException; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Logger; import org.apache.tuscany.sca.assembly.Binding; import org.apache.tuscany.sca.assembly.Component; import org.apache.tuscany.sca.assembly.ComponentProperty; import org.apache.tuscany.sca.assembly.ComponentReference; import org.apache.tuscany.sca.assembly.ComponentService; import org.apache.tuscany.sca.assembly.Composite; import org.apache.tuscany.sca.assembly.Implementation; import org.apache.tuscany.sca.assembly.Property; import org.apache.tuscany.sca.assembly.Reference; import org.apache.tuscany.sca.assembly.SCABinding; import org.apache.tuscany.sca.assembly.SCABindingFactory; import org.apache.tuscany.sca.assembly.Service; import org.apache.tuscany.sca.assembly.builder.ComponentPreProcessor; import org.apache.tuscany.sca.assembly.builder.CompositeBuilderException; import org.apache.tuscany.sca.assembly.builder.impl.CompositeBuilderImpl; import org.apache.tuscany.sca.assembly.xml.Constants; import org.apache.tuscany.sca.binding.BindingURICalculator; import org.apache.tuscany.sca.binding.DefaultBindingURICalculatorExtensionPoint; import org.apache.tuscany.sca.contribution.Contribution; import org.apache.tuscany.sca.contribution.Export; import org.apache.tuscany.sca.contribution.Import; import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.host.http.ServletMappingException; import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; import org.apache.tuscany.sca.interfacedef.impl.InterfaceContractMapperImpl; import org.apache.tuscany.sca.policy.IntentAttachPointType; import org.apache.tuscany.sca.policy.IntentAttachPointTypeFactory; import org.apache.tuscany.sca.policy.PolicySetAttachPoint; import org.apache.tuscany.sca.workspace.Workspace; /** * Changes the configuration of a composite to effect assignment to a node * * @version $Rev$ $Date$ */ public class NodeAssigner { private final static Logger logger = Logger.getLogger(NodeAssigner.class.getName()); SCABindingFactory scaBindingFactory; IntentAttachPointTypeFactory intentAttachPointTypeFactory; DefaultBindingURICalculatorExtensionPoint bindingURICalcualtorExtensionPoint; /** * Constructs a new NodeAssigner */ public NodeAssigner(ExtensionPointRegistry registry) { //Get factory extension point ModelFactoryExtensionPoint factories = registry.getExtensionPoint(ModelFactoryExtensionPoint.class); scaBindingFactory = factories.getFactory(SCABindingFactory.class); IntentAttachPointTypeFactory intentAttachPointTypeFactory = factories.getFactory(IntentAttachPointTypeFactory.class); //InterfaceContractMapper mapper = new InterfaceContractMapperImpl(); bindingURICalcualtorExtensionPoint = new DefaultBindingURICalculatorExtensionPoint(); } public void assignEndpointsToServiceBinding(NodeInfo nodeInfo, Composite composite, String uri){ String parentComponentURI = uri; // Process nested composites recursively for (Component component : composite.getComponents()) { // Initialize component URI String componentURI; if (parentComponentURI == null) { componentURI = component.getName(); } else { componentURI = URI.create(parentComponentURI + '/').resolve(component.getName()).toString(); } component.setURI(componentURI); Implementation implementation = component.getImplementation(); if (implementation instanceof Composite) { // Process nested composite assignEndpointsToServiceBinding(nodeInfo, (Composite)implementation, componentURI); } } // Initialize composite service binding URIs List compositeServices = composite.getServices(); for (Service service : compositeServices) { // Set default binding names // Create default SCA binding if (service.getBindings().isEmpty()) { SCABinding scaBinding = createSCABinding(); service.getBindings().add(scaBinding); } // Initialize binding names and URIs for (Binding binding : service.getBindings()) { constructBindingName(service, binding); constructBindingURI(parentComponentURI, composite, service, binding, nodeInfo); } } // Initialize component service binding URIs for (Component component : composite.getComponents()) { for (ComponentService service : component.getServices()) { // Create default SCA binding if (service.getBindings().isEmpty()) { SCABinding scaBinding = createSCABinding(); service.getBindings().add(scaBinding); } // Initialize binding names and URIs for (Binding binding : service.getBindings()) { constructBindingName(service, binding); constructBindingURI(component, service, binding, nodeInfo); } } } } private SCABinding createSCABinding() { SCABinding scaBinding = scaBindingFactory.createSCABinding(); IntentAttachPointType bindingType = intentAttachPointTypeFactory.createBindingType(); bindingType.setName(Constants.BINDING_SCA_QNAME); bindingType.setUnresolved(true); ((PolicySetAttachPoint)scaBinding).setType(bindingType); return scaBinding; } private void constructBindingName(Service service, Binding binding){ // set the default binding name if one is required // if there is no name on the binding then set it to the service name if (binding.getName() == null){ binding.setName(service.getName()); // if multiple bindings don't have a name raise an error as // binding must be uniquely named for (Binding serviceBinding : service.getBindings()){ if ((!binding.equals(serviceBinding)) && (serviceBinding.getName().equals(service.getName()))){ // TODO collate errors logger.warning("Multiple bindings for service " + service.getName() + " have no name"); } } } } /** * URI construction from Assembly spec section 1.7.2 * @return */ private void constructBindingURI(String parentComponentURI, Composite composite, Service service, Binding binding, NodeInfo nodeInfo ) { // This is a composite service so there is no component to provide a component URI // The path to this composite (through nested composites) is used. constructBindingURI(parentComponentURI, service, binding, composite.getServices().size() > 1, nodeInfo); } private void constructBindingURI(Component component, Service service, Binding binding, NodeInfo nodeInfo ) { String componentURIString = null; // if a URI is specified on the component use it otherwise use the component name if (component.getURI() != null){ componentURIString = component.getURI(); } else { componentURIString = component.getName(); } constructBindingURI(componentURIString, service, binding, component.getServices().size() > 1, nodeInfo); } private void constructBindingURI(String componentURIString, Service service, Binding binding, boolean includeServiceBindingURI, NodeInfo nodeInfo ){ try { URI baseURI = null; URI componentURI = null; URI serviceBindingURI = null; // calculate the service binding URI if (binding.getURI() == null){ serviceBindingURI = new URI(binding.getName()); } else { serviceBindingURI = new URI(binding.getURI()); } // if the user has provided an absolute binding URI then use it if (serviceBindingURI != null && serviceBindingURI.isAbsolute()){ binding.setURI(serviceBindingURI.toString()); return; } // calculate the component URI if (componentURIString != null) { componentURI = new URI(componentURIString); } else { componentURI = null; } // if the user has provided an absolute component URI then use it if (componentURI != null && componentURI.isAbsolute()){ binding.setURI(concatenateModelURI(null, componentURI, serviceBindingURI, includeServiceBindingURI).toString()); return; } // calculate the base URI // get the protocol for this binding/URI BindingURICalculator uriCalculator = bindingURICalcualtorExtensionPoint.getBindingURICalculator(binding); if (uriCalculator != null){ logger.warning("Binding calculator found for binding " + binding.getName() + " " + binding.getClass().getName()); String protocol = uriCalculator.getProtocol(binding); // find the default binding with the right protocol Binding defaultBinding = nodeInfo.getBindingDefault(binding, protocol); if (defaultBinding != null){ baseURI = new URI(defaultBinding.getURI()); } else { baseURI = null; } } else { logger.warning("Binding calculator not found for binding " + binding.getName() + " " + binding.getClass().getName()); baseURI = null; } binding.setURI(concatenateModelURI(baseURI, componentURI, serviceBindingURI,includeServiceBindingURI).toString()); } catch (Exception ex){ // TODO collate errors logger.warning("Error during URL creation " + ex.toString()); } } private URI concatenateModelURI(URI baseURI, URI componentURI, URI serviceBindingURI, boolean includeServiceBindingURI){ if (baseURI == null){ if (componentURI == null){ return serviceBindingURI; } else { if (includeServiceBindingURI){ return componentURI.resolve("/").resolve(serviceBindingURI); } else { return componentURI; } } } else { if (componentURI == null){ if (includeServiceBindingURI){ return baseURI.resolve("/").resolve(serviceBindingURI); } else { return baseURI; } } else { if (includeServiceBindingURI){ return baseURI.resolve("/").resolve(componentURI).resolve("/").resolve(serviceBindingURI); } else { return baseURI.resolve("/").resolve(componentURI); } } } } }