summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/META-INF/MANIFEST.MF44
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/pom.xml74
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/EndpointStash.java54
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastBinding.java33
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastBindingProviderFactory.java54
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastReferenceBindingProvider.java58
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastServiceBindingProvider.java52
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/ReferenceInvoker.java127
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/ServiceInvoker.java98
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/HazelcastDomainRegistry.java666
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/HazelcastDomainRegistryFactory.java49
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/RegistryConfig.java177
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/client/HazelcastClientDomainRegistryFactory.java49
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/client/HazelcastClientEndpointRegistry.java132
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor21
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.BindingProviderFactory19
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/resources/META-INF/services/org.apache.tuscany.sca.runtime.DomainRegistryFactory18
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/BadStringException.java29
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/ComplexType.java33
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastBindingTestCase.java116
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/TestService.java30
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/TestServiceClient.java45
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/TestServiceImpl.java43
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/registry/hazelcast/MultiRegTestCase.java218
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/registry/hazelcast/RegistryTestCase.java142
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/resources/client.composite29
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/resources/client2.composite29
-rw-r--r--sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/resources/service.composite28
28 files changed, 2467 insertions, 0 deletions
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/META-INF/MANIFEST.MF b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..a2e407b300
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/META-INF/MANIFEST.MF
@@ -0,0 +1,44 @@
+Manifest-Version: 1.0
+SCA-Version: 1.1
+Bundle-Name: Apache Tuscany SCA Hazelcast Based Domain
+Bundle-Vendor: The Apache Software Foundation
+Bundle-Version: 2.0.0
+Bundle-ManifestVersion: 2
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-Description: Apache Tuscany Domain Hazelcast
+Bundle-SymbolicName: org.apache.tuscany.sca.domain.hazelcast
+Bundle-DocURL: http://www.apache.org/
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Import-Package: javax.wsdl,
+ javax.wsdl.extensions,
+ javax.wsdl.extensions.schema,
+ javax.wsdl.factory,
+ javax.wsdl.xml,
+ javax.xml.stream,
+ com.hazelcast.client,
+ com.hazelcast.config,
+ com.hazelcast.core,
+ com.hazelcast.nio,
+ org.apache.tuscany.sca.assembly;version="2.0.0",
+ org.apache.tuscany.sca.assembly.impl;version="2.0.0",
+ org.apache.tuscany.sca.assembly.xml;version="2.0.0",
+ org.apache.tuscany.sca.binding.ws;version="2.0.0",
+ org.apache.tuscany.sca.binding.ws.wsdlgen;version="2.0.0",
+ org.apache.tuscany.sca.common.xml;version="2.0.0",
+ org.apache.tuscany.sca.common.xml.dom;version="2.0.0",
+ org.apache.tuscany.sca.common.xml.stax;version="2.0.0",
+ org.apache.tuscany.sca.context;version="2.0.0",
+ org.apache.tuscany.sca.core;version="2.0.0",
+ org.apache.tuscany.sca.databinding.xml;version="2.0.0",
+ org.apache.tuscany.sca.interfacedef;version="2.0.0",
+ org.apache.tuscany.sca.interfacedef.util;version="2.0.0",
+ org.apache.tuscany.sca.invocation;version="2.0.0",
+ org.apache.tuscany.sca.provider;version="2.0.0",
+ org.apache.tuscany.sca.runtime;version="2.0.0",
+ org.oasisopen.sca,
+ org.oasisopen.sca.annotation,
+ org.w3c.dom,
+ org.xml.sax
+Export-Package: org.apache.tuscany.sca.registry.hazelcast;version="2.0.0";
+ uses:="org.apache.tuscany.sca.runtime,org.apache.tuscany.sca.assembly,org.apache.tuscany.sca.core"
+
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/pom.xml b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/pom.xml
new file mode 100644
index 0000000000..88290651ee
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/pom.xml
@@ -0,0 +1,74 @@
+<?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.
+-->
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-modules</artifactId>
+ <version>2.0-Beta3-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>tuscany-domain-hazelcast</artifactId>
+ <name>Apache Tuscany SCA EndPoint Registry using Hazelcast</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.hazelcast</groupId>
+ <artifactId>hazelcast</artifactId>
+ <version>1.9.2.2</version>
+ </dependency>
+ <dependency>
+ <groupId>com.hazelcast</groupId>
+ <artifactId>hazelcast-client</artifactId>
+ <version>1.9.2.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-core</artifactId>
+ <version>2.0-Beta3-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-assembly-xml</artifactId>
+ <version>2.0-Beta3-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-binding-ws-wsdlgen</artifactId>
+ <version>2.0-Beta3-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-node-impl</artifactId>
+ <version>2.0-Beta3-SNAPSHOT</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-implementation-java-runtime</artifactId>
+ <version>2.0-Beta3-SNAPSHOT</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/EndpointStash.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/EndpointStash.java
new file mode 100644
index 0000000000..42f6193940
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/EndpointStash.java
@@ -0,0 +1,54 @@
+/*
+ * 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.binding.hazelcast;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
+
+
+public class EndpointStash {
+
+ // TODO a better way of sharing these endpoints than a static
+ // the issue is that the ServiceInvoker needs to get hold of the Endpoint
+ // for a URI. The ServiceInvoker runs in the context of a Hazelcast spawned
+ // thread so can only get to Tuscany via a static. The Hazelcast endpoint
+ // registry does actually have these endpoints so perhaps an alternative could be
+ // to use NodeFactory.getNodeFactories to get at the Hazelcast endpoint registry.
+ private static Map<String, RuntimeEndpoint> endpoints = new ConcurrentHashMap<String, RuntimeEndpoint>();
+
+ public static void addEndpoint(RuntimeEndpoint endpoint) {
+ endpoints.put(endpoint.getURI(), endpoint);
+ }
+
+ public static RuntimeEndpoint getEndpoint(String uri) {
+ for (RuntimeEndpoint ep : endpoints.values()) {
+ if (ep.matches(uri)) {
+ return ep;
+ }
+ }
+ return null;
+ }
+
+ public static void removeEndpoint(String uri) {
+ endpoints.remove(uri);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastBinding.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastBinding.java
new file mode 100644
index 0000000000..1636ed16ca
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastBinding.java
@@ -0,0 +1,33 @@
+/*
+ * 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.binding.hazelcast;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.impl.BindingImpl;
+
+public class HazelcastBinding extends BindingImpl {
+
+ public static final QName TYPE = new QName(SCA11_TUSCANY_NS, "binding.hazelcast");
+
+ public HazelcastBinding() {
+ super(TYPE);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastBindingProviderFactory.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastBindingProviderFactory.java
new file mode 100644
index 0000000000..3a1b89e83e
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastBindingProviderFactory.java
@@ -0,0 +1,54 @@
+/*
+ * 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.binding.hazelcast;
+
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.databinding.xml.DOMDataBinding;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.provider.BindingProviderFactory;
+import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
+import org.apache.tuscany.sca.provider.ServiceBindingProvider;
+import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
+import org.apache.tuscany.sca.runtime.RuntimeEndpointReference;
+
+public class HazelcastBindingProviderFactory implements BindingProviderFactory<HazelcastBinding> {
+
+ private ExtensionPointRegistry extensionsRegistry;
+
+ public HazelcastBindingProviderFactory(ExtensionPointRegistry extensionsRegistry) {
+ this.extensionsRegistry = extensionsRegistry;
+ }
+
+ public ReferenceBindingProvider createReferenceBindingProvider(RuntimeEndpointReference endpointReference) {
+ InterfaceContract interfaceContract = endpointReference.getGeneratedWSDLContract(endpointReference.getComponentReferenceInterfaceContract());
+ interfaceContract.getInterface().resetDataBinding(DOMDataBinding.NAME);
+ return new HazelcastReferenceBindingProvider(extensionsRegistry, endpointReference.getBinding().getURI(), interfaceContract);
+ }
+
+ public ServiceBindingProvider createServiceBindingProvider(RuntimeEndpoint endpoint) {
+ InterfaceContract interfaceContract = endpoint.getGeneratedWSDLContract(endpoint.getComponentServiceInterfaceContract());
+ interfaceContract.getInterface().resetDataBinding(DOMDataBinding.NAME);
+ return new HazelcastServiceBindingProvider(endpoint, interfaceContract);
+ }
+
+ public Class<HazelcastBinding> getModelType() {
+ return HazelcastBinding.class;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastReferenceBindingProvider.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastReferenceBindingProvider.java
new file mode 100644
index 0000000000..29546f405e
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastReferenceBindingProvider.java
@@ -0,0 +1,58 @@
+/*
+ * 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.binding.hazelcast;
+
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.provider.ReferenceBindingProvider;
+
+public class HazelcastReferenceBindingProvider implements ReferenceBindingProvider {
+
+ private ExtensionPointRegistry extensionsRegistry;
+ private String serviceURI;
+ private InterfaceContract interfaceContract;
+
+ public HazelcastReferenceBindingProvider(ExtensionPointRegistry extensionsRegistry, String serviceURI, InterfaceContract interfaceContract) {
+ this.extensionsRegistry = extensionsRegistry;
+ this.serviceURI = serviceURI;
+ this.interfaceContract = interfaceContract;
+ }
+
+ public Invoker createInvoker(Operation operation) {
+ return new ReferenceInvoker(extensionsRegistry, serviceURI, operation);
+ }
+
+ public InterfaceContract getBindingInterfaceContract() {
+ return interfaceContract;
+ }
+
+ public boolean supportsOneWayInvocation() {
+ return false;
+ }
+
+ public void start() {
+ }
+
+ public void stop() {
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastServiceBindingProvider.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastServiceBindingProvider.java
new file mode 100644
index 0000000000..6ac3542a8e
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastServiceBindingProvider.java
@@ -0,0 +1,52 @@
+/*
+ * 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.binding.hazelcast;
+
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.provider.ServiceBindingProvider;
+import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
+
+public class HazelcastServiceBindingProvider implements ServiceBindingProvider {
+
+ private RuntimeEndpoint endpoint;
+ private InterfaceContract interfaceContract;
+
+
+ public HazelcastServiceBindingProvider(RuntimeEndpoint endpoint, InterfaceContract interfaceContract) {
+ this.endpoint = endpoint;
+ this.interfaceContract = interfaceContract;
+ }
+
+ public void start() {
+ EndpointStash.addEndpoint(endpoint);
+ }
+
+ public void stop() {
+ EndpointStash.removeEndpoint(endpoint.getURI());
+ }
+
+ public InterfaceContract getBindingInterfaceContract() {
+ return interfaceContract;
+ }
+
+ public boolean supportsOneWayInvocation() {
+ return false;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/ReferenceInvoker.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/ReferenceInvoker.java
new file mode 100644
index 0000000000..1585684691
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/ReferenceInvoker.java
@@ -0,0 +1,127 @@
+/*
+ * 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.binding.hazelcast;
+
+import java.io.IOException;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.FutureTask;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.common.xml.dom.DOMHelper;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.util.FaultException;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.apache.tuscany.sca.invocation.MessageFactory;
+import org.apache.tuscany.sca.registry.hazelcast.HazelcastDomainRegistry;
+import org.apache.tuscany.sca.runtime.DomainRegistryFactory;
+import org.apache.tuscany.sca.runtime.DomainRegistry;
+import org.apache.tuscany.sca.runtime.ExtensibleDomainRegistryFactory;
+import org.oasisopen.sca.ServiceRuntimeException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+import com.hazelcast.core.DistributedTask;
+import com.hazelcast.core.Member;
+
+public class ReferenceInvoker implements Invoker {
+
+ HazelcastDomainRegistry hzRegistry;
+ DOMHelper domHelper;
+ String serviceURI;
+ private Operation operation;
+ MessageFactory messageFactory;
+
+ public ReferenceInvoker(ExtensionPointRegistry extensionsRegistry, String serviceURI, Operation operation) {
+ this.serviceURI = serviceURI;
+ this.operation = operation;
+ DomainRegistryFactory domainRegistryFactory = ExtensibleDomainRegistryFactory.getInstance(extensionsRegistry);
+ for (DomainRegistry r : domainRegistryFactory.getEndpointRegistries()) {
+ if (r instanceof HazelcastDomainRegistry) {
+ hzRegistry = (HazelcastDomainRegistry)r;
+ break;
+ }
+ }
+ this.domHelper = DOMHelper.getInstance(extensionsRegistry);
+ FactoryExtensionPoint modelFactories = extensionsRegistry.getExtensionPoint(FactoryExtensionPoint.class);
+ this.messageFactory = modelFactories.getFactory(MessageFactory.class);
+ }
+
+ public Message invoke(Message msg) {
+ Member owningMember = hzRegistry.getOwningMember(serviceURI);
+ if (owningMember == null) {
+ throw new ServiceRuntimeException("service not found: " + serviceURI);
+ }
+ String requestXML = getRequestXML(msg);
+ Callable<String> callable = new ServiceInvoker(serviceURI, operation.getName(), requestXML);
+ FutureTask<String> task = new DistributedTask<String>(callable, owningMember);
+ ExecutorService executorService = getExecutorService();
+ executorService.execute(task);
+ try {
+ return getResponseNode(task.get());
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ /**
+ * Hazelcast ExecutorService can't nest invocations so use a separate ExecutorService
+ * for nested calls. See http://groups.google.com/group/hazelcast/browse_thread/thread/1cc0b943716476e9
+ */
+ private ExecutorService getExecutorService() {
+ String threadName = Thread.currentThread().getName();
+ if (!threadName.startsWith("hz.executor.") || threadName.indexOf("binding.sca.") == -1) {
+ return hzRegistry.getHazelcastInstance().getExecutorService("binding.sca.1");
+ } else {
+ String oldName = threadName.substring(threadName.lastIndexOf("binding.sca."), threadName.lastIndexOf(".thread-"));
+ int x = Integer.parseInt(oldName.substring(oldName.lastIndexOf('.') + 1));
+ return hzRegistry.getHazelcastInstance().getExecutorService(oldName.substring(0, 12) + (x + 1));
+ }
+ }
+
+ private String getRequestXML(Message msg) {
+ Object[] args = msg.getBody();
+ String msgXML = domHelper.saveAsString((Node)args[0]);
+ return msgXML;
+ }
+
+ private Message getResponseNode(String responseXML) throws IOException, SAXException {
+ Message msg = messageFactory.createMessage();
+ if (responseXML.startsWith("DECLAREDEXCEPTION:")) {
+ Document responseDOM = domHelper.load(responseXML.substring(18));
+ FaultException e = new FaultException("remote exception", responseDOM);
+ Node node = ((Node)responseDOM).getFirstChild();
+ e.setFaultName(new QName(node.getNamespaceURI(), node.getLocalName()));
+ msg.setFaultBody(e);
+ } else if (responseXML.startsWith("EXCEPTION:")) {
+ throw new ServiceRuntimeException("Remote exception:" + responseXML.substring(10));
+ } else {
+ Document responseDOM = domHelper.load(responseXML);
+ msg.setBody(responseDOM);
+ }
+ return msg;
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/ServiceInvoker.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/ServiceInvoker.java
new file mode 100644
index 0000000000..42cac191aa
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/binding/hazelcast/ServiceInvoker.java
@@ -0,0 +1,98 @@
+/*
+ * 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.binding.hazelcast;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.util.concurrent.Callable;
+
+import org.apache.tuscany.sca.common.xml.dom.DOMHelper;
+import org.apache.tuscany.sca.interfacedef.Interface;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.util.FaultException;
+import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
+import org.oasisopen.sca.NoSuchServiceException;
+import org.oasisopen.sca.ServiceRuntimeException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+public class ServiceInvoker implements Callable<String>, Serializable {
+ private static final long serialVersionUID = 1L;
+
+ // all fields MUST be Serializable
+ private String serviceURI;
+ private String operationName;
+ private String requestXML;
+
+ public ServiceInvoker(String serviceURI, String operationName, String msgXML) {
+ this.serviceURI = serviceURI;
+ this.operationName = operationName;
+ this.requestXML = msgXML;
+ }
+
+ public String call() throws Exception {
+ RuntimeEndpoint endpoint = EndpointStash.getEndpoint(serviceURI);
+ if (endpoint == null) {
+ throw new NoSuchServiceException(serviceURI);
+ }
+ Operation operation = getRequestOperation(endpoint);
+ DOMHelper domHelper = DOMHelper.getInstance(endpoint.getCompositeContext().getExtensionPointRegistry());
+ Object[] args = getRequestArgs(domHelper);
+ String responseXML;
+ try {
+ Object response = endpoint.invoke(operation, args);
+ responseXML = getResponseXML(domHelper, response);
+ } catch (Exception e) {
+ if (e instanceof InvocationTargetException && ((InvocationTargetException)e).getTargetException() instanceof FaultException) {
+ responseXML = "DECLAREDEXCEPTION:" + getResponseXML(domHelper, ((FaultException)((InvocationTargetException)e).getTargetException()).getFaultInfo());
+ } else {
+ responseXML = "EXCEPTION: " + e.getClass() + ":" + e.getMessage();
+ }
+ }
+ return responseXML;
+ }
+
+ private Operation getRequestOperation(RuntimeEndpoint endpoint) {
+ InterfaceContract ic = endpoint.getBindingInterfaceContract();
+ Interface iface = ic.getInterface();
+ for (Operation op : iface.getOperations()) {
+ if (op.getName().equals(operationName)) {
+ return op;
+ }
+
+ }
+ // TODO: return err msg
+ throw new ServiceRuntimeException("operation not found " + operationName);
+ }
+
+ private Object[] getRequestArgs(DOMHelper domHelper) throws IOException, SAXException {
+ Document requestDOM = domHelper.load(requestXML);
+ return new Object[] {requestDOM};
+ }
+
+ private String getResponseXML(DOMHelper domHelper, Object response) {
+ String responseXML = domHelper.saveAsString((Node)response);
+ return responseXML;
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/HazelcastDomainRegistry.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/HazelcastDomainRegistry.java
new file mode 100644
index 0000000000..d7a31a38ef
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/HazelcastDomainRegistry.java
@@ -0,0 +1,666 @@
+/*
+ * 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.registry.hazelcast;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.FutureTask;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.assembly.Endpoint;
+import org.apache.tuscany.sca.common.xml.stax.StAXHelper;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.processor.ContributionWriteException;
+import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.core.LifeCycleListener;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.runtime.BaseDomainRegistry;
+import org.apache.tuscany.sca.runtime.ContributionDescription;
+import org.apache.tuscany.sca.runtime.ContributionListener;
+import org.apache.tuscany.sca.runtime.DomainRegistry;
+import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
+import org.apache.tuscany.sca.runtime.RuntimeProperties;
+import org.oasisopen.sca.ServiceRuntimeException;
+
+import com.hazelcast.config.Config;
+import com.hazelcast.config.NearCacheConfig;
+import com.hazelcast.config.TcpIpConfig;
+import com.hazelcast.config.XmlConfigBuilder;
+import com.hazelcast.core.DistributedTask;
+import com.hazelcast.core.EntryEvent;
+import com.hazelcast.core.EntryListener;
+import com.hazelcast.core.Hazelcast;
+import com.hazelcast.core.HazelcastInstance;
+import com.hazelcast.core.ILock;
+import com.hazelcast.core.IMap;
+import com.hazelcast.core.Member;
+import com.hazelcast.core.MembershipEvent;
+import com.hazelcast.core.MembershipListener;
+import com.hazelcast.core.MultiMap;
+import com.hazelcast.core.Transaction;
+import com.hazelcast.nio.Address;
+
+/**
+ * An DomainRegistry using a Hazelcast
+ */
+public class HazelcastDomainRegistry extends BaseDomainRegistry implements DomainRegistry, LifeCycleListener, EntryListener<String, Endpoint>, MembershipListener {
+ private final static Logger logger = Logger.getLogger(HazelcastDomainRegistry.class.getName());
+
+ private HazelcastInstance hazelcastInstance;
+
+ protected Map<Object, Object> endpointMap;
+ protected MultiMap<String, String> endpointOwners;
+
+ // key contributionURI, value map key compositeURI value compositeXML
+ protected Map<String, Map<String, String>> runningComposites;
+ // key member, value map key contributionURI value list of compositeURI
+ protected Map<String, Map<String, List<String>>> runningCompositeOwners;
+ // key componentName, value contributionURI
+ protected Map<String, String> runningComponentContributions;
+
+ protected Map<String, Endpoint> localEndpoints = new ConcurrentHashMap<String, Endpoint>();
+
+ protected Map<String, ContributionDescription> contributionDescriptions;
+
+ protected AssemblyFactory assemblyFactory;
+ protected Object shutdownMutex = new Object();
+ protected Properties properties;
+
+ public HazelcastDomainRegistry(ExtensionPointRegistry registry, Properties properties, String domainURI, String domainName) {
+ super(registry, null, domainURI, domainName);
+ this.assemblyFactory = registry.getExtensionPoint(FactoryExtensionPoint.class).getFactory(AssemblyFactory.class);
+ this.properties = properties;
+ }
+
+ public HazelcastDomainRegistry(ExtensionPointRegistry registry,
+ Map<String, String> attributes,
+ String domainURI,
+ String domainName) {
+ super(registry, attributes, domainURI, domainName);
+ this.assemblyFactory = registry.getExtensionPoint(FactoryExtensionPoint.class).getFactory(AssemblyFactory.class);
+ this.properties = registry.getExtensionPoint(UtilityExtensionPoint.class).getUtility(RuntimeProperties.class).getProperties();
+ }
+
+ public HazelcastInstance getHazelcastInstance() {
+ return hazelcastInstance;
+ }
+
+ public void start() {
+ if (endpointMap != null) {
+ throw new IllegalStateException("The registry has already been started");
+ }
+// if (configURI.toString().startsWith("tuscany:vm:")) {
+// endpointMap = new HashMap<Object, Object>();
+// } else {
+ initHazelcastInstance();
+ IMap imap = hazelcastInstance.getMap(domainURI + "/Endpoints");
+ imap.addEntryListener(this, true);
+ endpointMap = imap;
+
+ endpointOwners = hazelcastInstance.getMultiMap(domainURI + "/EndpointOwners");
+
+ runningComposites = hazelcastInstance.getMap(domainURI + "/RunningComposites");
+ runningCompositeOwners = hazelcastInstance.getMap(domainURI + "/RunningCompositeOwners");
+ runningComponentContributions = hazelcastInstance.getMap(domainURI + "/RunningComponentContributions");
+
+ contributionDescriptions = hazelcastInstance.getMap(domainURI + "/ContributionDescriptions");
+ ((IMap<String, ContributionDescription>)contributionDescriptions).addEntryListener(new EntryListener<String, ContributionDescription>() {
+ public void entryAdded(EntryEvent<String, ContributionDescription> event) {
+ }
+ public void entryRemoved(EntryEvent<String, ContributionDescription> event) {
+ for (ContributionListener listener : contributionlisteners) {
+ listener.contributionRemoved(event.getKey());
+ }
+ }
+ public void entryUpdated(EntryEvent<String, ContributionDescription> event) {
+ for (ContributionListener listener : contributionlisteners) {
+ listener.contributionUpdated(event.getKey());
+ }
+ }
+ public void entryEvicted(EntryEvent<String, ContributionDescription> event) {
+ }
+ }, false);
+
+ hazelcastInstance.getCluster().addMembershipListener(this);
+// }
+ }
+
+ public void stop() {
+ if (hazelcastInstance != null) {
+ synchronized (shutdownMutex) {
+ hazelcastInstance.shutdown();
+ hazelcastInstance = null;
+ endpointMap = null;
+ endpointOwners = null;
+ runningComposites = null;
+ runningCompositeOwners = null;
+ }
+ }
+ }
+
+ private void initHazelcastInstance() {
+
+ // Hazelcast is outputs a lot on info level log messages which are unnecessary for us,
+ // so disable info logging for hazelcast client classes unless fine logging is on for tuscany.
+ if (!logger.isLoggable(Level.CONFIG)) {
+ Logger hzl = Logger.getLogger("com.hazelcast");
+ if (!hzl.isLoggable(Level.FINE)) {
+ hzl.setLevel(Level.WARNING);
+ // we want the ClusterManager info messages so we can see nodes come and go
+ Logger.getLogger("com.hazelcast.cluster.ClusterManager").setLevel(Level.INFO);
+ // we don't want any of the XmlConfigBuilder warnings as set the config programatically
+ Logger.getLogger("com.hazelcast.config.XmlConfigBuilder").setLevel(Level.SEVERE);
+ }
+ }
+
+ Config config = getHazelcastConfig();
+
+ // do this when theres a way to have adders be the key owners
+ // config.getMapConfig(configURI.getDomainName() + "/Endpoints").setBackupCount(0);
+
+ // this caches reads locally
+ config.getMapConfig("default").setNearCacheConfig(new NearCacheConfig(0, 0, "NONE", 0, true));
+
+ // Disable the Hazelcast shutdown hook as Tuscany has its own and with both there are race conditions
+ config.setProperty("hazelcast.shutdownhook.enabled",
+ // GroupProperties.PROP_SHUTDOWNHOOK_ENABLED,
+ "false");
+
+ // By default this is 5 seconds, not sure what the implications are but dropping it down to 1 makes
+ // things like the samples look much faster
+ config.setProperty("hazelcast.wait.seconds.before.join",
+ // GroupProperties.PROP_WAIT_SECONDS_BEFORE_JOIN,
+ "1");
+
+ this.hazelcastInstance = Hazelcast.newHazelcastInstance(config);
+ if (logger.isLoggable(Level.INFO)) {
+ logger.info("started node in domain '" + domainURI + "' + at: " + hazelcastInstance.getCluster().getLocalMember().getInetSocketAddress());
+ }
+ }
+
+ protected Config getHazelcastConfig() {
+ Config config;
+ this.properties = registry.getExtensionPoint(UtilityExtensionPoint.class).getUtility(RuntimeProperties.class).getProperties();
+ String configFile = properties.getProperty("hazelcastConfig");
+ if (configFile != null) {
+ try {
+ config = new XmlConfigBuilder(configFile).build();
+ } catch (FileNotFoundException e) {
+ throw new IllegalArgumentException(configFile, e);
+ }
+ } else {
+ // TUSCANY-3675 - domainRegistryURI properties don't seem to be copied into the
+ // properties collection anywhere
+ config = new XmlConfigBuilder().build();
+ RegistryConfig rc = RegistryConfig.parseConfigURI(domainRegistryURI);
+ config.setPort(rc.getBindPort());
+ //config.setPortAutoIncrement(false);
+
+ if (!rc.getBindAddress().equals("*")) {
+ config.getNetworkConfig().getInterfaces().setEnabled(true);
+ config.getNetworkConfig().getInterfaces().clear();
+ config.getNetworkConfig().getInterfaces().addInterface(rc.getBindAddress());
+ }
+
+ config.getGroupConfig().setName(rc.getUserid());
+ config.getGroupConfig().setPassword(rc.getPassword());
+
+ if (rc.isMulticastDisabled()) {
+ config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
+ } else {
+ config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(true);
+ config.getNetworkConfig().getJoin().getMulticastConfig().setMulticastPort(rc.getMulticastPort());
+ config.getNetworkConfig().getJoin().getMulticastConfig().setMulticastGroup(rc.getMulticastAddress());
+ }
+
+ if (rc.getWKAs().size() > 0) {
+ TcpIpConfig tcpconfig = config.getNetworkConfig().getJoin().getTcpIpConfig();
+ tcpconfig.setEnabled(true);
+ List<Address> lsMembers = tcpconfig.getAddresses();
+ lsMembers.clear();
+ for (String addr : rc.getWKAs()) {
+ String[] ipNPort = addr.split(":");
+ try {
+ lsMembers.add(new Address(ipNPort[0], Integer.parseInt(ipNPort[1])));
+ } catch (UnknownHostException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ }
+ return config;
+ }
+
+ public void addEndpoint(Endpoint endpoint) {
+ if (findEndpoint(endpoint.getURI()).size() > 0) {
+ Member m = getOwningMember(endpoint.getURI());
+ throw new IllegalStateException("Endpoint " + endpoint.getURI() + " already exists in domain " + domainURI + " at " + (m == null? "null" : m.getInetSocketAddress()));
+ }
+
+ String localMemberAddr = hazelcastInstance.getCluster().getLocalMember().getInetSocketAddress().toString();
+ String endpointURI = endpoint.getURI();
+ String componentName = endpoint.getComponent().getName();
+ String curi = null;
+ if (endpoint instanceof RuntimeEndpoint) {
+ Composite dc = ((RuntimeEndpoint)endpoint).getCompositeContext().getDomainComposite();
+ if (dc != null) {
+ curi = dc.getContributionURI();
+ }
+ }
+ Transaction txn = hazelcastInstance.getTransaction();
+ txn.begin();
+ try {
+ localEndpoints.put(endpointURI, endpoint);
+ endpointMap.put(endpointURI, endpoint);
+ endpointOwners.put(localMemberAddr, endpointURI);
+ if (curi != null) {
+ runningComponentContributions.put(componentName, curi);
+ }
+ txn.commit();
+ } catch (Throwable e) {
+ txn.rollback();
+ throw new ServiceRuntimeException(e);
+ }
+ logger.info("Add endpoint - " + endpoint);
+ }
+
+ public List<Endpoint> findEndpoint(String uri) {
+ List<Endpoint> foundEndpoints = new ArrayList<Endpoint>();
+ for (Object v : endpointMap.values()) {
+ Endpoint endpoint = (Endpoint)v;
+ logger.fine("Matching against - " + endpoint);
+ if (endpoint.matches(uri)) {
+ endpoint = localizeEndpoint(endpoint);
+ foundEndpoints.add(endpoint);
+ logger.fine("Found endpoint with matching service - " + endpoint);
+ }
+ }
+ return foundEndpoints;
+ }
+
+ private Endpoint localizeEndpoint(Endpoint endpoint) {
+ if (endpoint == null) return null;
+ if (!isLocal(endpoint)) {
+ endpoint.setRemote(true);
+ ((RuntimeEndpoint)endpoint).bind(registry, this);
+ } else {
+ // get the local version of the endpoint
+ // this local version won't have been serialized
+ // won't be marked as remote and will have the
+ // full interface contract information
+ endpoint = localEndpoints.get(endpoint.getURI());
+ }
+ return endpoint;
+ }
+
+ private boolean isLocal(Endpoint endpoint) {
+ return localEndpoints.containsKey(endpoint.getURI());
+ }
+
+ public Endpoint getEndpoint(String uri) {
+ return localizeEndpoint((Endpoint)endpointMap.get(uri));
+ }
+
+ public List<Endpoint> getEndpoints() {
+ ArrayList<Endpoint> eps = new ArrayList();
+ for (Object ep : endpointMap.values()) {
+ eps.add(localizeEndpoint((Endpoint)ep));
+ }
+ return eps;
+ }
+
+ public void removeEndpoint(Endpoint endpoint) {
+ if (hazelcastInstance == null) {
+ return;
+ }
+ synchronized (shutdownMutex) {
+ String localMemberAddr = hazelcastInstance.getCluster().getLocalMember().getInetSocketAddress().toString();
+ String endpointURI = endpoint.getURI();
+ String componentName = endpoint.getComponent().getName();
+ Transaction txn = hazelcastInstance.getTransaction();
+ txn.begin();
+ try {
+ endpointOwners.remove(localMemberAddr, endpointURI);
+ endpointMap.remove(endpointURI);
+ runningComponentContributions.remove(componentName);
+ txn.commit();
+ } catch (Throwable e) {
+ txn.rollback();
+ throw new ServiceRuntimeException(e);
+ }
+ localEndpoints.remove(endpointURI);
+ logger.info("Removed endpoint - " + endpoint);
+ }
+ }
+
+
+ public void entryAdded(EntryEvent<String, Endpoint> event) {
+ entryAdded(event.getKey(), event.getValue());
+ }
+
+ public void entryEvicted(EntryEvent<String, Endpoint> event) {
+ // Should not happen
+ }
+
+ public void entryRemoved(EntryEvent<String, Endpoint> event) {
+ entryRemoved(event.getKey(), event.getValue());
+ }
+
+ public void entryUpdated(EntryEvent<String, Endpoint> event) {
+ entryUpdated(event.getKey(), null, event.getValue());
+ }
+
+ public void entryAdded(Object key, Object value) {
+ Endpoint newEp = (Endpoint)value;
+ if (!isLocal(newEp)) {
+ logger.info(" Remote endpoint added: " + newEp);
+ }
+ endpointAdded(newEp);
+ }
+
+ public void entryRemoved(Object key, Object value) {
+ Endpoint oldEp = (Endpoint)value;
+ if (!isLocal(oldEp)) {
+ logger.info(" Remote endpoint removed: " + value);
+ }
+ endpointRemoved(oldEp);
+ }
+
+ public void entryUpdated(Object key, Object oldValue, Object newValue) {
+ Endpoint oldEp = (Endpoint)oldValue;
+ Endpoint newEp = (Endpoint)newValue;
+ if (!isLocal(newEp)) {
+ logger.info(" Remote endpoint updated: " + newEp);
+ }
+ endpointUpdated(oldEp, newEp);
+ }
+
+ public void memberAdded(MembershipEvent event) {
+ }
+
+ public void memberRemoved(MembershipEvent event) {
+ try {
+ String memberAddr = event.getMember().getInetSocketAddress().toString();
+ if (endpointOwners.containsKey(memberAddr)) {
+ synchronized (shutdownMutex) {
+ ILock lock = hazelcastInstance.getLock("EndpointOwners/" + memberAddr);
+ lock.lock();
+ try {
+ if (endpointOwners.containsKey(memberAddr)) {
+ Collection<String> keys = endpointOwners.remove(memberAddr);
+ for (Object k : keys) {
+ Endpoint endpoint = (Endpoint)endpointMap.remove(k);
+ runningComponentContributions.remove(endpoint.getComponent().getName());
+ }
+ }
+ if (runningCompositeOwners.containsKey(memberAddr)) {
+ Map<String, List<String>> cs = runningCompositeOwners.remove(memberAddr);
+ for (String curi : cs.keySet()) {
+ Map<String, String> rcs = runningComposites.get(curi);
+ for (String uri : cs.get(curi)) {
+ rcs.remove(uri);
+ }
+ }
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+ }
+ } catch (Exception e) {
+ if (e.getCause() != null && e.getCause().getCause() != null) {
+ // ignore hazelcast already shutdown exception
+ if (!"Hazelcast Instance is not active!".equals(e.getCause().getCause().getMessage())) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+ }
+ }
+
+ public Member getOwningMember(String serviceURI) {
+ for (String memberAddr : endpointOwners.keySet()) {
+ for (String service : endpointOwners.get(memberAddr)) {
+ Endpoint ep = assemblyFactory.createEndpoint();
+ ep.setURI(service);
+ if (ep.matches(serviceURI)) {
+ for (Member m : getHazelcastInstance().getCluster().getMembers()) {
+ if (memberAddr.equals(m.getInetSocketAddress().toString())) {
+ return m;
+ }
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ public void addRunningComposite(String curi, Composite composite) {
+ String localMemberAddr = hazelcastInstance.getCluster().getLocalMember().getInetSocketAddress().toString();
+ String compositeXML = writeComposite(composite);
+ Transaction txn = hazelcastInstance.getTransaction();
+ txn.begin();
+ try {
+ Map<String, String> cs = runningComposites.get(curi);
+ if (cs == null) {
+ cs = new HashMap<String, String>();
+ }
+ cs.put(composite.getURI(), compositeXML);
+ runningComposites.put(curi, cs);
+ Map<String, List<String>> ocs = runningCompositeOwners.get(localMemberAddr);
+ if (ocs == null) {
+ ocs = new HashMap<String, List<String>>();
+ }
+ List<String> lcs = ocs.get(curi);
+ if (lcs == null) {
+ lcs = new ArrayList<String>();
+ ocs.put(curi, lcs);
+ }
+ lcs.add(composite.getURI());
+ runningCompositeOwners.put(localMemberAddr, ocs);
+ txn.commit();
+ } catch (Throwable e) {
+ txn.rollback();
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ public void removeRunningComposite(String curi, String compositeURI) {
+ String localMemberAddr = hazelcastInstance.getCluster().getLocalMember().getInetSocketAddress().toString();
+ Transaction txn = hazelcastInstance.getTransaction();
+ txn.begin();
+ try {
+ Map<String, String> cs = runningComposites.get(curi);
+ if (cs != null) {
+ cs.remove(compositeURI);
+ if (cs.size() > 0) {
+ runningComposites.put(curi, cs);
+ } else {
+ runningComposites.remove(curi);
+ }
+ }
+ Map<String, List<String>> ocs = runningCompositeOwners.get(localMemberAddr);
+ if (ocs != null) {
+ List<String> xya = ocs.get(curi);
+ if (xya != null) {
+ xya.remove(compositeURI);
+ if (xya.size() > 0) {
+ runningCompositeOwners.put(localMemberAddr, ocs);
+ } else {
+ runningCompositeOwners.remove(localMemberAddr);
+ }
+ }
+ }
+ txn.commit();
+ } catch (Throwable e) {
+ txn.rollback();
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ public Map<String, List<String>> getRunningCompositeURIs() {
+ Map<String, List<String>> compositeURIs = new HashMap<String, List<String>>();
+ for (String curi : runningComposites.keySet()) {
+ List<String> uris = new ArrayList<String>();
+ compositeURIs.put(curi, uris);
+ for (String uri : runningComposites.get(curi).keySet()) {
+ uris.add(uri);
+ }
+ }
+ return compositeURIs;
+ }
+
+ @Override
+ public Composite getRunningComposite(String contributionURI, String compositeURI) {
+ Map<String, String> cs = runningComposites.get(contributionURI);
+ if (cs != null) {
+ String compositeXML = cs.get(compositeURI);
+ // TODO: cache the Composite locally so that it doesn't get deserialized multiple times
+ Composite composite = readComposite(compositeXML);
+ composite.setContributionURI(contributionURI);
+ return composite;
+ }
+ return null;
+ }
+
+ protected Composite readComposite(String compositeXML) {
+ try {
+ StAXHelper stAXHelper = StAXHelper.getInstance(registry);
+ StAXArtifactProcessorExtensionPoint staxProcessors = registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+ ExtensibleStAXArtifactProcessor staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, stAXHelper.getInputFactory(), null);
+ XMLStreamReader reader = stAXHelper.createXMLStreamReader(compositeXML);
+ Composite composite = (Composite)staxProcessor.read(reader, new ProcessorContext(registry));
+ return composite;
+ } catch (XMLStreamException e) {
+ throw new RuntimeException(e);
+ } catch (ContributionReadException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ protected String writeComposite(Composite composite) {
+ try {
+ StAXHelper stAXHelper = StAXHelper.getInstance(registry);
+ StAXArtifactProcessorExtensionPoint staxProcessors = registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+ ExtensibleStAXArtifactProcessor staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, null, stAXHelper.getOutputFactory());
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ staxProcessor.write(composite, bos, new ProcessorContext(registry));
+ bos.close();
+ return bos.toString();
+ } catch (ContributionWriteException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public List<String> getInstalledContributionURIs() {
+ return new ArrayList<String>(contributionDescriptions.keySet());
+ }
+
+ public ContributionDescription getInstalledContribution(String uri) {
+ return contributionDescriptions.get(uri);
+ }
+
+ public void uninstallContribution(String uri) {
+ contributionDescriptions.remove(uri);
+ }
+
+ @Override
+ public void installContribution(ContributionDescription cd) {
+ contributionDescriptions.put(cd.getURI(), cd);
+ }
+
+ @Override
+ public void updateInstalledContribution(ContributionDescription cd) {
+ contributionDescriptions.put(cd.getURI(), cd);
+ }
+
+ @Override
+ public List<String> getNodeNames() {
+ List<String> members = new ArrayList<String>();
+ for (Member m : hazelcastInstance.getCluster().getMembers()) {
+ if (!m.isSuperClient()) {
+ members.add(m.getInetSocketAddress().toString());
+ }
+ }
+ return members;
+ }
+
+ @Override
+ public String getLocalNodeName() {
+ return hazelcastInstance.getCluster().getLocalMember().getInetSocketAddress().toString();
+ }
+
+ @Override
+ public String getRunningNodeName(String contributionURI, String compositeURI) {
+ for (String m : runningCompositeOwners.keySet()) {
+ Map<String, List<String>> rcs = runningCompositeOwners.get(m);
+ if (rcs != null) {
+ List<String> cs = rcs.get(contributionURI);
+ if (cs != null && cs.contains(compositeURI)) {
+ return m;
+ }
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String remoteCommand(String memberName, Callable<String> command) {
+ for (Member member : hazelcastInstance.getCluster().getMembers()) {
+ if (member.getInetSocketAddress().toString().equals(memberName)) {
+ FutureTask<String> task = new DistributedTask<String>(command, member);
+ hazelcastInstance.getExecutorService().execute(task);
+ try {
+ return task.get();
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+ }
+ throw new IllegalArgumentException("member not found: " + memberName);
+ }
+
+ @Override
+ public String getContainingCompositesContributionURI(String componentName) {
+ int x = runningComponentContributions.size();
+ return runningComponentContributions.get(componentName);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/HazelcastDomainRegistryFactory.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/HazelcastDomainRegistryFactory.java
new file mode 100644
index 0000000000..ca75679caa
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/HazelcastDomainRegistryFactory.java
@@ -0,0 +1,49 @@
+/*
+ * 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.registry.hazelcast;
+
+import java.util.Properties;
+
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.runtime.BaseDomainRegistryFactory;
+import org.apache.tuscany.sca.runtime.DomainRegistry;
+import org.apache.tuscany.sca.runtime.RuntimeProperties;
+
+/**
+ * The utility responsible for finding the endpoint regstry by the scheme and creating instances for the
+ * given domain
+ */
+public class HazelcastDomainRegistryFactory extends BaseDomainRegistryFactory {
+ private final static String[] schemes = new String[] {"multicast", "wka", "tuscany", "hazelcast", "uri"};
+
+ public HazelcastDomainRegistryFactory(ExtensionPointRegistry registry) {
+ super(registry);
+ }
+
+ protected DomainRegistry createEndpointRegistry(String domainURI, String domainName) {
+ Properties properties = registry.getExtensionPoint(UtilityExtensionPoint.class).getUtility(RuntimeProperties.class).getProperties();
+ return new HazelcastDomainRegistry(registry, properties, domainURI, domainName);
+ }
+
+ public String[] getSupportedSchemes() {
+ return schemes;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/RegistryConfig.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/RegistryConfig.java
new file mode 100644
index 0000000000..316abc7e2d
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/RegistryConfig.java
@@ -0,0 +1,177 @@
+/*
+ * 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.registry.hazelcast;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+
+/**
+ * Utility to parse the config properties.
+ *
+ * bind - ip[:port] - defines the local bind address and port, it defaults port 14820 and if that port in use it will try
+ * incrementing by one till a free port is found.
+ *
+ * multicast - groupip:port | off - defines if multicast discovery is used and if so what multicast ip group and port is used
+ * defaults to 224.5.12.10:51482. A value of off means multicast is disabled.
+ *
+ * wka - ip[:port] - a comma separated list of ip address and port for remote nodes in the domain group. The port defaults to 14820.
+ *
+ * userid - is the userid other nodes must use to connect to this domain group. The default is the default domain name.
+ *
+ * password - is the password other nodes must use to connect to this domain group. The default is 'tuscany'.
+ *
+ * client - true means this is an SCAClient call
+ *
+ */
+public class RegistryConfig {
+
+ private String bindAddress = "*";
+ private int bindPort = 14820;
+ private boolean multicastDisabled = false;
+ private String multicastAddress = "224.5.12.10";
+ private int multicastPort = 51482;
+ private List<String> wkas = new ArrayList<String>();
+ private String userid;
+ private String password;
+ boolean client;
+
+ public RegistryConfig(Properties properties) {
+ init(properties);
+ }
+
+ private void init(Properties properties) {
+
+ String bindValue = properties.getProperty("bind");
+ if (bindValue != null) {
+ if (bindValue.indexOf(":") == -1) {
+ this.bindAddress = bindValue;
+ } else {
+ String[] addr = bindValue.split(":");
+ this.bindAddress = addr[0];
+ this.bindPort = Integer.parseInt(addr[1]);
+ }
+ }
+
+ String multicastValue = properties.getProperty("multicast");
+ if (multicastValue != null) {
+ if ("off".equalsIgnoreCase(multicastValue)) {
+ this.multicastDisabled = true;
+ } else {
+ if (multicastValue.indexOf(":") == -1) {
+ this.multicastAddress = multicastValue;
+ } else {
+ String[] addr = multicastValue.split(":");
+ this.multicastAddress = addr[0];
+ this.multicastPort = Integer.parseInt(addr[1]);
+ }
+ }
+ }
+
+ String wkaValue = properties.getProperty("wka");
+ if (wkaValue != null) {
+ String[] ips = wkaValue.split(",");
+ for (String ip : ips) {
+ if (ip.indexOf(":") == -1) {
+ wkas.add(ip + ":14820");
+ } else {
+ wkas.add(ip);
+ }
+ }
+ }
+
+ this.client = Boolean.parseBoolean(properties.getProperty("client", "false"));
+ this.password = properties.getProperty("password", "tuscany");
+ this.userid = properties.getProperty("userid", properties.getProperty("defaultDomainName", "default"));
+
+ }
+
+ public String getBindAddress() {
+ return bindAddress;
+ }
+
+ public int getBindPort() {
+ return bindPort;
+ }
+
+ public boolean isMulticastDisabled() {
+ return multicastDisabled;
+ }
+
+ public String getMulticastAddress() {
+ return multicastAddress;
+ }
+
+ public int getMulticastPort() {
+ return multicastPort;
+ }
+
+ public List<String> getWKAs() {
+ return wkas;
+ }
+
+ public String getUserid() {
+ return userid;
+ }
+ public String getPassword() {
+ return password;
+ }
+
+ /**
+ * Parse the config string into a Properties object.
+ * The config URI has the following format:
+ * uri:<domainName>?name=value&...
+ */
+ public static RegistryConfig parseConfigURI(String configURI) {
+ Properties properties = new Properties();
+ int c = configURI.indexOf(':');
+ if (c > -1) {
+ configURI = configURI.substring(c+1);
+ }
+ int qm = configURI.indexOf('?');
+ if (qm < 0) {
+ properties.setProperty("defaultDomainName", configURI);
+ } else {
+ if (qm == 0) {
+ properties.setProperty("defaultDomainName", "default");
+ } else {
+ properties.setProperty("defaultDomainName", configURI.substring(0, qm));
+ }
+ if (configURI.length() > qm+1) {
+ Map<String, String> params = new HashMap<String, String>();
+ for (String param : configURI.substring(qm+1).split("&")) {
+ String[] px = param.split("=");
+ if (px.length == 2) {
+ params.put(px[0], px[1]);
+ } else {
+ params.put(px[0], "");
+ }
+ }
+ for (String name : params.keySet()) {
+ properties.setProperty(name, params.get(name));
+ }
+ }
+ }
+ return new RegistryConfig(properties);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/client/HazelcastClientDomainRegistryFactory.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/client/HazelcastClientDomainRegistryFactory.java
new file mode 100644
index 0000000000..5193b577da
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/client/HazelcastClientDomainRegistryFactory.java
@@ -0,0 +1,49 @@
+/*
+ * 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.registry.hazelcast.client;
+
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.runtime.BaseDomainRegistryFactory;
+import org.apache.tuscany.sca.runtime.DomainRegistry;
+
+/**
+ * The utility responsible for finding the endpoint regstry by the scheme and creating instances for the
+ * given domain
+ */
+public class HazelcastClientDomainRegistryFactory extends BaseDomainRegistryFactory {
+ private final static String[] schemes = new String[] {"hazelcastclient", "tuscanyclient"};
+
+ /**
+ * @param extensionRegistry
+ */
+ public HazelcastClientDomainRegistryFactory(ExtensionPointRegistry registry) {
+ super(registry);
+ }
+
+ protected DomainRegistry createEndpointRegistry(String endpointRegistryURI, String domainURI) {
+ DomainRegistry domainRegistry =
+ new HazelcastClientEndpointRegistry(registry, null, endpointRegistryURI, domainURI);
+ return domainRegistry;
+ }
+
+ public String[] getSupportedSchemes() {
+ return schemes;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/client/HazelcastClientEndpointRegistry.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/client/HazelcastClientEndpointRegistry.java
new file mode 100644
index 0000000000..972bd43075
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/java/org/apache/tuscany/sca/registry/hazelcast/client/HazelcastClientEndpointRegistry.java
@@ -0,0 +1,132 @@
+/*
+ * 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.registry.hazelcast.client;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.registry.hazelcast.HazelcastDomainRegistry;
+import org.apache.tuscany.sca.registry.hazelcast.RegistryConfig;
+import org.apache.tuscany.sca.runtime.RuntimeProperties;
+
+import com.hazelcast.client.ClientProperties;
+import com.hazelcast.client.ClientProperties.ClientPropertyName;
+import com.hazelcast.client.HazelcastClient;
+import com.hazelcast.core.HazelcastInstance;
+
+/**
+ * An DomainRegistry using a Hazelcast Native Client
+ */
+public class HazelcastClientEndpointRegistry extends HazelcastDomainRegistry {
+
+ RegistryConfig rc;
+ HazelcastClient hazelcastClient;
+
+ public HazelcastClientEndpointRegistry(ExtensionPointRegistry registry,
+ Map<String, String> attributes,
+ String domainRegistryURI,
+ String domainURI) {
+ super(registry, attributes, domainRegistryURI, domainURI);
+ }
+
+ @Override
+ public void start() {
+ if (endpointMap != null) {
+ throw new IllegalStateException("The registry has already been started");
+ }
+ initHazelcastClientInstance();
+ endpointMap = hazelcastClient.getMap(rc.getUserid() + "/Endpoints");
+ endpointOwners = hazelcastClient.getMultiMap(rc.getUserid() + "/EndpointOwners");
+ runningComponentContributions = hazelcastClient.getMap(rc.getUserid() + "/RunningComponentContributions");
+ contributionDescriptions = hazelcastClient.getMap(rc.getUserid() + "/ContributionDescriptions");
+ }
+
+ @Override
+ public void stop() {
+ if (hazelcastClient != null) {
+ hazelcastClient.shutdown();
+ hazelcastClient = null;
+ endpointMap = null;
+ }
+ }
+
+ private void initHazelcastClientInstance() {
+ if (this.domainURI == null) {
+ this.properties = registry.getExtensionPoint(UtilityExtensionPoint.class).getUtility(RuntimeProperties.class).getProperties();
+ this.domainURI = properties.getProperty("defaultDomainName", "default");
+ }
+ this.rc = RegistryConfig.parseConfigURI(domainURI);
+ if (rc.getWKAs().size() < 1) {
+ String ip = getDefaultWKA();
+ if (ip != null) {
+ rc.getWKAs().add(ip);
+ }
+ }
+ if (rc.getWKAs().size() < 1) {
+ throw new IllegalArgumentException("No local domain instance found, please use domain URI 'wka=' argument to define IP address(es) for domain");
+ }
+
+ // Hazelcast is outputs a lot on info level log messages which are unnecessary for us,
+ // so disable info logging for hazelcast client classes unless fine logging is on for tuscany.
+ if (!Logger.getLogger(this.getClass().getName()).isLoggable(Level.CONFIG)) {
+ Logger hzl = Logger.getLogger("com.hazelcast");
+ if (!hzl.isLoggable(Level.FINE)) {
+ hzl.setLevel(Level.WARNING);
+ }
+ }
+
+ ClientProperties clientProps = ClientProperties.crateBaseClientProperties(rc.getUserid(), rc.getPassword());
+ clientProps.setPropertyValue(ClientPropertyName.INIT_CONNECTION_ATTEMPTS_LIMIT, "1");
+ this.hazelcastClient = HazelcastClient.newHazelcastClient(clientProps, rc.getWKAs().toArray(new String[0]));
+ }
+
+ @Override
+ public HazelcastInstance getHazelcastInstance() {
+ return hazelcastClient;
+ }
+
+ /**
+ * As a default connect to a local runtime instance listening on port 14820
+ */
+ protected static String getDefaultWKA() {
+ Socket s = null;
+ try {
+ s = new Socket(InetAddress.getLocalHost(), 14820);
+ if (s.isConnected()) {
+ return s.getInetAddress().getHostAddress() + ":14820";
+ }
+ } catch (IOException e) {
+ } finally {
+ if (s != null) {
+ try {
+ s.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor
new file mode 100644
index 0000000000..2fc977b41f
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor
@@ -0,0 +1,21 @@
+# 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.
+
+# Implementation class for the artifact processor extension
+org.apache.tuscany.sca.assembly.xml.DefaultBeanModelProcessor;qname=http://tuscany.apache.org/xmlns/sca/1.1#binding.hazelcast,model=org.apache.tuscany.sca.binding.hazelcast.HazelcastBinding
+
+
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.BindingProviderFactory b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.BindingProviderFactory
new file mode 100644
index 0000000000..3878c5f0da
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.BindingProviderFactory
@@ -0,0 +1,19 @@
+# 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.
+
+# Implementation class for the binding extension
+org.apache.tuscany.sca.binding.hazelcast.HazelcastBindingProviderFactory;model=org.apache.tuscany.sca.binding.hazelcast.HazelcastBinding
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/resources/META-INF/services/org.apache.tuscany.sca.runtime.DomainRegistryFactory b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/resources/META-INF/services/org.apache.tuscany.sca.runtime.DomainRegistryFactory
new file mode 100644
index 0000000000..4b461bceca
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/main/resources/META-INF/services/org.apache.tuscany.sca.runtime.DomainRegistryFactory
@@ -0,0 +1,18 @@
+# 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.
+org.apache.tuscany.sca.registry.hazelcast.HazelcastDomainRegistryFactory;ranking=100
+org.apache.tuscany.sca.registry.hazelcast.client.HazelcastClientDomainRegistryFactory;ranking=100
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/BadStringException.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/BadStringException.java
new file mode 100644
index 0000000000..937046f0b1
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/BadStringException.java
@@ -0,0 +1,29 @@
+/*
+ * 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.binding.hazelcast;
+
+public class BadStringException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ public BadStringException(String msg) {
+ super(msg);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/ComplexType.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/ComplexType.java
new file mode 100644
index 0000000000..68353c89cf
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/ComplexType.java
@@ -0,0 +1,33 @@
+/*
+ * 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.binding.hazelcast;
+
+public class ComplexType {
+
+ private String s;
+
+ public void setString(String s) {
+ this.s = s;
+ }
+
+ public String getString() {
+ return s;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastBindingTestCase.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastBindingTestCase.java
new file mode 100644
index 0000000000..1cc857e7a4
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/HazelcastBindingTestCase.java
@@ -0,0 +1,116 @@
+/*
+ * 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.binding.hazelcast;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import org.apache.tuscany.sca.node.Node;
+import org.apache.tuscany.sca.node.NodeFactory;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.oasisopen.sca.ServiceRuntimeException;
+
+@Ignore
+public class HazelcastBindingTestCase {
+
+ private static Node serviceNode;
+ private static Node clientNode;
+
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ // Note use of NodeFactory.newInstance() so as to start separate runtimes
+ serviceNode = NodeFactory.newInstance("uri:HazelcastBindingTestCase?bind=127.0.0.1").createNode("service.composite", new String[]{"target/test-classes"});
+ serviceNode.start();
+ clientNode = NodeFactory.newInstance("uri:HazelcastBindingTestCase?bind=127.0.0.1").createNode("client.composite", new String[]{"target/test-classes"});
+ clientNode.start();
+ }
+
+ @Test
+ public void testNestedClient() throws Exception {
+ Node client2Node = NodeFactory.newInstance("uri:HazelcastBindingTestCase?bind=127.0.0.1").createNode("client2.composite", new String[]{"target/test-classes"});
+ client2Node.start();
+ TestService service = client2Node.getService(TestService.class, "TestServiceClient2");
+ assertNotNull(service);
+ assertEquals("Petra", service.echoString("Petra"));
+ client2Node.stop();
+ }
+
+ @Test
+ public void testEchoString() throws Exception {
+ TestService service = clientNode.getService(TestService.class, "TestServiceClient");
+ assertNotNull(service);
+ assertEquals("Petra", service.echoString("Petra"));
+ }
+
+ @Test
+ public void testOnewayString() throws Exception {
+ TestService service = clientNode.getService(TestService.class, "TestServiceClient");
+ assertNotNull(service);
+ service.onewayString("Petra");
+ }
+
+ @Test
+ public void testEchoComplexType() throws Exception {
+ TestService service = clientNode.getService(TestService.class, "TestServiceClient");
+ assertNotNull(service);
+ ComplexType ct = new ComplexType();
+ ct.setString("beate");
+ assertEquals("beate", service.echoComplexType(ct).getString());
+ }
+
+ @Test
+ public void testDeclaredException() throws Exception {
+ TestService service = clientNode.getService(TestService.class, "TestServiceClient");
+ assertNotNull(service);
+ try {
+ service.testExceptions("Sue");
+ fail();
+ } catch (BadStringException e) {
+ assertEquals("Sue", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testRuntimeException() throws Exception {
+ TestService service = clientNode.getService(TestService.class, "TestServiceClient");
+ assertNotNull(service);
+ try {
+ service.testExceptions("runtime");
+ fail();
+ } catch (ServiceRuntimeException e) {
+ assertEquals("org.oasisopen.sca.ServiceRuntimeException: Remote exception: class java.lang.RuntimeException:runtime", e.getMessage());
+ }
+ }
+
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ if (clientNode != null) {
+ clientNode.stop();
+ }
+ if (serviceNode != null) {
+ serviceNode.stop();
+ }
+ }
+}
+
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/TestService.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/TestService.java
new file mode 100644
index 0000000000..3ffcb0d384
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/TestService.java
@@ -0,0 +1,30 @@
+/*
+ * 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.binding.hazelcast;
+
+import org.oasisopen.sca.annotation.Remotable;
+
+@Remotable
+public interface TestService {
+ String echoString(String s);
+ void onewayString(String s);
+ ComplexType echoComplexType(ComplexType ct);
+ String testExceptions(String s) throws BadStringException;
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/TestServiceClient.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/TestServiceClient.java
new file mode 100644
index 0000000000..4b462068f0
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/TestServiceClient.java
@@ -0,0 +1,45 @@
+/*
+ * 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.binding.hazelcast;
+
+import org.oasisopen.sca.annotation.Reference;
+
+public class TestServiceClient implements TestService {
+
+ @Reference
+ public TestService service;
+
+ public String echoString(String s) {
+ return service.echoString(s);
+ }
+
+ public void onewayString(String s) {
+ service.onewayString(s);
+ }
+
+ public ComplexType echoComplexType(ComplexType ct) {
+ return service.echoComplexType(ct);
+ }
+
+ public String testExceptions(String s) throws BadStringException {
+ return service.testExceptions(s);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/TestServiceImpl.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/TestServiceImpl.java
new file mode 100644
index 0000000000..1f5a3872c6
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/binding/hazelcast/TestServiceImpl.java
@@ -0,0 +1,43 @@
+/*
+ * 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.binding.hazelcast;
+
+public class TestServiceImpl implements TestService {
+
+ public String echoString(String s) {
+ return s;
+ }
+
+ public void onewayString(String s) {
+ System.out.println("onewayString " + s);
+ }
+
+ public ComplexType echoComplexType(ComplexType ct) {
+ return ct;
+ }
+
+ public String testExceptions(String s) throws BadStringException {
+ if (s.equals("runtime")) {
+ throw new RuntimeException("runtime");
+ }
+ throw new BadStringException(s);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/registry/hazelcast/MultiRegTestCase.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/registry/hazelcast/MultiRegTestCase.java
new file mode 100644
index 0000000000..72188f29b7
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/registry/hazelcast/MultiRegTestCase.java
@@ -0,0 +1,218 @@
+/*
+ * 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.registry.hazelcast;
+
+import java.util.Properties;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.Endpoint;
+import org.apache.tuscany.sca.assembly.SCABindingFactory;
+import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry;
+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.interfacedef.Interface;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
+import org.apache.tuscany.sca.registry.hazelcast.HazelcastDomainRegistry;
+import org.apache.tuscany.sca.runtime.RuntimeEndpoint;
+import org.apache.tuscany.sca.runtime.RuntimeProperties;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class MultiRegTestCase {
+ private static ExtensionPointRegistry extensionPoints;
+ private static AssemblyFactory assemblyFactory;
+ private static SCABindingFactory scaBindingFactory;
+
+ @BeforeClass
+ public static void init() {
+ extensionPoints = new DefaultExtensionPointRegistry();
+ FactoryExtensionPoint factories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class);
+ assemblyFactory = factories.getFactory(AssemblyFactory.class);
+ scaBindingFactory = factories.getFactory(SCABindingFactory.class);
+ Properties properties = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class).getUtility(RuntimeProperties.class).getProperties();
+ properties.setProperty("bind", "127.0.0.1");
+ }
+
+ @Test
+ public void testReplication() throws Exception {
+
+ System.out.println("Starting reg1");
+ HazelcastDomainRegistry reg1 = new HazelcastDomainRegistry(extensionPoints, (Properties)null, "tuscany:foo?bind=127.0.0.1:9876&multicast=off", "bar");
+ reg1.start();
+
+ System.out.println("Adding ep1");
+ RuntimeEndpoint ep1 = createEndpoint("ep1uri");
+ ep1.bind(extensionPoints, reg1);
+ reg1.addEndpoint(ep1);
+
+ System.out.println("Starting reg3");
+ HazelcastDomainRegistry reg2 = new HazelcastDomainRegistry(extensionPoints, (Properties)null, "tuscany:foo?bind=127.0.0.1:9877&multicast=off&wka=127.0.0.1:9876", "bar");
+ reg2.start();
+
+ System.out.println("Starting reg2");
+ HazelcastDomainRegistry reg3 = new HazelcastDomainRegistry(extensionPoints, (Properties)null, "tuscany:foo?bind=127.0.0.1:9878&multicast=off&wka=127.0.0.1:9877", "bar");
+ reg3.start();
+
+ assertExists(reg1, "ep1uri");
+ assertExists(reg2, "ep1uri");
+ assertExists(reg3, "ep1uri");
+
+ System.out.println("Adding ep2");
+ RuntimeEndpoint ep2 = createEndpoint("ep2uri");
+ ep2.bind(extensionPoints, reg2);
+ reg2.addEndpoint(ep2);
+
+ assertExists(reg2, "ep2uri");
+ assertExists(reg1, "ep2uri");
+ assertExists(reg3, "ep2uri");
+
+ System.out.println("Stopping reg1");
+ reg1.stop();
+ System.out.println("Stopped reg1");
+ Thread.sleep(500);
+
+ Assert.assertNull(reg2.getEndpoint("ep1uri"));
+ Assert.assertNull(reg3.getEndpoint("ep1uri"));
+
+ assertExists(reg2, "ep2uri");
+ assertExists(reg3, "ep2uri");
+
+ System.out.println("Starting reg1");
+ reg1.start();
+ ep1.bind(extensionPoints, reg1);
+
+ System.out.println("adding ep1");
+ reg1.addEndpoint(ep1);
+ assertExists(reg1, "ep1uri");
+ assertExists(reg2, "ep1uri");
+ assertExists(reg3, "ep1uri");
+
+ System.out.println("Stopping reg1");
+ reg1.stop();
+ System.out.println("Stopping reg2");
+ reg2.stop();
+ System.out.println("Stopping reg3");
+ reg3.stop();
+ System.out.println("done");
+ }
+
+ @Test
+ public void testDuplicates() throws Exception {
+ HazelcastDomainRegistry reg1 = new HazelcastDomainRegistry(extensionPoints, (Properties)null, "tuscany:foo?bind=127.0.0.1:9876&multicast=off", "bar");
+ reg1.start();
+ RuntimeEndpoint ep1 = createEndpoint("ep1uri");
+ ep1.bind(extensionPoints, reg1);
+ reg1.addEndpoint(ep1);
+
+ HazelcastDomainRegistry reg2 = new HazelcastDomainRegistry(extensionPoints, (Properties)null, "tuscany:foo?bind=127.0.0.1:9877&multicast=off&wka=127.0.0.1:9876", "bar");
+ reg2.start();
+
+ try {
+ reg2.addEndpoint(ep1);
+ Assert.fail();
+ } catch (IllegalStateException e) {
+ // expected
+ }
+
+ reg1.stop();
+
+ Thread.sleep(200);
+
+ // now it should work
+ reg2.addEndpoint(ep1);
+
+ reg2.stop();
+ }
+
+ private Endpoint assertExists(HazelcastDomainRegistry reg, String uri) throws InterruptedException {
+ Endpoint ep = reg.getEndpoint(uri);
+ Assert.assertNotNull(ep);
+ Assert.assertEquals(uri, ep.getURI());
+ return ep;
+ }
+
+ private RuntimeEndpoint createEndpoint(String uri) {
+ RuntimeEndpoint ep = (RuntimeEndpoint) assemblyFactory.createEndpoint();
+ Component comp = assemblyFactory.createComponent();
+ ep.setComponent(comp);
+ ep.setService(assemblyFactory.createComponentService());
+ ep.getService().setInterfaceContract(getIC());
+ Binding b = scaBindingFactory.createSCABinding();
+ ep.setBinding(b);
+ ep.setURI(uri);
+ return ep;
+ }
+
+ private InterfaceContract getIC() {
+ InterfaceContract ic = new JavaInterfaceContract(){
+
+ public Object clone() throws CloneNotSupportedException {
+ return null;
+ }
+ @Override
+ public Interface getInterface() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void setInterface(Interface callInterface) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public Interface getCallbackInterface() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void setCallbackInterface(Interface callbackInterface) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public InterfaceContract makeUnidirectional(boolean isCallback) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public InterfaceContract getNormalizedWSDLContract() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void setNormalizedWSDLContract(InterfaceContract wsdlInterfaceContract) {
+ // TODO Auto-generated method stub
+
+ }};
+ return ic;
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/registry/hazelcast/RegistryTestCase.java b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/registry/hazelcast/RegistryTestCase.java
new file mode 100644
index 0000000000..934c77484e
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/java/org/apache/tuscany/sca/registry/hazelcast/RegistryTestCase.java
@@ -0,0 +1,142 @@
+/*
+ * 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.registry.hazelcast;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.junit.Ignore;
+import org.junit.Test;
+
+import com.hazelcast.config.Config;
+import com.hazelcast.config.TcpIpConfig;
+import com.hazelcast.config.XmlConfigBuilder;
+import com.hazelcast.core.Hazelcast;
+import com.hazelcast.core.HazelcastInstance;
+import com.hazelcast.core.IMap;
+import com.hazelcast.nio.Address;
+
+@Ignore
+public class RegistryTestCase {
+
+ @Test
+ public void test1() throws UnknownHostException {
+
+ HazelcastInstance h1 = create("54327", 9001);
+
+ IMap<Object, Object> h1map = h1.getMap("mymap");
+ h1map.put("key1", "bla1");
+ Assert.assertEquals("bla1", h1map.get("key1"));
+
+ HazelcastInstance h2 = create("false", 9002, 9001);
+ IMap<Object, Object> h2map = h2.getMap("mymap");
+ Assert.assertEquals("bla1", h2map.get("key1"));
+
+ HazelcastInstance h3 = create("false", 9003, 9002);
+ IMap<Object, Object> h3map = h3.getMap("mymap");
+ Assert.assertEquals("bla1", h3map.get("key1"));
+
+ h3map.put("k3", "v3");
+ h2map.put("k2", "v2");
+
+ Assert.assertEquals("v2", h1map.get("k2"));
+ Assert.assertEquals("v3", h1map.get("k3"));
+ Assert.assertEquals("v2", h2map.get("k2"));
+ Assert.assertEquals("v3", h2map.get("k3"));
+ Assert.assertEquals("v2", h3map.get("k2"));
+ Assert.assertEquals("v3", h3map.get("k3"));
+
+ HazelcastInstance h4 = create("54328", 9004, 9001);
+ IMap<Object, Object> h4map = h4.getMap("mymap");
+// Assert.assertNull(h4map.get("k2"));
+// Assert.assertNull(h4map.get("k3"));
+ Assert.assertEquals("v2", h4map.get("k2"));
+ Assert.assertEquals("v3", h4map.get("k3"));
+
+// HazelcastInstance h5 = create("false", 9005, 9003, 9004);
+ HazelcastInstance h5 = create("54328", 9005);
+
+// Assert.assertEquals("v2", h4map.get("k2"));
+// Assert.assertEquals("v3", h4map.get("k3"));
+
+ IMap<Object, Object> h5map = h5.getMap("mymap");
+ Assert.assertEquals("v2", h5map.get("k2"));
+ Assert.assertEquals("v3", h5map.get("k3"));
+
+ h1.shutdown();
+
+ Assert.assertEquals("v2", h2map.get("k2"));
+ Assert.assertEquals("v3", h2map.get("k3"));
+ Assert.assertEquals("v2", h3map.get("k2"));
+ Assert.assertEquals("v3", h3map.get("k3"));
+ Assert.assertEquals("v2", h4map.get("k2"));
+ Assert.assertEquals("v3", h4map.get("k3"));
+
+ h3map.put("key1a", "bla1a");
+
+ Assert.assertEquals("bla1a", h2map.get("key1a"));
+ Assert.assertEquals("bla1a", h3map.get("key1a"));
+ Assert.assertEquals("bla1a", h4map.get("key1a"));
+
+// HazelcastInstance h4 = create(true, 9004, 9003);
+// HazelcastInstance h5 = create(true, 9005);
+// IMap<Object, Object> h5map = h5.getMap("mymap");
+// Assert.assertEquals("bla1", h5map.get("key1"));
+
+// HazelcastInstance h6 = create(false, 9006, 9005);
+// IMap<Object, Object> h6map = h6.getMap("mymap");
+// Assert.assertEquals("bla1", h6map.get("key1"));
+
+ }
+
+ private HazelcastInstance create(String multicast, int listenPort, int... connectPorts) throws UnknownHostException {
+ Config config = new XmlConfigBuilder().build();
+ config.setPort(listenPort);
+ config.setPortAutoIncrement(false);
+
+ // declare the interface Hazelcast should bind to
+ config.getNetworkConfig().getInterfaces().clear();
+ config.getNetworkConfig().getInterfaces().addInterface(InetAddress.getLocalHost().getHostAddress());
+ config.getNetworkConfig().getInterfaces().setEnabled(true);
+
+ if ("false".equals(multicast)) {
+ config.getNetworkConfig().getJoin().getMulticastConfig().setEnabled(false);
+ } else {
+ config.getNetworkConfig().getJoin().getMulticastConfig().setMulticastPort(Integer.parseInt(multicast));
+ }
+
+ if (connectPorts.length > 0) {
+ TcpIpConfig tcpconfig = config.getNetworkConfig().getJoin().getTcpIpConfig();
+ tcpconfig.setEnabled(true);
+
+ List<Address> lsMembers = tcpconfig.getAddresses();
+ lsMembers.clear();
+ for (int p : connectPorts) {
+ lsMembers.add(new Address(InetAddress.getLocalHost(), p));
+ }
+ }
+
+ return Hazelcast.newHazelcastInstance(config);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/resources/client.composite b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/resources/client.composite
new file mode 100644
index 0000000000..7436a5e24b
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/resources/client.composite
@@ -0,0 +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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ targetNamespace="http://itest"
+ name="TestServiceClient">
+
+ <component name="TestServiceClient">
+ <implementation.java class="org.apache.tuscany.sca.binding.hazelcast.TestServiceClient"/>
+ <reference name="service" target="TestService"/>
+ </component>
+
+</composite>
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/resources/client2.composite b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/resources/client2.composite
new file mode 100644
index 0000000000..20667984ca
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/resources/client2.composite
@@ -0,0 +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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ targetNamespace="http://itest"
+ name="TestServiceClient2">
+
+ <component name="TestServiceClient2">
+ <implementation.java class="org.apache.tuscany.sca.binding.hazelcast.TestServiceClient"/>
+ <reference name="service" target="TestServiceClient"/>
+ </component>
+
+</composite>
diff --git a/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/resources/service.composite b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/resources/service.composite
new file mode 100644
index 0000000000..83f13a35f2
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta3/modules/domain-hazelcast/src/test/resources/service.composite
@@ -0,0 +1,28 @@
+<?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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ targetNamespace="http://itest"
+ name="TestService">
+
+ <component name="TestService">
+ <implementation.java class="org.apache.tuscany.sca.binding.hazelcast.TestServiceImpl"/>
+ </component>
+
+</composite>