Use sca-config XML files for SCA binding/policy definitions

git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@830339 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
rfeng 2009-10-27 21:04:51 +00:00
parent 49992e45cb
commit 5cfd47acaa
33 changed files with 733 additions and 602 deletions

View file

@ -79,7 +79,6 @@ public interface Constants {
String REPLACE = "replace";
String REQUIRES = "requires";
String POLICY_SETS = "policySets";
String APPLICABLE_POLICY_SETS = "applicablePolicySets";
String PROMOTE = "promote";
String TARGET = "target";
String WIRED_BY_IMPL = "wiredByImpl";

View file

@ -53,10 +53,8 @@ import org.apache.tuscany.sca.policy.PolicySet;
* @version $Rev$ $Date$
*/
public class DefinitionsProcessor extends BaseStAXArtifactProcessor implements StAXArtifactProcessor<Definitions> {
private StAXArtifactProcessor<Object> extensionProcessor;
private DefinitionsFactory definitionsFactory;
public static final String SCA11_NS = "http://docs.oasis-open.org/ns/opencsa/sca/200903";
public static final String BINDING = "binding";
@ -144,6 +142,10 @@ public class DefinitionsProcessor extends BaseStAXArtifactProcessor implements S
for (PolicySet policySet : definitions.getPolicySets()) {
extensionProcessor.write(policySet, writer, context);
}
for (Binding binding : definitions.getBindings()) {
extensionProcessor.write(binding, writer, context);
}
for (BindingType bindingType : definitions.getBindingTypes()) {
extensionProcessor.write(bindingType, writer, context);
@ -203,7 +205,11 @@ public class DefinitionsProcessor extends BaseStAXArtifactProcessor implements S
for (PolicySet policySet : referredPolicySets)
extensionProcessor.resolve(policySet, resolver, context);
for (Binding binding : scaDefns.getBindings()) {
extensionProcessor.resolve(binding, resolver, context);
}
for (BindingType bindingType : scaDefns.getBindingTypes()) {
extensionProcessor.resolve(bindingType, resolver, context);
}

View file

@ -22,6 +22,7 @@ import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import org.apache.tuscany.sca.extensibility.ServiceDeclaration;
import org.apache.tuscany.sca.extensibility.ServiceDiscovery;
@ -103,11 +104,19 @@ public class DefaultModelResolverExtensionPoint implements ModelResolverExtensio
}
// Load model resolvers
for (ServiceDeclaration modelResolverDeclaration: modelResolverDeclarations) {
for (ServiceDeclaration modelResolverDeclaration : modelResolverDeclarations) {
Map<String, String> attributes = modelResolverDeclaration.getAttributes();
String model = attributes.get("model");
// The model can be a list of interfaces so that one model resolver can be used
// to resolve different types of models
if (model != null) {
StringTokenizer tokenizer = new StringTokenizer(model);
while (tokenizer.hasMoreTokens()) {
String key = tokenizer.nextToken();
loadedResolvers.put(key, modelResolverDeclaration);
}
loadedResolvers.put(model, modelResolverDeclaration);
}
}
}

View file

@ -78,7 +78,7 @@ public class OSGiDistributionProvider {
props.put(PRODUCT_NAME, "Apache Tuscany SCA");
props.put(PRODUCT_VERSION, headers.get(Constants.BUNDLE_VERSION));
props.put(VENDOR_NAME, headers.get(Constants.BUNDLE_VENDOR));
props.put(REMOTE_CONFIGS_SUPPORTED, new String[] {"sca"});
props.put(REMOTE_CONFIGS_SUPPORTED, new String[] {"org.osgi.sca"});
// FIXME: We need to populate the list of intents from the SCA definitions
props.put(REMOTE_INTENTS_SUPPORTED, new String[] {});
return props;

View file

@ -18,6 +18,7 @@ Import-Package: javax.xml.namespace,
org.apache.tuscany.sca.contribution.processor;version="2.0.0",
org.apache.tuscany.sca.contribution.resolver;version="2.0.0",
org.apache.tuscany.sca.core;version="2.0.0",
org.apache.tuscany.sca.definitions;version="2.0.0",
org.apache.tuscany.sca.implementation.osgi;version="2.0.0",
org.apache.tuscany.sca.interfacedef;version="2.0.0",
org.apache.tuscany.sca.interfacedef.java;version="2.0.0",

View file

@ -1,34 +0,0 @@
/*
* 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.implementation.osgi;
import java.util.List;
import javax.xml.namespace.QName;
import org.apache.tuscany.sca.assembly.Binding;
/**
* OSGi RFC 119 SCA binding descriptions
*/
public interface BindingDescriptions extends List<Binding> {
String OSGI_SD_NS = ServiceDescriptions.OSGI_SD_NS;
QName BINDINGS_QNAME = new QName(OSGI_SD_NS, "bindings");
}

View file

@ -28,85 +28,103 @@ public interface OSGiProperty {
String NAME = "name";
QName PROPERTY_QNAME = new QName(OSGiImplementation.SCA11_TUSCANY_NS, "osgi.property");
String SCA_BINDINGS = "sca.bindings";
String REMOTE_CONFIG_SCA = "org.osgi.sca";
String SCA_BINDINGS = "org.osgi.sca.bindings";
String SCA_REFERENCE = "sca.reference";
String SCA_SERVICE = "sca.service";
String SCA_REFERENCE_BINDING = "sca.reference.binding";
String SCA_SERVICE_BINDING = "sca.service.binding";
String REMOTE_CONFIG_SCA = "sca";
/**
* The configuration types supported by this Distribution Provider. Services
* that are suitable for distribution list the configuration types that
* describe the configuration information for that service in the
* SERVICE_EXPORTED_CONFIGS or SERVICE_IMPORTED_CONFIGS property. A
* distribution provider must register a service that has this property and
* enumerate all configuration types that it supports. The type of this
* property String+
* The configuration types supported by this Distribution Provider.
*
* @see SERVICE_EXPORTED_CONFIGS
* @see SERVICE_IMPORTED_CONFIGS
* Services that are suitable for distribution list the configuration types
* that describe the configuration information for that service in the
* {@link #SERVICE_EXPORTED_CONFIGS} or {@link #SERVICE_IMPORTED_CONFIGS}
* property.
*
* A distribution provider must register a service that has this property
* and enumerate all configuration types that it supports.
*
* The type of this property <code>String+</code>
*
* @see #SERVICE_EXPORTED_CONFIGS
* @see #SERVICE_IMPORTED_CONFIGS
*/
String REMOTE_CONFIGS_SUPPORTED = "remote.configs.supported";
public final static String REMOTE_CONFIGS_SUPPORTED = "remote.configs.supported";
/**
* Service property that lists the intents supported by the distribution
* provider. Each distribution provider must register a service that has
* this property and enumerate all the supported intents, having any
* qualified intents expanded. The value of this property is of type
* String+.
* provider.
*
* @see SERVICE_INTENTS
* @see SERVICE_EXPORTED_INTENTS
* @see SERVICE_EXPORTED_INTENTS_EXTRA
* Each distribution provider must register a service that has this property
* and enumerate all the supported intents, having any qualified intents
* expanded.
*
* The value of this property is of type <code>String+</code>.
*
* @see #SERVICE_INTENTS
* @see #SERVICE_EXPORTED_INTENTS
* @see #SERVICE_EXPORTED_INTENTS_EXTRA
*/
String REMOTE_INTENTS_SUPPORTED = "remote.intents.supported";
public final static String REMOTE_INTENTS_SUPPORTED = "remote.intents.supported";
/**
* A list of configuration types that should be used to export the service.
* Configuration types can be synonymous or alternatives. In principle, a
* distribution provider should create an endpoint for each recognized
* configuration type, the deployer is responsible that synonyms do not
* clash. Each configuration type has an associated specification that
* describes how the configuration data for the exported service is
* represented in an OSGi framework. The value of this property is of type
* String+.
*
* Configuration types can be <em>synonymous</em> or <em>alternatives</em>.
* In principle, a distribution provider should create an endpoint for each
* recognized configuration type, the deployer is responsible that synonyms
* do not clash.
*
* Each configuration type has an associated specification that describes
* how the configuration data for the exported service is represented in an
* OSGi framework.
*
* The value of this property is of type <code>String+</code>.
*/
String SERVICE_EXPORTED_CONFIGS = "service.exported.configs";
public final static String SERVICE_EXPORTED_CONFIGS = "service.exported.configs";
/**
* A list of intents that the distribution provider must implement to
* distribute the service. Intents listed in this property are reserved for
* intents that are critical for the code to function correctly, for
* example, ordering of messages. These intents should not be configurable.
* The value of this property is of type String+.
*
* The value of this property is of type <code>String+</code>.
*/
String SERVICE_EXPORTED_INTENTS = "service.exported.intents";
public final static String SERVICE_EXPORTED_INTENTS = "service.exported.intents";
/**
* Extra intents configured in addition to the the intents specified in
* SERVICE_EXPORTED_INTENTS. These intents are merged with the service.
* exported.intents and therefore have the same semantics. They are extra,
* so that the SERVICE_EXPORTED_INTENTS can be set by the bundle developer
* and this property is then set by the administrator/deployer. Bundles
* should make this property configurable, for example through the
* Configuration Admin service. The value of this property is of type
* String+.
* {@link #SERVICE_EXPORTED_INTENTS}.
*
* These intents are merged with the service.exported.intents and therefore
* have the same semantics. They are extra, so that the
* {@link #SERVICE_EXPORTED_INTENTS} can be set by the bundle developer and
* this property is then set by the administrator/deployer. Bundles should
* make this property configurable, for example through the Configuration
* Admin service.
*
* The value of this property is of type <code>String+</code>.
*/
String SERVICE_EXPORTED_INTENTS_EXTRA = "service.exported.intents.extra";
public final static String SERVICE_EXPORTED_INTENTS_EXTRA = "service.exported.intents.extra";
/**
* Defines the interfaces under which this service can be exported. This
* list must be a subset of the types listed in the objectClass service
* property. The single value of an asterisk ('*' *) indicates all
* Defines the interfaces under which this service can be exported.
*
* This list must be a subset of the types listed in the objectClass service
* property. The single value of an asterisk ('*' \u002A) indicates all
* interfaces in the registration's objectClass property (not classes). It
* is highly recommended to only export interfaces and not concrete classes
* due to the complexity of creating proxies for some type of classes. The
* value of this property is of type String+.
* due to the complexity of creating proxies for some type of classes.
*
* The value of this property is of type String+.
*/
String SERVICE_EXPORTED_INTERFACES = "service.exported.interfaces";
public final static String SERVICE_EXPORTED_INTERFACES = "service.exported.interfaces";
/**
* Must be set by a distribution provider to true when it registers the
* end-point proxy as an imported service. Can be used by a bundle to
* prevent it from getting an imported service. The value of this property
* is not defined, setting it is sufficient.
* Must be set by a distribution provider to <code>true</code> when it
* registers the end-point proxy as an imported service. Can be used by a
* bundle to prevent it from getting an imported service.
*
* The value of this property is not defined, setting it is sufficient.
*/
String SERVICE_IMPORTED = "service.imported";
public final static String SERVICE_IMPORTED = "service.imported";
/**
* A list of intents that this service implements. This property has dual
* purpose. A bundle can use this service property to notify the
@ -115,19 +133,41 @@ public interface OSGiProperty {
* must use this property to convey the combined intents of the exporting
* service and the intents that the distribution providers add. To export a
* service, a distribution provider must recognize all these intents and
* expand any qualified intents. The value of this property is of type
* String+.
* expand any qualified intents.
*
* The value of this property is of type <code>String+</code>.
*/
String SERVICE_INTENTS = "service.intents";
public final static String SERVICE_INTENTS = "service.intents";
/**
* The property key for the endpoint service id. This is a unique id for a
* service based on the framework id '.' service id or another model. As far as this specification is
* concerned, this unique id is opaque.
*/
final public static String SERVICE_REMOTE_FRAMEWORK_UUID = "service.remote.framework.id";
/**
* The property key for the endpoint service id. This is a unique id for a
* service based on the framework id '.' service id or another model. As far as this specification is
* concerned, this unique id is opaque.
*/
final public static String SERVICE_REMOTE_ID = "service.remote.id";
/**
* The property key for the endpoint URI. This is a unique id for an
* endpoint following the URI syntax. As far as this specification is
* concerned, this unique id is opaque.
*/
final public static String SERVICE_REMOTE_URI = "service.remote.uri";
/**
* The configuration type used to import this services, as described in
* SERVICE_EXPORTED_CONFIGS. Any associated properties for this
* {@link #SERVICE_EXPORTED_CONFIGS}. Any associated properties for this
* configuration types must be properly mapped to the importing system. For
* example, a URL in these properties must point to a valid resource when
* used in the importing framework. Configuration types in this property
* must be synonymous. The value of this property is of type String+.
* must be synonymous.
*
* The value of this property is of type <code>String+</code>.
*/
String SERVICE_IMPORTED_CONFIGS = "service.imported.configs";
public final String SERVICE_IMPORTED_CONFIGS = "service.imported.configs";
String getValue();

View file

@ -0,0 +1,65 @@
/*
* 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.implementation.osgi;
import java.util.List;
import org.apache.tuscany.sca.assembly.Binding;
import org.apache.tuscany.sca.policy.Intent;
import org.apache.tuscany.sca.policy.PolicySet;
/**
*
*/
public interface SCAConfig {
/**
* Returns the target namespace for this SCA Definition
* @return the target namespace
*/
String getTargetNamespace();
/**
* Sets the target names for this SCA Definition.
*
* @param ns the target namespace for this SCA Definition
*/
void setTargetNamespace(String ns);
/**
* Returns a list of domain wide Policy Intents
*
* @return a list of domain wide Policy Intents
*/
List<Intent> getIntents();
/**
* Returns a list of domain wide PolicySets
*
* @return a list of domain wide PolicySets
*/
List<PolicySet> getPolicySets();
/**
* Returns a list of domain wide binding definition objects
*
* @return a list of domain wide binding definition objects
*/
List<Binding> getBindings();
}

View file

@ -26,6 +26,6 @@ public interface ServiceDescriptionsFactory {
ServiceDescriptions createServiceDescriptions();
ServiceDescription createServiceDescription();
BindingDescriptions createBindingDescriptions();
SCAConfig createSCAConfig();
}

View file

@ -19,18 +19,40 @@
package org.apache.tuscany.sca.implementation.osgi.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import org.apache.tuscany.sca.assembly.Binding;
import org.apache.tuscany.sca.implementation.osgi.BindingDescriptions;
import org.apache.tuscany.sca.implementation.osgi.SCAConfig;
import org.apache.tuscany.sca.policy.Intent;
import org.apache.tuscany.sca.policy.PolicySet;
/**
*
*/
public class BindingDescriptionsImpl extends ArrayList<Binding> implements BindingDescriptions {
private static final long serialVersionUID = 7647814680087128002L;
public class SCAConfigImpl implements SCAConfig {
private String targetNamespace = null;
private List<Intent> intents = new CopyOnWriteArrayList<Intent>();
private List<PolicySet> policySets = new CopyOnWriteArrayList<PolicySet>();
private List<Binding> bindings = new CopyOnWriteArrayList<Binding>();
public BindingDescriptionsImpl() {
super();
public List<Intent> getIntents() {
return intents;
}
public List<PolicySet> getPolicySets() {
return policySets;
}
public String getTargetNamespace() {
return targetNamespace;
}
public void setTargetNamespace(String ns) {
this.targetNamespace = ns;
}
public List<Binding> getBindings() {
return bindings;
}
}

View file

@ -19,7 +19,7 @@
package org.apache.tuscany.sca.implementation.osgi.impl;
import org.apache.tuscany.sca.implementation.osgi.BindingDescriptions;
import org.apache.tuscany.sca.implementation.osgi.SCAConfig;
import org.apache.tuscany.sca.implementation.osgi.ServiceDescription;
import org.apache.tuscany.sca.implementation.osgi.ServiceDescriptions;
import org.apache.tuscany.sca.implementation.osgi.ServiceDescriptionsFactory;
@ -41,8 +41,8 @@ public class ServiceDescriptionsFactoryImpl implements ServiceDescriptionsFactor
return new ServiceDescriptionsImpl();
}
public BindingDescriptions createBindingDescriptions() {
return new BindingDescriptionsImpl();
public SCAConfig createSCAConfig() {
return new SCAConfigImpl();
}
}

View file

@ -1,114 +0,0 @@
/*
* 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.implementation.osgi.xml;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import org.apache.tuscany.sca.assembly.Binding;
import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
import org.apache.tuscany.sca.contribution.processor.ContributionWriteException;
import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
import org.apache.tuscany.sca.core.ExtensionPointRegistry;
import org.apache.tuscany.sca.core.FactoryExtensionPoint;
import org.apache.tuscany.sca.implementation.osgi.BindingDescriptions;
import org.apache.tuscany.sca.implementation.osgi.ServiceDescriptionsFactory;
/*
<?xml version="1.0" encoding="UTF-8"?>
<bindings xmlns="http://www.osgi.org/xmlns/sd/v1.0.0" xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200903">
<binding.ws/>
<binding.sca/>
</bindings>
*/
public class BindingDescriptionsProcessor implements StAXArtifactProcessor<BindingDescriptions> {
private StAXArtifactProcessor processor;
private ServiceDescriptionsFactory factory;
public BindingDescriptionsProcessor(ExtensionPointRegistry registry,
StAXArtifactProcessor processor) {
this.processor = processor;
this.factory =
registry.getExtensionPoint(FactoryExtensionPoint.class).getFactory(ServiceDescriptionsFactory.class);
}
public BindingDescriptions read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException {
BindingDescriptions bindings = factory.createBindingDescriptions();
boolean exit = false;
while (!exit) {
int event = reader.getEventType();
switch (event) {
case XMLStreamConstants.START_ELEMENT:
QName name = reader.getName();
if (!"bindings".equals(name.getLocalPart())) {
Object element = null;
try {
element = processor.read(reader, context);
} catch (ContributionReadException e) {
throw e;
}
if (element instanceof Binding) {
bindings.add((Binding)element);
}
}
break;
case XMLStreamConstants.END_ELEMENT:
name = reader.getName();
if ("bindings".equals(name.getLocalPart())) {
exit = true;
}
break;
}
if (reader.hasNext()) {
reader.next();
} else {
exit = true;
}
}
return bindings;
}
public QName getArtifactType() {
return BindingDescriptions.BINDINGS_QNAME;
}
public void write(BindingDescriptions model, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException,
XMLStreamException {
writer.writeStartElement(BindingDescriptions.OSGI_SD_NS, "bindings");
for (Binding binding : model) {
processor.write(model, writer, context);
}
writer.writeEndElement();
}
public Class<BindingDescriptions> getModelType() {
return BindingDescriptions.class;
}
public void resolve(BindingDescriptions model, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException {
// TODO: To be implemented
}
}

View file

@ -0,0 +1,190 @@
/*
* 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.implementation.osgi.xml;
import java.util.ArrayList;
import java.util.List;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
import org.apache.tuscany.sca.assembly.Binding;
import org.apache.tuscany.sca.contribution.processor.BaseStAXArtifactProcessor;
import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
import org.apache.tuscany.sca.contribution.processor.ContributionWriteException;
import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
import org.apache.tuscany.sca.core.ExtensionPointRegistry;
import org.apache.tuscany.sca.core.FactoryExtensionPoint;
import org.apache.tuscany.sca.implementation.osgi.SCAConfig;
import org.apache.tuscany.sca.implementation.osgi.ServiceDescriptionsFactory;
import org.apache.tuscany.sca.policy.Intent;
import org.apache.tuscany.sca.policy.PolicySet;
/*
<?xml version="1.0" encoding="UTF-8"?>
<scact:sca-config targetNamespace="http://www.foocorp.com/definitions"
xmlns:scact="http://www.osgi.org/xmlns/scact/v1.0.0"
xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200903"
xmlns:foocorp="http://www.foocorp.com/definitions"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.osgi.org/xmlns/scact/v1.0.0 http://www.osgi.org/xmlns/scact/v1.0.0/sca-config.xsd">
<sca:binding.ws name="com.foocorp.FooOrderWebServiceBinding"
uri="http://www.foocorp.com/FooOrderService" requires="sca:soap.1_2" />
<foocorp:binding.rmi name="com.foocorp.FooOrderRMIBinding"
host="www.foocorp.com" port="8099" serviceName="FooOrderService" />
</scact:sca-config>
*/
public class SCAConfigProcessor extends BaseStAXArtifactProcessor implements StAXArtifactProcessor<SCAConfig> {
private static final QName SCA_CONFIG_QNAME = new QName("http://www.osgi.org/xmlns/scact/v1.0.0", "sca-config");
private ServiceDescriptionsFactory factory;
private StAXArtifactProcessor processor;
public SCAConfigProcessor(ExtensionPointRegistry registry, StAXArtifactProcessor processor) {
this.processor = processor;
FactoryExtensionPoint modelFactories = registry.getExtensionPoint(FactoryExtensionPoint.class);
this.factory = modelFactories.getFactory(ServiceDescriptionsFactory.class);
}
public SCAConfig read(XMLStreamReader reader, ProcessorContext context) throws XMLStreamException,
ContributionReadException {
int event = reader.getEventType();
SCAConfig definitions = factory.createSCAConfig();
String targetNamespace = null;
while (true) {
switch (event) {
case XMLStreamConstants.START_ELEMENT:
QName name = reader.getName();
if (SCA_CONFIG_QNAME.equals(name)) {
targetNamespace = reader.getAttributeValue(null, "targetNamespace");
definitions.setTargetNamespace(targetNamespace);
} else {
Object extension = processor.read(reader, context);
if (extension != null) {
if (extension instanceof Intent) {
Intent intent = (Intent)extension;
intent.setName(new QName(targetNamespace, intent.getName().getLocalPart()));
definitions.getIntents().add(intent);
for (Intent i : intent.getQualifiedIntents()) {
i.setName(new QName(targetNamespace, i.getName().getLocalPart()));
}
} else if (extension instanceof PolicySet) {
PolicySet policySet = (PolicySet)extension;
policySet.setName(new QName(targetNamespace, policySet.getName().getLocalPart()));
definitions.getPolicySets().add(policySet);
} else if (extension instanceof Binding) {
Binding binding = (Binding)extension;
definitions.getBindings().add(binding);
}
}
}
break;
case XMLStreamConstants.END_ELEMENT:
name = reader.getName();
if (SCA_CONFIG_QNAME.equals(name)) {
return definitions;
}
break;
}
if (reader.hasNext()) {
event = reader.next();
} else {
return definitions;
}
}
}
public QName getArtifactType() {
return SCA_CONFIG_QNAME;
}
public void write(SCAConfig definitions, XMLStreamWriter writer, ProcessorContext context)
throws ContributionWriteException, XMLStreamException {
writeStartDocument(writer,
SCA_CONFIG_QNAME.getNamespaceURI(),
SCA_CONFIG_QNAME.getLocalPart(),
new XAttr("targetNamespace", definitions.getTargetNamespace()));
for (Intent policyIntent : definitions.getIntents()) {
processor.write(policyIntent, writer, context);
}
for (PolicySet policySet : definitions.getPolicySets()) {
processor.write(policySet, writer, context);
}
writeEndDocument(writer);
}
public void resolve(SCAConfig scaDefns, ModelResolver resolver, ProcessorContext context)
throws ContributionResolveException {
// start by adding all of the top level artifacts into the resolver as there
// are many cross artifact references in a definitions file and we don't want
// to be dependent on the order things appear
List<Intent> intents = new ArrayList<Intent>();
List<PolicySet> policySets = new ArrayList<PolicySet>();
List<PolicySet> referredPolicySets = new ArrayList<PolicySet>();
for (Intent intent : scaDefns.getIntents()) {
intents.add(intent);
resolver.addModel(intent, context);
for (Intent i : intent.getQualifiedIntents()) {
intents.add(i);
resolver.addModel(i, context);
}
}
for (PolicySet policySet : scaDefns.getPolicySets()) {
if (policySet.getReferencedPolicySets().isEmpty()) {
policySets.add(policySet);
} else {
referredPolicySets.add(policySet);
}
resolver.addModel(policySet, context);
}
// now resolve everything to ensure that any references between
// artifacts are satisfied
for (Intent policyIntent : intents)
processor.resolve(policyIntent, resolver, context);
for (PolicySet policySet : policySets)
processor.resolve(policySet, resolver, context);
for (PolicySet policySet : referredPolicySets)
processor.resolve(policySet, resolver, context);
}
public Class<SCAConfig> getModelType() {
return SCAConfig.class;
}
}

View file

@ -19,4 +19,4 @@
org.apache.tuscany.sca.implementation.osgi.xml.OSGiImplementationProcessor;qname=http://tuscany.apache.org/xmlns/sca/1.1#implementation.osgi,model=org.apache.tuscany.sca.implementation.osgi.OSGiImplementation
org.apache.tuscany.sca.implementation.osgi.xml.ServiceDescriptionsProcessor;qname=http://www.osgi.org/xmlns/sd/v1.0.0#service-descriptions,model=org.apache.tuscany.sca.implementation.osgi.ServiceDescriptions
org.apache.tuscany.sca.implementation.osgi.xml.OSGiPropertyProcessor;qname=http://tuscany.apache.org/xmlns/sca/1.1#osgi.property,model=org.apache.tuscany.sca.implementation.osgi.OSGiProperty
org.apache.tuscany.sca.implementation.osgi.xml.BindingDescriptionsProcessor;qname=http://www.osgi.org/xmlns/sd/v1.0.0#bindings,model=org.apache.tuscany.sca.implementation.osgi.BindingDescriptions
org.apache.tuscany.sca.implementation.osgi.xml.SCAConfigProcessor;qname=http://www.osgi.org/xmlns/scact/v1.0.0#sca-config,model=org.apache.tuscany.sca.implementation.osgi.SCAConfig

View file

@ -24,6 +24,7 @@ Import-Package: javax.xml.namespace,
org.apache.tuscany.sca.definitions;version="2.0.0",
org.apache.tuscany.sca.definitions.util;version="2.0.0",
org.apache.tuscany.sca.definitions.xml;version="2.0.0",
org.apache.tuscany.sca.deployment;version="2.0.0",
org.apache.tuscany.sca.extensibility.equinox;version="2.0.0",
org.apache.tuscany.sca.implementation.osgi;version="2.0.0",
org.apache.tuscany.sca.interfacedef;version="2.0.0",

View file

@ -21,8 +21,8 @@ package org.apache.tuscany.sca.node.osgi.impl;
import static org.apache.tuscany.sca.node.osgi.impl.NodeManager.isSCABundle;
import org.apache.tuscany.sca.osgi.remoteserviceadmin.impl.TopologyManagerImpl;
import org.apache.tuscany.sca.osgi.remoteserviceadmin.impl.RemoteServiceAdminImpl;
import org.apache.tuscany.sca.osgi.remoteserviceadmin.impl.TopologyManagerImpl;
import org.apache.tuscany.sca.osgi.service.discovery.impl.DiscoveryActivator;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
@ -63,14 +63,11 @@ public class NodeActivator implements BundleActivator, SynchronousBundleListener
remoteAdmin = new RemoteServiceAdminImpl(context);
remoteAdmin.start();
discoveryActivator.start(context);
controller = new TopologyManagerImpl(context);
controller.start();
// exporter = new OSGiServiceExporter(context);
// exporter.start();
discoveryActivator.start(context);
boolean found = false;
for (Bundle b : context.getBundles()) {
if (isSCABundle(b)) {

View file

@ -28,10 +28,6 @@ import static org.osgi.framework.Constants.OBJECTCLASS;
import static org.osgi.framework.Constants.SERVICE_ID;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@ -44,10 +40,7 @@ import java.util.Set;
import java.util.UUID;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import org.apache.tuscany.sca.assembly.AssemblyFactory;
import org.apache.tuscany.sca.assembly.Base;
@ -62,50 +55,48 @@ import org.apache.tuscany.sca.assembly.Service;
import org.apache.tuscany.sca.contribution.Contribution;
import org.apache.tuscany.sca.contribution.ContributionFactory;
import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor;
import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint;
import org.apache.tuscany.sca.contribution.resolver.ExtensibleModelResolver;
import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
import org.apache.tuscany.sca.contribution.resolver.ModelResolverExtensionPoint;
import org.apache.tuscany.sca.core.ExtensionPointRegistry;
import org.apache.tuscany.sca.core.FactoryExtensionPoint;
import org.apache.tuscany.sca.core.UtilityExtensionPoint;
import org.apache.tuscany.sca.implementation.osgi.BindingDescriptions;
import org.apache.tuscany.sca.deployment.Deployer;
import org.apache.tuscany.sca.implementation.osgi.OSGiImplementation;
import org.apache.tuscany.sca.implementation.osgi.OSGiImplementationFactory;
import org.apache.tuscany.sca.implementation.osgi.OSGiProperty;
import org.apache.tuscany.sca.implementation.osgi.ServiceDescriptionsFactory;
import org.apache.tuscany.sca.implementation.osgi.SCAConfig;
import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
import org.apache.tuscany.sca.monitor.MonitorFactory;
import org.apache.tuscany.sca.osgi.remoteserviceadmin.EndpointDescription;
import org.apache.tuscany.sca.osgi.service.discovery.impl.LocalDiscoveryService;
import org.apache.tuscany.sca.osgi.service.discovery.impl.LocalDiscoveryService.ExtenderConfiguration;
import org.apache.tuscany.sca.policy.Intent;
import org.apache.tuscany.sca.policy.PolicyFactory;
import org.oasisopen.sca.ServiceRuntimeException;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
/**
* Introspect an OSGi Service to create an SCA composite that contains a single component with
* implementation.osgi
*/
public class EndpointIntrospector {
private BundleContext context;
private AssemblyFactory assemblyFactory;
private ContributionFactory contributionFactory;
private OSGiImplementationFactory implementationFactory;
private ServiceDescriptionsFactory serviceDescriptionsFactory;
private PolicyFactory policyFactory;
private ExtensionPointRegistry registry;
private FactoryExtensionPoint factories;
private ModelResolverExtensionPoint modelResolvers;
private XMLInputFactory xmlInputFactory;
private XMLOutputFactory xmlOutputFactory;
private JavaInterfaceFactory javaInterfaceFactory;
private StAXArtifactProcessor processor;
private Deployer deployer;
private ServiceTracker discoveryTracker;
/**
* @param intentName
@ -131,8 +122,10 @@ public class EndpointIntrospector {
* @param context TODO
* @param registry
*/
public EndpointIntrospector(BundleContext context, ExtensionPointRegistry registry) {
public EndpointIntrospector(BundleContext context, ExtensionPointRegistry registry, ServiceTracker discoveryTracker) {
super();
this.context = context;
this.discoveryTracker = discoveryTracker;
this.registry = registry;
this.factories = registry.getExtensionPoint(FactoryExtensionPoint.class);
this.modelResolvers = registry.getExtensionPoint(ModelResolverExtensionPoint.class);
@ -140,15 +133,8 @@ public class EndpointIntrospector {
this.contributionFactory = factories.getFactory(ContributionFactory.class);
this.policyFactory = factories.getFactory(PolicyFactory.class);
this.implementationFactory = factories.getFactory(OSGiImplementationFactory.class);
this.serviceDescriptionsFactory = factories.getFactory(ServiceDescriptionsFactory.class);
this.xmlInputFactory = factories.getFactory(XMLInputFactory.class);
this.xmlOutputFactory = factories.getFactory(XMLOutputFactory.class);
this.javaInterfaceFactory = factories.getFactory(JavaInterfaceFactory.class);
StAXArtifactProcessorExtensionPoint processors =
registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
UtilityExtensionPoint utilities = this.registry.getExtensionPoint(UtilityExtensionPoint.class);
MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class);
processor = new ExtensibleStAXArtifactProcessor(processors, xmlInputFactory, xmlOutputFactory);
this.deployer = registry.getExtensionPoint(UtilityExtensionPoint.class).getUtility(Deployer.class);
}
private Intent getIntent(String intent) {
@ -278,8 +264,8 @@ public class EndpointIntrospector {
String[] objectClasses = getStrings(reference.getProperty(OBJECTCLASS));
Set<String> objectClassSet = new HashSet<String>(Arrays.asList(objectClasses));
if (!objectClassSet.containsAll(Arrays.asList(remoteInterfaces))) {
throw new IllegalArgumentException("The exported interfaces are not a subset of the types"
+ " listed in the objectClass service property from the Service Reference");
throw new IllegalArgumentException(
"The exported interfaces are not a subset of the types" + " listed in the objectClass service property from the Service Reference");
}
}
for (String intf : remoteInterfaces) {
@ -311,8 +297,8 @@ public class EndpointIntrospector {
String[] requiredIntentsExtra = getStrings(properties.get(SERVICE_EXPORTED_INTENTS_EXTRA));
List<Intent> extraIntents = getIntents(requiredIntentsExtra);
String[] bindingDocuments = getStrings(properties.get(SCA_BINDINGS));
List<Binding> bindings = loadBindings(reference.getBundle(), bindingDocuments);
String[] bindingNames = getStrings(properties.get(SCA_BINDINGS));
Collection<Binding> bindings = loadBindings(bindingNames);
for (ComponentService componentService : component.getServices()) {
componentService.getRequiredIntents().addAll(intents);
@ -332,7 +318,7 @@ public class EndpointIntrospector {
}
public Contribution introspect(Bundle bundle, EndpointDescription endpoint) throws Exception {
Endpoint ep = (Endpoint) endpoint.getProperties().get(Endpoint.class.getName());
Endpoint ep = (Endpoint)endpoint.getProperties().get(Endpoint.class.getName());
if (ep != null) {
return introspect(bundle, ep);
}
@ -382,19 +368,12 @@ public class EndpointIntrospector {
String[] requiredIntents = getStrings(properties.get(SERVICE_EXPORTED_INTENTS));
List<Intent> intents = getIntents(requiredIntents);
String[] bindingDocuments = getStrings(properties.get(SCA_BINDINGS));
List<Binding> bindings = loadBindings(bundle, bindingDocuments);
List<Binding> bindingList = new ArrayList<Binding>(bindings);
BindingDescriptions bindingDescriptions =
(BindingDescriptions)properties.get(BindingDescriptions.BINDINGS_QNAME.toString());
if (bindingDescriptions != null) {
bindingList.addAll(bindingDescriptions);
}
String[] bindingNames = getStrings(properties.get(SCA_BINDINGS));
Collection<Binding> bindings = loadBindings(bindingNames);
for (ComponentReference componentReference : component.getReferences()) {
componentReference.getRequiredIntents().addAll(intents);
componentReference.getBindings().addAll(bindingList);
componentReference.getBindings().addAll(bindings);
}
// FIXME: Should we scan the owning bundle to create the SCA contribution?
Contribution contribution = contributionFactory.createContribution();
@ -455,46 +434,42 @@ public class EndpointIntrospector {
return contribution;
}
private List<Binding> loadBindings(Bundle bundle, String[] bindingDocuments) throws IOException,
ContributionReadException {
if (bindingDocuments == null || bindingDocuments.length == 0) {
private Collection<Binding> loadBindings(String[] qnames) throws IOException,
ContributionReadException, XMLStreamException {
if (qnames == null || qnames.length == 0) {
return Collections.emptyList();
}
List<Binding> bindings = new ArrayList<Binding>();
for (String doc : bindingDocuments) {
URL url = locate(bundle, doc);
if (url == null) {
throw new IOException("Entry " + doc + " cannot be found in bundle " + bundle);
}
bindings.addAll(loadBindings(url));
QName[] bindingNames = new QName[qnames.length];
int index = 0;
for (String name : qnames) {
bindingNames[index++] = getQName(name);
}
return bindings;
}
private List<Binding> loadBindings(URL url) throws ContributionReadException, IOException {
InputStream is = url.openStream();
try {
XMLStreamReader reader = xmlInputFactory.createXMLStreamReader(is);
reader.nextTag();
Object model = processor.read(reader, new ProcessorContext(registry));
if (model instanceof BindingDescriptions) {
return ((BindingDescriptions)model);
} else {
return Collections.emptyList();
}
} catch (XMLStreamException e) {
throw new ContributionReadException(e);
} finally {
is.close();
}
}
LocalDiscoveryService discoveryService = (LocalDiscoveryService)discoveryTracker.getService();
private URL locate(Bundle bundle, String location) throws MalformedURLException {
URI uri = URI.create(location);
if (uri.isAbsolute()) {
return uri.toURL();
Map<QName, Binding> bindingMap = new HashMap<QName, Binding>();
if (discoveryService != null) {
for (ExtenderConfiguration config : discoveryService.getConfigurations()) {
for (SCAConfig sc : config.getSCAConfigs()) {
for (QName bindingName : bindingNames) {
if (sc.getTargetNamespace().equals(bindingName.getNamespaceURI())) {
for (Binding binding : sc.getBindings()) {
if (bindingName.getLocalPart().equals(binding.getName())) {
bindingMap.put(bindingName, binding);
break;
}
}
}
}
}
}
}
return bundle.getEntry(location);
for (QName bindingName : bindingNames) {
if (!bindingMap.containsKey(bindingName)) {
throw new ServiceRuntimeException("Binding cannot be resolved: " + bindingName);
}
}
return bindingMap.values();
}
/**

View file

@ -19,9 +19,14 @@
package org.apache.tuscany.sca.osgi.remoteserviceadmin.impl;
import java.net.URL;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashSet;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
@ -83,4 +88,48 @@ public class OSGiHelper {
}
}
/**
* Get a collection of resources that are configured by the given header
* @param bundle The bundle
* @param header
* @param defaultValue
* @return
*/
public static Collection<URL> getConfiguration(Bundle bundle, String header, String defaultValue) {
String value = (String)bundle.getHeaders().get(header);
if (value == null) {
return Collections.emptyList();
}
String paths[] = value.trim().split("( |\t|\n|\r|\f|,)+");
if (paths.length == 0) {
if (defaultValue != null) {
paths = new String[] {defaultValue};
} else {
paths = new String[0];
}
}
Collection<URL> files = new HashSet<URL>();
for (String path : paths) {
if (path.endsWith("/")) {
path = path + "*.xml";
}
if (!path.startsWith("/")) {
path = "/" + path;
}
int lastIndex = path.lastIndexOf('/');
String root = path.substring(0, lastIndex);
if ("".equals(root)) {
root = "/";
}
String pattern = path.substring(lastIndex + 1);
Enumeration<URL> entries = bundle.findEntries(root, pattern, false);
if (entries != null) {
while (entries.hasMoreElements()) {
files.add(entries.nextElement());
}
}
}
return files;
}
}

View file

@ -38,6 +38,7 @@ import org.apache.tuscany.sca.node.impl.NodeFactoryImpl;
import org.apache.tuscany.sca.node.impl.NodeImpl;
import org.apache.tuscany.sca.osgi.remoteserviceadmin.EndpointDescription;
import org.apache.tuscany.sca.osgi.remoteserviceadmin.ExportRegistration;
import org.apache.tuscany.sca.osgi.service.discovery.impl.LocalDiscoveryService;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTracker;
@ -51,6 +52,7 @@ public class OSGiServiceExporter implements ServiceTrackerCustomizer, LifeCycleL
private BundleContext context;
private NodeFactoryImpl nodeFactory;
private EndpointIntrospector introspector;
private ServiceTracker discoveryTracker;
/**
* @param context
@ -65,7 +67,9 @@ public class OSGiServiceExporter implements ServiceTrackerCustomizer, LifeCycleL
if (nodeFactory == null) {
this.nodeFactory = (NodeFactoryImpl)NodeFactory.newInstance();
this.nodeFactory.init();
this.introspector = new EndpointIntrospector(context, getExtensionPointRegistry());
this.discoveryTracker = LocalDiscoveryService.getTracker(context);
discoveryTracker.open();
this.introspector = new EndpointIntrospector(context, getExtensionPointRegistry(), discoveryTracker);
}
}
@ -74,7 +78,12 @@ public class OSGiServiceExporter implements ServiceTrackerCustomizer, LifeCycleL
}
public void stop() {
this.introspector = null;
discoveryTracker.close();
discoveryTracker = null;
introspector = null;
nodeFactory = null;
registry = null;
context = null;
}
public Object addingService(ServiceReference reference) {

View file

@ -33,6 +33,7 @@ import org.apache.tuscany.sca.node.impl.NodeFactoryImpl;
import org.apache.tuscany.sca.node.impl.NodeImpl;
import org.apache.tuscany.sca.osgi.remoteserviceadmin.EndpointDescription;
import org.apache.tuscany.sca.osgi.remoteserviceadmin.ImportRegistration;
import org.apache.tuscany.sca.osgi.service.discovery.impl.LocalDiscoveryService;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
@ -46,6 +47,7 @@ public class OSGiServiceImporter implements LifeCycleListener {
private BundleContext context;
private NodeFactoryImpl nodeFactory;
private EndpointIntrospector introspector;
private ServiceTracker discoveryTracker;
/**
* @param context
@ -60,7 +62,9 @@ public class OSGiServiceImporter implements LifeCycleListener {
if (nodeFactory == null) {
this.nodeFactory = (NodeFactoryImpl)NodeFactory.newInstance();
this.nodeFactory.init();
this.introspector = new EndpointIntrospector(context, getExtensionPointRegistry());
this.discoveryTracker = LocalDiscoveryService.getTracker(context);
discoveryTracker.open();
this.introspector = new EndpointIntrospector(context, getExtensionPointRegistry(), discoveryTracker);
}
}
@ -68,6 +72,12 @@ public class OSGiServiceImporter implements LifeCycleListener {
}
public void stop() {
discoveryTracker.close();
discoveryTracker = null;
introspector = null;
nodeFactory = null;
registry = null;
context = null;
}
public ImportRegistration importService(Bundle bundle, EndpointDescription endpointDescription) {

View file

@ -118,7 +118,7 @@ public abstract class AbstractDiscoveryService implements Discovery, LifeCycleLi
props.put(PRODUCT_NAME, "Apache Tuscany SCA");
props.put(PRODUCT_VERSION, headers.get(Constants.BUNDLE_VERSION));
props.put(VENDOR_NAME, headers.get(Constants.BUNDLE_VENDOR));
props.put(SUPPORTED_PROTOCOLS, new String[] {"local", "org.osgi.sca"});
// props.put(SUPPORTED_PROTOCOLS, new String[] {"local", "org.osgi.sca"});
return props;
}

View file

@ -21,6 +21,8 @@ package org.apache.tuscany.sca.osgi.service.discovery.impl;
import static org.apache.tuscany.sca.osgi.remoteserviceadmin.impl.EndpointHelper.createEndpointDescription;
import java.util.Dictionary;
import org.apache.tuscany.sca.assembly.Endpoint;
import org.apache.tuscany.sca.assembly.Implementation;
import org.apache.tuscany.sca.core.UtilityExtensionPoint;
@ -105,5 +107,11 @@ public class DomainDiscoveryService extends AbstractDiscoveryService implements
domainRegistryFactory.removeListener(this);
super.stop();
}
@Override
protected Dictionary<String, Object> getProperties() {
Dictionary<String, Object> props = super.getProperties();
props.put(SUPPORTED_PROTOCOLS, new String[] {"org.osgi.sca"});
return props;
}
}

View file

@ -18,51 +18,42 @@
*/
package org.apache.tuscany.sca.osgi.service.discovery.impl;
import static org.osgi.framework.Bundle.ACTIVE;
import static org.osgi.framework.BundleEvent.STARTED;
import static org.osgi.framework.BundleEvent.STOPPING;
import static org.apache.tuscany.sca.osgi.remoteserviceadmin.impl.OSGiHelper.getConfiguration;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Collection;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.Map.Entry;
import java.util.logging.Level;
import javax.xml.stream.XMLStreamReader;
import org.apache.tuscany.sca.assembly.AssemblyFactory;
import org.apache.tuscany.sca.common.java.io.IOHelper;
import org.apache.tuscany.sca.common.xml.stax.StAXHelper;
import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor;
import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint;
import org.apache.tuscany.sca.core.FactoryExtensionPoint;
import org.apache.tuscany.sca.core.UtilityExtensionPoint;
import org.apache.tuscany.sca.deployment.Deployer;
import org.apache.tuscany.sca.implementation.osgi.SCAConfig;
import org.apache.tuscany.sca.implementation.osgi.ServiceDescription;
import org.apache.tuscany.sca.implementation.osgi.ServiceDescriptions;
import org.apache.tuscany.sca.monitor.Monitor;
import org.apache.tuscany.sca.monitor.MonitorFactory;
import org.apache.tuscany.sca.osgi.remoteserviceadmin.EndpointDescription;
import org.apache.tuscany.sca.osgi.remoteserviceadmin.RemoteConstants;
import org.apache.tuscany.sca.osgi.remoteserviceadmin.impl.EndpointHelper;
import org.oasisopen.sca.ServiceRuntimeException;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.util.tracker.BundleTracker;
import org.osgi.util.tracker.BundleTrackerCustomizer;
import org.osgi.util.tracker.ServiceTracker;
public class LocalDiscoveryService extends AbstractDiscoveryService implements BundleListener {
private StAXHelper staxHelper;
private AssemblyFactory assemblyFactory;
private StAXArtifactProcessor processor;
public class LocalDiscoveryService extends AbstractDiscoveryService implements BundleTrackerCustomizer {
private Deployer deployer;
private BundleTracker bundleTracker;
private Collection<ExtenderConfiguration> extenders = new ArrayList<ExtenderConfiguration>();
public LocalDiscoveryService(BundleContext context) {
super(context);
@ -70,87 +61,28 @@ public class LocalDiscoveryService extends AbstractDiscoveryService implements B
public void start() {
super.start();
context.addBundleListener(this);
getExtensionPointRegistry();
FactoryExtensionPoint factories = registry.getExtensionPoint(FactoryExtensionPoint.class);
this.assemblyFactory = factories.getFactory(AssemblyFactory.class);
this.staxHelper = StAXHelper.getInstance(registry);
StAXArtifactProcessorExtensionPoint processors =
registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
UtilityExtensionPoint utilities = this.registry.getExtensionPoint(UtilityExtensionPoint.class);
MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class);
Monitor monitor = null;
if (monitorFactory != null) {
monitor = monitorFactory.createMonitor();
}
processor =
new ExtensibleStAXArtifactProcessor(processors, staxHelper.getInputFactory(),
staxHelper.getOutputFactory());
processExistingBundles();
this.deployer = utilities.getUtility(Deployer.class);
bundleTracker = new BundleTracker(context, Bundle.ACTIVE | Bundle.STARTING, this);
bundleTracker.open();
}
public void bundleChanged(BundleEvent event) {
public static ServiceTracker getTracker(BundleContext context) {
Filter filter = null;
try {
switch (event.getType()) {
case STARTED:
discover(event.getBundle());
break;
case STOPPING:
removeServicesDeclaredInBundle(event.getBundle());
break;
}
} catch (Throwable e) {
logger.log(Level.SEVERE, e.getMessage(), e);
if (e instanceof Error) {
throw (Error)e;
} else if (e instanceof RuntimeException) {
throw (RuntimeException)e;
} else {
// Should not happen
throw new RuntimeException(e);
}
}
}
private void processExistingBundles() {
Bundle[] bundles = context.getBundles();
if (bundles == null) {
return;
}
for (Bundle b : bundles) {
if (b.getState() == ACTIVE) {
discover(b);
}
}
}
private void discover(Bundle b) {
List<URL> urls = findServiceDescriptionsDocuments(b);
if (urls == null || urls.isEmpty()) {
return;
}
List<ServiceDescription> serviceDescriptions = new ArrayList<ServiceDescription>();
for (URL url : urls) {
ServiceDescriptions descriptions = null;
try {
descriptions = loadServiceDescriptions(url);
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
}
if (descriptions != null) {
serviceDescriptions.addAll(descriptions);
}
}
for (ServiceDescription sd : serviceDescriptions) {
EndpointDescription sed = createEndpointDescription(sd);
servicesInfo.put(sed, b);
serviceDescriptionAdded(sed);
filter =
context.createFilter("(& (" + Discovery.SUPPORTED_PROTOCOLS
+ "=local) ("
+ Constants.OBJECTCLASS
+ "="
+ Discovery.class.getName()
+ "))");
} catch (InvalidSyntaxException e) {
throw new IllegalArgumentException(e);
}
return new ServiceTracker(context, filter, null);
}
private EndpointDescription createEndpointDescription(ServiceDescription sd) {
@ -170,46 +102,6 @@ public class LocalDiscoveryService extends AbstractDiscoveryService implements B
return sed;
}
private List<URL> findServiceDescriptionsDocuments(Bundle b) {
List<URL> urls = null;
String path = (String)b.getHeaders().get(ServiceDescriptions.REMOTE_SERVICE_HEADER);
if (path == null) {
Enumeration<URL> files = b.findEntries(ServiceDescriptions.REMOTE_SERVICE_FOLDER, "*.xml", false);
if (files == null || !files.hasMoreElements()) {
return Collections.emptyList();
} else {
urls = new ArrayList<URL>();
while (files.hasMoreElements()) {
urls.add(files.nextElement());
}
}
} else {
URL url = b.getEntry(path);
if (url != null) {
urls = Collections.singletonList(url);
} else {
urls = Collections.emptyList();
}
}
return urls;
}
private ServiceDescriptions loadServiceDescriptions(URL url) throws Exception {
InputStream is = IOHelper.openStream(url);
try {
XMLStreamReader reader = staxHelper.createXMLStreamReader(is);
reader.nextTag();
Object model = processor.read(reader, new ProcessorContext(registry));
if (model instanceof ServiceDescriptions) {
return (ServiceDescriptions)model;
} else {
return null;
}
} finally {
is.close();
}
}
private void removeServicesDeclaredInBundle(Bundle bundle) {
for (Iterator<Map.Entry<EndpointDescription, Bundle>> i = servicesInfo.entrySet().iterator(); i.hasNext();) {
Entry<EndpointDescription, Bundle> entry = i.next();
@ -229,8 +121,85 @@ public class LocalDiscoveryService extends AbstractDiscoveryService implements B
}
public void stop() {
context.removeBundleListener(this);
if (bundleTracker != null) {
bundleTracker.close();
}
super.stop();
}
public Object addingBundle(Bundle bundle, BundleEvent event) {
Collection<URL> scaConfigs = getConfiguration(bundle, "SCA-Configuration", "OSGI-INF/sca-config/*.xml");
Collection<URL> descriptions = getConfiguration(bundle, "Remote-Service", null);
if (scaConfigs.isEmpty() && descriptions.isEmpty()) {
return null;
}
ExtenderConfiguration extender = new ExtenderConfiguration();
for (URL url : scaConfigs) {
try {
SCAConfig scaConfig = deployer.loadXMLDocument(url, deployer.createMonitor());
extender.scaConfigs.add(scaConfig);
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
throw new ServiceRuntimeException(e);
}
}
for (URL url : descriptions) {
try {
ServiceDescriptions sds = deployer.loadXMLDocument(url, deployer.createMonitor());
extender.remoteServiceDescriptions.add(sds);
} catch (Exception e) {
logger.log(Level.SEVERE, e.getMessage(), e);
// throw new ServiceRuntimeException(e);
}
}
// Notify
for (ServiceDescriptions sds : extender.getRemoteServiceDescriptions()) {
for (ServiceDescription sd : sds) {
EndpointDescription sed = createEndpointDescription(sd);
servicesInfo.put(sed, bundle);
serviceDescriptionAdded(sed);
}
}
this.extenders.add(extender);
return extender;
}
public void modifiedBundle(Bundle bundle, BundleEvent event, Object object) {
// STARTING --> ACTIVE
}
public void removedBundle(Bundle bundle, BundleEvent event, Object object) {
if (object instanceof ExtenderConfiguration) {
extenders.remove((ExtenderConfiguration)object);
removeServicesDeclaredInBundle(bundle);
}
}
public Collection<ExtenderConfiguration> getConfigurations() {
return extenders;
}
public static class ExtenderConfiguration {
private Collection<SCAConfig> scaConfigs = new ArrayList<SCAConfig>();
private Collection<ServiceDescriptions> remoteServiceDescriptions = new ArrayList<ServiceDescriptions>();
public Collection<ServiceDescriptions> getRemoteServiceDescriptions() {
return remoteServiceDescriptions;
}
public Collection<SCAConfig> getSCAConfigs() {
return scaConfigs;
}
}
@Override
protected Dictionary<String, Object> getProperties() {
Dictionary<String, Object> props = super.getProperties();
props.put(SUPPORTED_PROTOCOLS, new String[] {"local"});
return props;
}
}

View file

@ -20,3 +20,4 @@ Service-Component-Disabled: OSGI-INF/add-component.xml,
OSGI-INF/multiply-component.xml,
OSGI-INF/divide-component.xml
Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6
SCA-Configuration: OSGI-INF/sca-config/*.xml

View file

@ -1,24 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
* 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.
-->
<!-- SCA bindings for calculator service -->
<bindings xmlns="http://www.osgi.org/xmlns/sd/v1.0.0"
xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200903">
<sca:binding.ws uri="http://localhost:8086/CalculatorService"/>
</bindings>
<?xml version="1.0" encoding="UTF-8"?>
<!--
* 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.
-->
<scact:sca-config targetNamespace="http://sample"
xmlns:scact="http://www.osgi.org/xmlns/scact/v1.0.0"
xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200903"
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1">
<tuscany:binding.rmi name="Add" uri="rmi://localhost:8085/AddService"/>
<tuscany:binding.rmi name="Divide" uri="rmi://localhost:8085/DivideService"/>
<tuscany:binding.rmi name="Subtract" uri="rmi://localhost:8085/SubtractService"/>
<tuscany:binding.rmi name="Multiply" uri="rmi://localhost:8085/MultiplyService"/>
</scact:sca-config>

View file

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
* 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.
-->
<bindings xmlns="http://www.osgi.org/xmlns/sd/v1.0.0"
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1">
<tuscany:binding.rmi uri="rmi://localhost:8085/DivideService"/>
</bindings>

View file

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
* 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.
-->
<bindings xmlns="http://www.osgi.org/xmlns/sd/v1.0.0"
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1">
<tuscany:binding.rmi uri="rmi://localhost:8085/MultiplyService"/>
</bindings>

View file

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
* 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.
-->
<bindings xmlns="http://www.osgi.org/xmlns/sd/v1.0.0"
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1">
<tuscany:binding.rmi uri="rmi://localhost:8085/SubtractService"/>
</bindings>

View file

@ -49,22 +49,22 @@ public class OperationsActivator implements BundleActivator {
logger.info("Registering " + AddService.class.getName());
props.put("sca.service", "AddComponent#service-name(Add)");
props.put("sca.bindings", new String[] {"OSGI-INF/sca/add-service.bindings"});
props.put("org.osgi.sca.bindings", new String[] {"{http://sample}Add"});
context.registerService(AddService.class.getName(), new AddServiceImpl(), props);
logger.info("Registering " + SubtractService.class.getName());
props.put("sca.service", "SubtractComponent#service-name(Subtract)");
props.put("sca.bindings", new String[] {"OSGI-INF/sca/subtract-service.bindings"});
props.put("org.osgi.sca.bindings", new String[] {"{http://sample}Subtract"});
context.registerService(SubtractService.class.getName(), new SubtractServiceImpl(), props);
logger.info("Registering " + MultiplyService.class.getName());
props.put("sca.service", "MultiplyComponent#service-name(Multiply)");
props.put("sca.bindings", new String[] {"OSGI-INF/sca/multiply-service.bindings"});
props.put("org.osgi.sca.bindings", new String[] {"{http://sample}Multiply"});
context.registerService(MultiplyService.class.getName(), new MultiplyServiceImpl(), props);
logger.info("Registering " + DivideService.class.getName());
props.put("sca.service", "DivideComponent#service-name(Divide)");
props.put("sca.bindings", new String[] {"OSGI-INF/sca/divide-service.bindings"});
props.put("org.osgi.sca.bindings", new String[] {"{http://sample}Divide"});
context.registerService(DivideService.class.getName(), new DivideServiceImpl(), props);
getBundle(context, AddService.class);

View file

@ -17,4 +17,7 @@ Eclipse-LazyStart: true
Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
Bundle-DocURL: http://www.apache.org/
Service-Component-Disabled: OSGI-INF/calculator-component.xml
Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6
Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6
SCA-Configuration: OSGI-INF/sca-config/calculator-config.xml
Remote-Service: OSGI-INF/remote-service/*.xml

View file

@ -24,58 +24,38 @@
<!-- Describe a remote OSGi service -->
<service-description>
<provide interface="calculator.dosgi.operations.AddService" />
<property name="service.exported.intents">sca:SOAP sca:HTTP</property>
<property name="service.exported.configs">sca</property>
<property name="sca.componentType">
OSGI-INF/sca/bundle.componentType
</property>
<property name="remote.exported.intents"></property>
<property name="remote.configs.supported">org.osgi.sca</property>
<property name="sca.reference">
addService
</property>
<bindings>
<tuscany:binding.rmi uri="rmi://localhost:8085/AddService" />
</bindings>
<property name="org.osgi.sca.bindings">{http://sample}Add</property>
</service-description>
<service-description>
<provide interface="calculator.dosgi.operations.SubtractService" />
<property name="service.exported.intents">sca:SOAP sca:HTTP</property>
<property name="service.exported.configs">sca</property>
<property name="sca.componentType">
OSGI-INF/sca/bundle.componentType
</property>
<property name="remote.exported.intents"></property>
<property name="remote.configs.supported">org.osgi.sca</property>
<property name="sca.reference">
subtractService
</property>
<bindings>
<tuscany:binding.rmi uri="rmi://localhost:8085/SubtractService" />
</bindings>
<property name="org.osgi.sca.bindings">{http://sample}Subtract</property>
</service-description>
<service-description>
<provide interface="calculator.dosgi.operations.MultiplyService" />
<property name="service.exported.intents">sca:SOAP sca:HTTP</property>
<property name="service.exported.configs">sca</property>
<property name="sca.componentType">
OSGI-INF/sca/bundle.componentType
</property>
<property name="remote.exported.intents"></property>
<property name="remote.configs.supported">org.osgi.sca</property>
<property name="sca.reference">
multiplyService
</property>
<bindings>
<tuscany:binding.rmi uri="rmi://localhost:8085/MultiplyService" />
</bindings>
<property name="org.osgi.sca.bindings">{http://sample}Multiply</property>
</service-description>
<service-description>
<provide interface="calculator.dosgi.operations.DivideService" />
<property name="service.exported.intents">sca:SOAP sca:HTTP</property>
<property name="service.exported.configs">sca</property>
<property name="sca.componentType">
OSGI-INF/sca/bundle.componentType
</property>
<property name="remote.exported.intents"></property>
<property name="remote.configs.supported">org.osgi.sca</property>
<property name="sca.reference">
divideService
</property>
<bindings>
<tuscany:binding.rmi uri="rmi://localhost:8085/DivideService" />
</bindings>
<property name="org.osgi.sca.bindings">{http://sample}Divide</property>
</service-description>
</service-descriptions>

View file

@ -1,23 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
* 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.
-->
<bindings xmlns="http://www.osgi.org/xmlns/sd/v1.0.0"
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1">
<tuscany:binding.rmi uri="rmi://localhost:8085/AddService"/>
</bindings>
<?xml version="1.0" encoding="UTF-8"?>
<!--
* 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.
-->
<scact:sca-config targetNamespace="http://sample"
xmlns:scact="http://www.osgi.org/xmlns/scact/v1.0.0"
xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200903"
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1">
<sca:binding.ws name="Calculator" uri="http://localhost:8086/CalculatorService"/>
<!-- bindings for the remote services -->
<tuscany:binding.rmi name="Add" uri="rmi://localhost:8085/AddService"/>
<tuscany:binding.rmi name="Divide" uri="rmi://localhost:8085/DivideService"/>
<tuscany:binding.rmi name="Subtract" uri="rmi://localhost:8085/SubtractService"/>
<tuscany:binding.rmi name="Multiply" uri="rmi://localhost:8085/MultiplyService"/>
</scact:sca-config>

View file

@ -60,7 +60,7 @@ public class CalculatorActivator implements BundleActivator {
props.put("sca.service", "CalculatorComponent#service-name(Calculator)");
props.put("calculator", "Calculator");
props.put("service.exported.configs", new String[] {"org.osgi.sca"});
props.put("sca.bindings", new String[] {"OSGI-INF/sca/calculator-service.bindings"});
props.put("org.osgi.sca.bindings", new String[] {"{http://sample}Calculator"});
props.put("service.exported.interfaces", new String[] {"*"});
logger.info("Registering " + CalculatorService.class.getName());
CalculatorService calculator = new CalculatorServiceImpl(context);