diff options
author | dims <dims@13f79535-47bb-0310-9956-ffa450edef68> | 2008-06-17 00:23:01 +0000 |
---|---|---|
committer | dims <dims@13f79535-47bb-0310-9956-ffa450edef68> | 2008-06-17 00:23:01 +0000 |
commit | bdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a (patch) | |
tree | 38a92061c0793434c4be189f1d70c3458b6bc41d /branches/sca-java-1.1/modules/binding-jms/src |
Move Tuscany from Incubator to top level.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'branches/sca-java-1.1/modules/binding-jms/src')
39 files changed, 3736 insertions, 0 deletions
diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/ActivationSpec.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/ActivationSpec.java new file mode 100644 index 0000000000..5cca3fb67c --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/ActivationSpec.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.jms; + +/** + * @version $Rev$ $Date$ + */ +public interface ActivationSpec extends PropertyList { + String getName(); + + void setName(String name); + + CreateResource getCreate(); + + void setCreate(CreateResource create); +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/ConnectionFactory.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/ConnectionFactory.java new file mode 100644 index 0000000000..c5cd9ca3d9 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/ConnectionFactory.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.jms; + +/** + * @version $Rev$ $Date$ + */ +public interface ConnectionFactory extends PropertyList { + String getName(); + + void setName(String name); + + CreateResource getCreate(); + + void setCreate(CreateResource create); +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/ConnectionInfo.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/ConnectionInfo.java new file mode 100644 index 0000000000..b792c1c333 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/ConnectionInfo.java @@ -0,0 +1,39 @@ +/* + * 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.jms; + +/** + * Specifies the metadata for a JMS connection + * + * @version $Rev$ $Date$ + */ +public interface ConnectionInfo { + Destination getDestination(); + + ConnectionFactory getConnectionFactory(); + + ActivationSpec getActivationSpec(); + + void setDestination(Destination destination); + + void setConnectionFactory(ConnectionFactory connectionFactory); + + void setActivationSpec(ActivationSpec activationSpec); +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/CorrelationScheme.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/CorrelationScheme.java new file mode 100644 index 0000000000..5fa8a3c371 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/CorrelationScheme.java @@ -0,0 +1,27 @@ +/* + * 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.jms; + +/** + * @version $Rev$ $Date$ + */ +public enum CorrelationScheme { + RequestMsgIDToCorrelID, RequestCorrelIDToCorrelID, None +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/CreateResource.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/CreateResource.java new file mode 100644 index 0000000000..c943238a77 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/CreateResource.java @@ -0,0 +1,31 @@ +/* + * 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.jms; + +/** + * Indicates whether the destination should be created when the containing composite is deployed. Valid values are + * "always", "never" and "ifnotexist". The default value is "ifnotexist". If "always" is specified and the corresponding + * resource already exists, then this should be considered an error + * + * @version $Rev$ $Date$ + */ +public enum CreateResource { + ALWAYS, NEVER, IFNOTEXIST +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/Definitions.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/Definitions.java new file mode 100644 index 0000000000..f81192d6d9 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/Definitions.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.jms; + +import java.util.List; + +/** + * @version $Rev$ $Date$ + */ +public interface Definitions { + List<JMSBinding> getBindings(); +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/Destination.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/Destination.java new file mode 100644 index 0000000000..00b2546c76 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/Destination.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.jms; + +/** + * Identifies the destination that is to be used to process requests/responses by this binding. + * + * @version $Rev$ $Date$ + */ +public interface Destination extends PropertyList { + /** + * The name of the destination to which the binding is connected. This may be a JNDI name or a plain destination + * name + * + * @return + */ + String getName(); + + void setName(String name); + + DestinationType getType(); + + void setType(DestinationType type); + + CreateResource getCreate(); + + void setCreate(CreateResource create); +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/DestinationType.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/DestinationType.java new file mode 100644 index 0000000000..aa1601db27 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/DestinationType.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.jms; + +/** + * The type of the request destination. Must take one of the values "queue" or "topic". The default value is "queue". + * When "topic" is specified, then all the operations in the interface that corresponds to the binding must be one-way. + * + * @version $Rev$ $Date$ + */ +public enum DestinationType { + QUEUE, TOPIC +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/Headers.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/Headers.java new file mode 100644 index 0000000000..e6375b477b --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/Headers.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.binding.jms; + +/** + * this element allows JMS headers to be set to the given values for all operations. These values apply to requests from + * a reference and responses from a service. + * + * @version $Rev$ $Date$ + */ +public interface Headers extends PropertyList { + String getJMSType(); + + void setJMSType(String jmsType); + + String getJMSCorrelationId(); + + void setJMSCorrelationId(String jmsCorrelationId); + + String getJMSDeliveryMode(); + + void setJMSDeliveryMode(String jmsDeliveryMode); + + String getJMSTimeToLive(); + + void setJMSTimeToLive(String jmsTimeToLive); + + String getJMSPriority(); + + void setJMSPriority(String jmsPriority); + +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/JMSBinding.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/JMSBinding.java new file mode 100644 index 0000000000..291ce4b081 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/JMSBinding.java @@ -0,0 +1,93 @@ +/* + * 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.jms; + +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.Extensible; + +/** + * This is the generic JMS binding type. The type is extensible so that JMS binding implementers can add additional JMS + * provider-specific attributes and elements although such extensions are not guaranteed to be portable across runtimes. + * + * @version $Rev$ $Date$ + */ +public interface JMSBinding extends Binding, Extensible { + /** + * Identifies the correlation scheme used when sending reply or callback messages. Valid values are + * "RequestMsgIDToCorrelID" (the default), "RequestCorrelIDToCorrelID", and "None". + * + * @return + */ + CorrelationScheme getCorrelationScheme(); + + void setCorrelationScheme(CorrelationScheme correlationScheme); + + /** + * the name of the JNDI initial context factory + * + * @return + */ + String getInitialContextFactory(); + + void setInitialContextFactory(String initialContextFactory); + + /** + * The URL for the JNDI provider + * + * @return + */ + String getJndiURL(); + + void setJndiURL(String jndiURL); + + /** + * identifies a binding.jms element that is present in a definition document, whose destination, connectionFactory, + * activationSpec and resourceAdapter children are used to define the values for this binding. In this case the + * corresponding elements must not be present within this binding element + * + * @return + */ + ConnectionInfo getRequestConnection(); + + void setRequestConnection(ConnectionInfo requestConnection); + + /** + * identifies a binding.jms element that is present in a definition document, whose response child element is used + * to define the values for this binding. In this case no response element must be present within this binding + * element + * + * @return + */ + ConnectionInfo getResponseConnection(); + + void setResponseConnection(ConnectionInfo responseConnection); + + /** + * identifies a binding.jms element that is present in a definition document, whose operationProperties children are + * used to define the values for this binding. In this case no operationProperties elements must be present within + * this binding element + * + * @return + */ + OperationProperties getOperationProperties(); + + void setOperationProperties(OperationProperties operationProperties); + +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/JMSBindingFactory.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/JMSBindingFactory.java new file mode 100644 index 0000000000..2394cf5cdc --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/JMSBindingFactory.java @@ -0,0 +1,47 @@ +/* + * 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.jms; + +/** + * The factory to create the JMS binding model objects + * + * @version $Rev$ $Date$ + */ +public interface JMSBindingFactory { + JMSBinding createJMSBinding(); + + ActivationSpec createActivationSpec(); + + ConnectionFactory createConnectionFactory(); + + ConnectionInfo createConnectionInfo(); + + Definitions createDefinitions(); + + Destination createDestination(); + + Headers createHeaders(); + + OperationProperties createOperationProperties(); + + Property createProperty(); + + ResourceAdapter createResourceAdapter(); +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/OperationProperties.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/OperationProperties.java new file mode 100644 index 0000000000..3b183db858 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/OperationProperties.java @@ -0,0 +1,35 @@ +/* + * 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.jms; + +/** + * Specifies various properties that are specific to the processing of a particular operation. + * + * @version $Rev$ $Date$ + */ +public interface OperationProperties extends PropertyList { + Headers getHeaders(); + + void setHeaders(Headers headers); + + String getNativeOperation(); + + void setNativeOperation(String nativeOperation); +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/Property.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/Property.java new file mode 100644 index 0000000000..efe45d4683 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/Property.java @@ -0,0 +1,35 @@ +/* + * 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.jms; + +/** + * Specifies the value to use for the specified JMS user property + * + * @version $Rev$ $Date$ + */ +public interface Property { + String getName(); + + void setName(String name); + + String getValue(); + + void setValue(String type); +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/PropertyList.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/PropertyList.java new file mode 100644 index 0000000000..323df239d4 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/PropertyList.java @@ -0,0 +1,31 @@ +/* + * 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.jms; + +import java.util.List; + +/** + * A list of properties + * + * @version $Rev$ $Date$ + */ +public interface PropertyList { + List<Property> getProperties(); +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/ResourceAdapter.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/ResourceAdapter.java new file mode 100644 index 0000000000..85e11a5f95 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/ResourceAdapter.java @@ -0,0 +1,35 @@ +/* + * 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.jms; + +/** + * Specifies name, type and properties of the Resource Adapter Java bean. This is required when the JMS resources are to + * be created for a JCA 1.5-compliant JMS provider, and is ignored otherwise. There may be a restriction, depending on + * the deployment platform, about specifying properties of the RA Java Bean. For non-JCA 1.5-compliant JMS providers, + * information necessary for resource creation must be done in provider-specific elements or attributes allowed by the + * extensibility of the binding.jms element. + * + * @version $Rev$ $Date$ + */ +public interface ResourceAdapter extends PropertyList { + String getName(); + + void setName(String name); +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/impl/JMSBinding.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/impl/JMSBinding.java new file mode 100644 index 0000000000..3019ad676f --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/impl/JMSBinding.java @@ -0,0 +1,540 @@ +/* + * 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.jms.impl; + +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.List; + +import javax.jms.DeliveryMode; + +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.binding.jms.provider.JMSMessageProcessor; + +/** + * Models a binding to a JMS resource. + */ + +public class JMSBinding implements Binding { + + /** + * Clone the binding + */ + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + // properties required to implement the Tuscany + // binding extension SPI + private String uri = null; + private String name = null; + private boolean unresolved = false; + private List<Object> extensions = new ArrayList<Object>(); + + // Properties required to describe the JMS + // binding model + + // <binding.jms correlationScheme="string"? Not yet implemented in binding + // initialContextFactory="xs:anyURI"? + // jndiURL="xs:anyURI"? + // requestConnection="QName"? Not yet implemented in binding + // responseConnection="QName"? Not yet implemented in binding + // operationProperties="QName"? Not yet implemented in binding + // ...> + private String correlationScheme = JMSBindingConstants.CORRELATE_MSG_ID; + private String initialContextFactoryName = JMSBindingConstants.DEFAULT_CONTEXT_FACTORY_NAME; + private String jndiURL = JMSBindingConstants.DEFAULT_JNDI_URL; + // private String requestConnection = null; + // private String responseConnection = null; + // private String operationProperties = null; + // + // <destination name="xs:anyURI" + // type="string"? Not yet implemented in binding + // create="string"?> Not yet implemented in binding + // <property name="NMTOKEN" Not yet implemented in binding + // type="NMTOKEN">* Not yet implemented in binding + // </destination>? + private String destinationName = JMSBindingConstants.DEFAULT_DESTINATION_NAME; + private String destinationType = JMSBindingConstants.DESTINATION_TYPE_QUEUE; + private String destinationCreate = JMSBindingConstants.CREATE_IF_NOT_EXIST; + // + // <connectionFactory name="xs:anyURI" Not yet implemented in binding + // create="string"?> Not yet implemented in binding + // <property name="NMTOKEN" Not yet implemented in binding + // type="NMTOKEN">* Not yet implemented in binding + // </connectionFactory>? + private String connectionFactoryName = JMSBindingConstants.DEFAULT_CONNECTION_FACTORY_NAME; + private String connectionFactoryCreate = JMSBindingConstants.CREATE_IF_NOT_EXIST; + // + // <activationSpec name="xs:anyURI" Not yet implemented in binding + // create="string"?> Not yet implemented in binding + // <property name="NMTOKEN" Not yet implemented in binding + // type="NMTOKEN">* Not yet implemented in binding + // </activationSpec>? + private String activationSpecName = null; + private String activationSpecCreate = null; + // + // <response> + // <destination name="xs:anyURI" + // type="string"? Not yet implemented in binding + // create="string"?> Not yet implemented in binding + // <property name="NMTOKEN" Not yet implemented in binding + // type="NMTOKEN">* Not yet implemented in binding + // </destination>? + private String responseDestinationName = JMSBindingConstants.DEFAULT_RESPONSE_DESTINATION_NAME; + private String responseDestinationType = JMSBindingConstants.DESTINATION_TYPE_QUEUE; + private String responseDestinationCreate = JMSBindingConstants.CREATE_IF_NOT_EXIST; + // + // <connectionFactory name="xs:anyURI" Not yet implemented in binding + // create="string"?> Not yet implemented in binding + // <property name="NMTOKEN" Not yet implemented in binding + // type="NMTOKEN">* Not yet implemented in binding + // </connectionFactory>? + private String responseConnectionFactoryName = JMSBindingConstants.DEFAULT_CONNECTION_FACTORY_NAME; + private String responseConnectionFactoryCreate = JMSBindingConstants.CREATE_IF_NOT_EXIST; + // + // <activationSpec name="xs:anyURI" Not yet implemented in binding + // create="string"?> Not yet implemented in binding + // <property name="NMTOKEN" Not yet implemented in binding + // type="NMTOKEN">* Not yet implemented in binding + // </activationSpec>? + private String responseActivationSpecName = null; + private String responseActivationSpecCreate = null; + // </response>? + // + // <resourceAdapter name="NMTOKEN">? Not yet implemented in binding + // <property name="NMTOKEN" Not yet implemented in binding + // type="NMTOKEN">* Not yet implemented in binding + // </resourceAdapter>? + // private String resourceAdapterName = null; + // + // <headers JMSType="string"? Not yet implemented in binding + // JMSCorrelationId="string"? Not yet implemented in binding + // JMSDeliveryMode="string"? Not yet implemented in binding + // JMSTimeToLive="int"? Not yet implemented in binding + // JMSPriority="string"?> Not yet implemented in binding + // <property name="NMTOKEN" Not yet implemented in binding + // type="NMTOKEN">* Not yet implemented in binding + // </headers>? + // private String jmsType = null; + // private String jmsCorrelationId = null; + private int jmsDeliveryMode = DeliveryMode.NON_PERSISTENT; // Maps to javax.jms.DeliveryMode + private int jmsTimeToLive = JMSBindingConstants.DEFAULT_TIME_TO_LIVE; + private int jmsPriority = JMSBindingConstants.DEFAULT_PRIORITY; + // + // <operationProperties name="string" Not yet implemented in binding + // nativeOperation="string"?> Not yet implemented in binding + // <property name="NMTOKEN" Not yet implemented in binding + // type="NMTOKEN">* Not yet implemented in binding + // <headers JMSType="string"? Not yet implemented in binding + // JMSCorrelationId="string"? Not yet implemented in binding + // JMSDeliveryMode="string"? Not yet implemented in binding + // JMSTimeToLive="int"? Not yet implemented in binding + // JMSPriority="string"?> Not yet implemented in binding + // <property name="NMTOKEN" Not yet implemented in binding + // type="NMTOKEN">* Not yet implemented in binding + // </headers>? + // </operationProperties>* + // </binding.jms> + + // Other properties not directly related to the + // XML definition of the JMS binding + + // Provides the name of the factory that interfaces to the + // JMS API for us. + private String jmsResourceFactoryName = JMSBindingConstants.DEFAULT_RF_CLASSNAME; + + // Message processors used to deal with the request + // and response messages + public String requestMessageProcessorName = JMSBindingConstants.DEFAULT_MP_CLASSNAME; + public String responseMessageProcessorName = JMSBindingConstants.DEFAULT_MP_CLASSNAME; + + // The JMS message property used to hold the name of the + // operation being called + private String operationSelectorPropertyName = JMSBindingConstants.DEFAULT_OPERATION_PROP_NAME; + + // If the operation selector is derived automatically from the service + // interface it's stored here + private String operationSelectorName = null; + + // Set true if messages are sent/received in XML format + private boolean xmlFormat = true; + + // TODO ..... + private String replyTo; + + // Methods required by the Tuscany SPI + + /** + * No arg constructor used by the JSMBindingFactoryImpl to create JMS binding model objects + */ + public JMSBinding() { + super(); + } + + /** + * Returns the binding URI. + * + * @return the binding uri + */ + public String getURI() { + return this.uri; + } + + /** + * Sets the binding URI. + * + * @param uri the binding uri + */ + public void setURI(String uri) { + this.uri = uri; + } + + /** + * Returns the binding name. + * + * @return the binding name + */ + public String getName() { + return this.name; + } + + /** + * Sets the binding name. + * + * @param name the binding name + */ + public void setName(String name) { + this.name = name; + } + + public boolean isUnresolved() { + return this.unresolved; + } + + public void setUnresolved(boolean unresolved) { + this.unresolved = unresolved; + } + + public List<Object> getExtensions() { + return extensions; + } + + // Methods for getting/setting JMS binding model information + // as derived from the XML of the binding.jms element + + public void setCorrelationScheme(String correlationScheme) { + this.correlationScheme = correlationScheme; + } + + public String getCorrelationScheme() { + return correlationScheme; + } + + public String getInitialContextFactoryName() { + return initialContextFactoryName; + } + + public void setInitialContextFactoryName(String initialContextFactoryName) { + this.initialContextFactoryName = initialContextFactoryName; + } + + public String getJndiURL() { + return this.jndiURL; + } + + public void setJndiURL(String jndiURL) { + this.jndiURL = jndiURL; + } + + public String getDestinationName() { + return destinationName; + } + + public void setDestinationName(String destinationName) { + this.destinationName = destinationName; + } + + public String getDestinationType() { + return destinationType; + } + + public void setDestinationType(String destinationType) { + this.destinationType = destinationType; + } + + public String getDestinationCreate() { + return this.destinationCreate; + } + + public void setDestinationCreate(String create) { + this.destinationCreate = create; + } + + public String getConnectionFactoryName() { + return connectionFactoryName; + } + + public void setConnectionFactoryName(String connectionFactoryName) { + this.connectionFactoryName = connectionFactoryName; + } + + public String getConnectionFactoryCreate() { + return this.connectionFactoryCreate; + } + + public void setConnectionFactoryCreate(String create) { + this.connectionFactoryCreate = create; + } + + public String getActivationSpecName() { + return activationSpecName; + } + + public void setActivationSpecName(String activationSpecName) { + this.activationSpecName = activationSpecName; + } + + public String getActivationSpecCreate() { + return this.activationSpecCreate; + } + + public void setActivationSpecCreate(String create) { + this.activationSpecCreate = create; + } + + public String getResponseDestinationName() { + return this.responseDestinationName; + } + + public void setResponseDestinationName(String name) { + this.responseDestinationName = name; + } + + public String getResponseDestinationType() { + return this.responseDestinationType; + } + + public void setResponseDestinationType(String type) { + this.responseDestinationType = type; + } + + public String getResponseDestinationCreate() { + return this.responseDestinationCreate; + } + + public void setResponseDestinationCreate(String create) { + this.responseDestinationCreate = create; + } + + public String getResponseConnectionFactoryName() { + return responseConnectionFactoryName; + } + + public void setResponseConnectionFactoryName(String connectionFactoryName) { + this.responseConnectionFactoryName = connectionFactoryName; + } + + public String getResponseConnectionFactoryCreate() { + return this.responseConnectionFactoryCreate; + } + + public void setResponseConnectionFactoryCreate(String create) { + this.responseConnectionFactoryCreate = create; + } + + public String getResponseActivationSpecName() { + return responseActivationSpecName; + } + + public void setResponseActivationSpecName(String activationSpecName) { + this.responseActivationSpecName = activationSpecName; + } + + public String getResponseActivationSpecCreate() { + return this.responseActivationSpecCreate; + } + + public void setResponseActivationSpecCreate(String create) { + this.responseActivationSpecCreate = create; + } + + public int getDeliveryMode() { + return jmsDeliveryMode; + } + + public void setDeliveryMode(int deliveryMode) { + this.jmsDeliveryMode = deliveryMode; + } + + public int getTimeToLive() { + return jmsTimeToLive; + } + + public void setTimeToLive(int timeToLive) { + this.jmsTimeToLive = timeToLive; + } + + public int getPriority() { + return jmsPriority; + } + + public void setPriority(int priority) { + this.jmsPriority = priority; + } + + // operations to manage the other information required by the + // JMS binding + + public String getJmsResourceFactoryName() { + return jmsResourceFactoryName; + } + + public void setJmsResourceFactoryName(String jmsResourceFactoryName) { + this.jmsResourceFactoryName = jmsResourceFactoryName; + } + +// public JMSResourceFactory getJmsResourceFactory() { +// return (JMSResourceFactory)instantiate(null, jmsResourceFactoryName); +// } + + public void setRequestMessageProcessorName(String name) { + this.requestMessageProcessorName = name; + } + + public String getRequestMessageProcessorName() { + return requestMessageProcessorName; + } + + public JMSMessageProcessor getRequestMessageProcessor() { + return (JMSMessageProcessor)instantiate(null, requestMessageProcessorName); + } + + public void setResponseMessageProcessorName(String name) { + this.responseMessageProcessorName = name; + } + + public String getResponseMessageProcessorName() { + return responseMessageProcessorName; + } + + public JMSMessageProcessor getResponseMessageProcessor() { + return (JMSMessageProcessor)instantiate(null, responseMessageProcessorName); + } + + public String getOperationSelectorPropertyName() { + return operationSelectorPropertyName; + } + + public void setOperationSelectorPropertyName(String operationSelectorPropertyName) { + this.operationSelectorPropertyName = operationSelectorPropertyName; + } + + public String getOperationSelectorName() { + return operationSelectorName; + } + + public void setOperationSelectorName(String operationSelectorName) { + this.operationSelectorName = operationSelectorName; + } + + public boolean getXMLFormat() { + return xmlFormat; + } + + public void setXMLFormat(boolean b) { + this.xmlFormat = b; + } + + /** + * Used to create instances of the JMSResourceFactory and RequestMessageProcessor and ResponseMessageProcessor from + * sting based classname provided in the configuration + * + * @param cl classloader + * @param className the string based classname to load and instantiate + * @return the new object + */ + private Object instantiate(ClassLoader cl, String className) { + Object instance; + if (cl == null) { + cl = this.getClass().getClassLoader(); + } + + try { + Class clazz; + + try { + clazz = cl.loadClass(className); + } catch (ClassNotFoundException e) { + clazz = this.getClass().getClassLoader().loadClass(className); + } + + Constructor constructor = clazz.getDeclaredConstructor(new Class[] {JMSBinding.class}); + instance = constructor.newInstance(this); + + } catch (Throwable e) { + throw new JMSBindingException("Exception instantiating OperationAndDataBinding class", e); + } + + return instance; + } + + /** + * The validation rules for the JMS model are relatively complicated to they all live together here + */ + public void validate() throws JMSBindingException { + /* + * first fix up anything now the model has been read + */ + + if (getDestinationName().equals(JMSBindingConstants.DEFAULT_DESTINATION_NAME)) { + /* + * No desitnation name has been set so make sure that the runtime is able to create one automatically + */ + setDestinationCreate(JMSBindingConstants.CREATE_IF_NOT_EXIST); + } + + if (getResponseDestinationName().equals(JMSBindingConstants.DEFAULT_RESPONSE_DESTINATION_NAME)) { + /* + * No repsonse desitination name has been set so make sure that the runtime is able to create one + * automatically + */ + setResponseDestinationCreate(JMSBindingConstants.CREATE_IF_NOT_EXIST); + } + + /* + * Now some cross field validation + */ + + // connection factory doesn't contradict detsination type + // connection factory and activation spec are mutually exclusive + // TODO check spec for all validations + } + + // TODO... + + public String getReplyTo() { + return replyTo; + } + + public void setReplyTo(String replyTo) { + this.replyTo = replyTo; + } + +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/impl/JMSBindingConstants.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/impl/JMSBindingConstants.java new file mode 100644 index 0000000000..0f4e309bf2 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/impl/JMSBindingConstants.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.jms.impl; + +import java.util.Arrays; +import java.util.List; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.assembly.xml.Constants; +import org.apache.tuscany.sca.binding.jms.provider.JMSMessageProcessorImpl; + +public interface JMSBindingConstants { + + // Contants used when describing the JMS binding + // model and for setting up defaults + public final static String BINDING_JMS = "binding.jms"; + public final static QName BINDING_JMS_QNAME = new QName(Constants.SCA10_NS, BINDING_JMS); + public final static String CORRELATE_MSG_ID = "requestmsgidtocorrelid"; + public final static String CORRELATE_CORRELATION_ID = "requestcorrelidtocorrelid"; + public final static String CORRELATE_NONE = "none"; + public final static List<String> VALID_CORRELATION_SCHEMES = + Arrays.asList(new String[] {CORRELATE_MSG_ID, CORRELATE_CORRELATION_ID, CORRELATE_NONE}); + public final static String DESTINATION_TYPE_QUEUE = "queue"; // 0 + public final static String DESTINATION_TYPE_TOPIC = "topic"; // 1 + public final static List<String> VALID_DESTINATION_TYPES = + Arrays.asList(new String[] {DESTINATION_TYPE_QUEUE, DESTINATION_TYPE_TOPIC}); + public final static String CREATE_ALWAYS = "always"; + public final static String CREATE_NEVER = "never"; + public final static String CREATE_IF_NOT_EXIST = "ifnotexist"; + public final static String DEFAULT_DESTINATION_NAME = "NODESTINATION"; + public final static String DEFAULT_RESPONSE_DESTINATION_NAME = "NORESPONSEDESTINATION"; + public final static String DEFAULT_CONNECTION_FACTORY_NAME = "ConnectionFactory"; + public final static String DEFAULT_CONTEXT_FACTORY_NAME = "org.apache.activemq.jndi.ActiveMQInitialContextFactory"; + public final static String DEFAULT_JNDI_URL = "tcp://localhost:61616"; + public final static int DEFAULT_TIME_TO_LIVE = 10000; // in milli seconds + public final static int DEFAULT_PRIORITY = 1; + public final static String DEFAULT_RF_CLASSNAME = "org.apache.tuscany.sca.host.jms.activemq.JMSResourceFactoryImpl"; + public final static String DEFAULT_MP_CLASSNAME = JMSMessageProcessorImpl.class.getName(); + public final static String DEFAULT_OPERATION_PROP_NAME = "scaOperationName"; + +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/impl/JMSBindingException.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/impl/JMSBindingException.java new file mode 100644 index 0000000000..60cd33d9bb --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/impl/JMSBindingException.java @@ -0,0 +1,40 @@ +/* + * 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.jms.impl; + +public class JMSBindingException extends RuntimeException { + private static final long serialVersionUID = 1L; + + public JMSBindingException() { + super(); + } + + public JMSBindingException(String arg0, Throwable arg1) { + super(arg0, arg1); + } + + public JMSBindingException(String arg0) { + super(arg0); + } + + public JMSBindingException(Throwable arg0) { + super(arg0); + } + +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/impl/JMSBindingProcessor.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/impl/JMSBindingProcessor.java new file mode 100644 index 0000000000..c8fecd1d23 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/impl/JMSBindingProcessor.java @@ -0,0 +1,348 @@ +/* + * 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.jms.impl; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.xml.Constants; +import org.apache.tuscany.sca.assembly.xml.PolicyAttachPointProcessor; +import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.service.ContributionReadException; +import org.apache.tuscany.sca.contribution.service.ContributionResolveException; +import org.apache.tuscany.sca.contribution.service.ContributionWriteException; +import org.apache.tuscany.sca.policy.PolicyFactory; + +/** + * A processor to read the XML that describes the JMS binding... + * + * <binding.jms correlationScheme="string"? + * initialContextFactory="xs:anyURI"? + * jndiURL="xs:anyURI"? + * requestConnection="QName"? + * responseConnection="QName"? + * operationProperties="QName"? + * ...> + * + * <destination name="xs:anyURI" type="string"? create="string"?> + * <property name="NMTOKEN" type="NMTOKEN">* + * </destination>? + * + * <connectionFactory name="xs:anyURI" create="string"?> + * <property name="NMTOKEN" type="NMTOKEN">* + * </connectionFactory>? + * + * <activationSpec name="xs:anyURI" create="string"?> + * <property name="NMTOKEN" type="NMTOKEN">* + * </activationSpec>? + * + * <response> + * <destination name="xs:anyURI" type="string"? create="string"?> + * <property name="NMTOKEN" type="NMTOKEN">* + * </destination>? + * + * <connectionFactory name="xs:anyURI" create="string"?> + * <property name="NMTOKEN" type="NMTOKEN">* + * </connectionFactory>? + * + * <activationSpec name="xs:anyURI" create="string"?> + * <property name="NMTOKEN" type="NMTOKEN">* + * </activationSpec>? + * </response>? + * + * <resourceAdapter name="NMTOKEN">? + * <property name="NMTOKEN" type="NMTOKEN">* + * </resourceAdapter>? + * + * <headers JMSType="string"? + * JMSCorrelationId="string"? + * JMSDeliveryMode="string"? + * JMSTimeToLive="int"? + * JMSPriority="string"?> + * <property name="NMTOKEN" type="NMTOKEN">* + * </headers>? + * + * <operationProperties name="string" nativeOperation="string"?> + * <property name="NMTOKEN" type="NMTOKEN">* + * <headers JMSType="string"? + * JMSCorrelationId="string"? + * JMSDeliveryMode="string"? + * JMSTimeToLive="int"? + * JMSPriority="string"?> + * <property name="NMTOKEN" type="NMTOKEN">* + * </headers>? + * </operationProperties>* + * </binding.jms> + */ + +public class JMSBindingProcessor implements StAXArtifactProcessor<JMSBinding> { + + private PolicyFactory policyFactory; + private PolicyAttachPointProcessor policyProcessor; + + public JMSBindingProcessor(ModelFactoryExtensionPoint modelFactories) { + this.policyFactory = modelFactories.getFactory(PolicyFactory.class); + this.policyProcessor = new PolicyAttachPointProcessor(policyFactory); + } + + public QName getArtifactType() { + return JMSBindingConstants.BINDING_JMS_QNAME; + } + + public Class<JMSBinding> getModelType() { + return JMSBinding.class; + } + + public JMSBinding read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException { + JMSBinding jmsBinding = new JMSBinding(); + + // Read policies + policyProcessor.readPolicies(jmsBinding, reader); + + // Read binding name + String name = reader.getAttributeValue(null, "name"); + if (name != null) { + jmsBinding.setName(name); + } + + // Read binding URI + String uri = reader.getAttributeValue(null, "uri"); + if (uri != null) { + jmsBinding.setURI(uri); + System.err.println("JMS Binding doesn't process uri yet"); + } + + // Read correlation scheme + String correlationScheme = reader.getAttributeValue(null, "correlationScheme"); + if (correlationScheme != null && correlationScheme.length() > 0) { + if (JMSBindingConstants.VALID_CORRELATION_SCHEMES.contains(correlationScheme.toLowerCase())) { + jmsBinding.setCorrelationScheme(correlationScheme); + } else { + throw new JMSBindingException("invalid correlationScheme: " + correlationScheme); + } + System.err.println("JMS Binding doesn't process correlationScheme yet"); + } + + // Read initial context factory + String initialContextFactory = reader.getAttributeValue(null, "initialContextFactory"); + if (initialContextFactory != null && initialContextFactory.length() > 0) { + jmsBinding.setInitialContextFactoryName(initialContextFactory); + } + + // Read jndi URL + String jndiURL = reader.getAttributeValue(null, "jndiURL"); + if (jndiURL != null && jndiURL.length() > 0) { + jmsBinding.setJndiURL(jndiURL); + } + + // Read requestConnection + // TODO + // Read reponseConnection + // TODO + // Read operationProperties + // TODO + + // Read subelements of binding.jms + boolean endFound = false; + while (!endFound) { + switch (reader.next()) { + case START_ELEMENT: + String elementName = reader.getName().getLocalPart(); + if ("destination".equals(elementName)) { + parseDestination(reader, jmsBinding); + } else if ("connectionFactory".equals(elementName)) { + parseConnectionFactory(reader, jmsBinding); + } else if ("activationSpec".equals(elementName)) { + parseActivationSpec(reader, jmsBinding); + } else if ("response".equals(elementName)) { + parseResponse(reader, jmsBinding); + } else if ("resourceAdapter".equals(elementName)) { + parseResourceAdapter(reader, jmsBinding); + } else if ("headers".equals(elementName)) { + parseHeaders(reader, jmsBinding); + } else if ("operationProperties".equals(elementName)) { + parseOperationProperties(reader, jmsBinding); + } + reader.next(); + break; + case END_ELEMENT: + QName x = reader.getName(); + if (x.equals(JMSBindingConstants.BINDING_JMS_QNAME)) { + endFound = true; + } else { + throw new RuntimeException("Incomplete binding.jms definition found unexpected element " + x + .toString()); + } + } + } + + jmsBinding.validate(); + + return jmsBinding; + } + + public void resolve(JMSBinding model, ModelResolver resolver) throws ContributionResolveException { + } + + public void write(JMSBinding rmiBinding, XMLStreamWriter writer) throws ContributionWriteException, + XMLStreamException { + // Write a <binding.jms> + writer.writeStartElement(Constants.SCA10_NS, JMSBindingConstants.BINDING_JMS); + + // FIXME Implement + + writer.writeEndElement(); + } + + private void parseDestination(XMLStreamReader reader, JMSBinding jmsBinding) throws XMLStreamException { + String name = reader.getAttributeValue(null, "name"); + if (name != null && name.length() > 0) { + jmsBinding.setDestinationName(name); + } + + String type = reader.getAttributeValue(null, "type"); + if (type != null && type.length() > 0) { + if (JMSBindingConstants.DESTINATION_TYPE_QUEUE.equalsIgnoreCase(type)) { + jmsBinding.setDestinationType(JMSBindingConstants.DESTINATION_TYPE_QUEUE); + } else if (JMSBindingConstants.DESTINATION_TYPE_TOPIC.equalsIgnoreCase(type)) { + jmsBinding.setDestinationType(JMSBindingConstants.DESTINATION_TYPE_TOPIC); + } else { + throw new RuntimeException("invalid destination type: " + type); + } + System.err.println("JMS Binding doesn't process destination type yet"); + } + + String create = reader.getAttributeValue(null, "create"); + if (create != null && create.length() > 0) { + jmsBinding.setDestinationCreate(create); + } + } + + private void parseConnectionFactory(XMLStreamReader reader, JMSBinding jmsBinding) { + String name = reader.getAttributeValue(null, "name"); + if (name != null && name.length() > 0) { + jmsBinding.setConnectionFactoryName(name); + } else { + throw new RuntimeException("missing connectionFactory name"); + } + } + + private void parseActivationSpec(XMLStreamReader reader, JMSBinding jmsBinding) { + String name = reader.getAttributeValue(null, "name"); + if (name != null && name.length() > 0) { + jmsBinding.setActivationSpecName(name); + System.err.println("JMS Binding doesn't process activationSpec yet"); + } else { + throw new RuntimeException("missing ActivationSpec name"); + } + } + + private void parseResponseDestination(XMLStreamReader reader, JMSBinding jmsBinding) throws XMLStreamException { + String name = reader.getAttributeValue(null, "name"); + if (name != null && name.length() > 0) { + jmsBinding.setResponseDestinationName(name); + } + + String type = reader.getAttributeValue(null, "type"); + if (type != null && type.length() > 0) { + if (JMSBindingConstants.DESTINATION_TYPE_QUEUE.equalsIgnoreCase(type)) { + jmsBinding.setResponseDestinationType(JMSBindingConstants.DESTINATION_TYPE_QUEUE); + } else if (JMSBindingConstants.DESTINATION_TYPE_TOPIC.equalsIgnoreCase(type)) { + jmsBinding.setResponseDestinationType(JMSBindingConstants.DESTINATION_TYPE_TOPIC); + } else { + throw new RuntimeException("invalid response destination type: " + type); + } + System.err.println("JMS Binding doesn't process response destination type yet"); + } + + String create = reader.getAttributeValue(null, "create"); + if (create != null && create.length() > 0) { + jmsBinding.setResponseDestinationCreate(create); + } + } + + private void parseResponseConnectionFactory(XMLStreamReader reader, JMSBinding jmsBinding) { + String name = reader.getAttributeValue(null, "name"); + if (name != null && name.length() > 0) { + jmsBinding.setResponseConnectionFactoryName(name); + System.err.println("JMS Binding doesn't process response connectionFactory yet"); + } else { + throw new RuntimeException("missing response connectionFactory name"); + } + } + + private void parseResponseActivationSpec(XMLStreamReader reader, JMSBinding jmsBinding) { + String name = reader.getAttributeValue(null, "name"); + if (name != null && name.length() > 0) { + jmsBinding.setResponseActivationSpecName(name); + System.err.println("JMS Binding doesn't process response activationSpec yet"); + } else { + throw new RuntimeException("missing response ActivationSpec name"); + } + } + + private void parseResponse(XMLStreamReader reader, JMSBinding jmsBinding) throws XMLStreamException { + // Read subelements of response + while (true) { + switch (reader.next()) { + case START_ELEMENT: + String elementName = reader.getName().getLocalPart(); + if ("destination".equals(elementName)) { + parseResponseDestination(reader, jmsBinding); + } else if ("connectionFactory".equals(elementName)) { + parseResponseConnectionFactory(reader, jmsBinding); + } else if ("activationSpec".equals(elementName)) { + parseResponseActivationSpec(reader, jmsBinding); + } + reader.next(); + break; + case END_ELEMENT: + QName x = reader.getName(); + if (x.getLocalPart().equals("response")) { + return; + } else { + throw new RuntimeException( + "Incomplete binding.jms/response definition found unexpected element " + x + .toString()); + } + } + } + } + + private void parseResourceAdapter(XMLStreamReader reader, JMSBinding jmsBinding) throws XMLStreamException { + System.err.println("JMS Binding doesn't process resourceAdapter yet"); + } + + private void parseHeaders(XMLStreamReader reader, JMSBinding jmsBinding) throws XMLStreamException { + System.err.println("JMS Binding doesn't process headers yet"); + } + + private void parseOperationProperties(XMLStreamReader reader, JMSBinding jmsBinding) throws XMLStreamException { + System.err.println("JMS Binding doesn't process operationProperties yet"); + } + +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingInvoker.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingInvoker.java new file mode 100644 index 0000000000..444c659eeb --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingInvoker.java @@ -0,0 +1,258 @@ +/* + * 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.jms.provider; + +import java.lang.reflect.InvocationTargetException; + +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.naming.NamingException; + +import org.apache.tuscany.sca.binding.jms.impl.JMSBinding; +import org.apache.tuscany.sca.binding.jms.impl.JMSBindingConstants; +import org.apache.tuscany.sca.binding.jms.impl.JMSBindingException; +import org.apache.tuscany.sca.host.jms.JMSResourceFactory; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.invocation.Invoker; + +/** + * Interceptor for the JMS binding. + * + * @version $Rev$ $Date$ + */ +public class JMSBindingInvoker implements Invoker { + + protected Operation operation; + protected String operationName; + + protected JMSBinding jmsBinding; + protected JMSResourceFactory jmsResourceFactory; + protected JMSMessageProcessor requestMessageProcessor; + protected JMSMessageProcessor responseMessageProcessor; + protected Destination requestDest; + protected Destination replyDest; + + public JMSBindingInvoker(JMSBinding jmsBinding, Operation operation, JMSResourceFactory jmsResourceFactory) { + + this.operation = operation; + operationName = operation.getName(); + + this.jmsBinding = jmsBinding; + this.jmsResourceFactory = jmsResourceFactory; + requestMessageProcessor = jmsBinding.getRequestMessageProcessor(); + responseMessageProcessor = jmsBinding.getResponseMessageProcessor(); + try { + requestDest = lookupDestination(); + replyDest = lookupResponseDestination(); + } catch (NamingException e) { + throw new JMSBindingException(e); + } + + } + + /** + * Looks up the Destination Queue for the JMS Binding + * + * @return The Destination Queue + * @throws NamingException Failed to lookup Destination Queue + * @throws JMSBindingException Failed to lookup Destination Queue + * @see #lookupDestinationQueue(boolean) + */ + private Destination lookupDestination() throws NamingException, JMSBindingException { + return lookupDestinationQueue(false); + } + + /** + * Looks up the Destination Response Queue for the JMS Binding + * + * @return The Destination Response Queue + * @throws NamingException Failed to lookup Destination Response Queue + * @throws JMSBindingException Failed to lookup Destination Response Queue + * @see #lookupDestinationQueue(boolean) + */ + private Destination lookupResponseDestination() throws NamingException, JMSBindingException { + return lookupDestinationQueue(true); + } + + /** + * Looks up the Destination Queue for the JMS Binding. + * <p> + * What happens in the look up will depend on the create mode specified for the JMS Binding: + * <ul> + * <li>always - the JMS queue is always created. It is an error if the queue already exists + * <li>ifnotexist - the JMS queue is created if it does not exist. It is not an error if the queue already exists + * <li>never - the JMS queue is never created. It is an error if the queue does not exist + * </ul> + * See the SCA JMS Binding specification for more information. + * <p> + * + * @param isReponseQueue <code>true</code> if we are creating a response queue. <code>false</code> if we are + * creating a request queue + * @return The Destination queue. + * @throws NamingException Failed to lookup JMS queue + * @throws JMSBindingException Failed to lookup JMS Queue. Probable cause is that the JMS queue's current + * existance/non-existance is not compatible with the create mode specified on the binding + */ + private Destination lookupDestinationQueue(boolean isReponseQueue) throws NamingException, JMSBindingException { + String queueName; + String queueType; + String qCreateMode; + if (isReponseQueue) { + queueName = jmsBinding.getResponseDestinationName(); + queueType = "JMS Response Destination "; + qCreateMode = jmsBinding.getResponseDestinationCreate(); + } else { + queueName = jmsBinding.getDestinationName(); + queueType = "JMS Destination "; + qCreateMode = jmsBinding.getDestinationCreate(); + } + + Destination dest = jmsResourceFactory.lookupDestination(queueName); + + if (qCreateMode.equals(JMSBindingConstants.CREATE_ALWAYS)) { + // In this mode, the queue must not already exist as we are creating it + if (dest != null) { + throw new JMSBindingException(queueType + queueName + + " already exists but has create mode of \"" + + qCreateMode + + "\" while registering binding " + + jmsBinding.getName() + + " invoker"); + } + // Create the queue + dest = jmsResourceFactory.createDestination(queueName); + + } else if (qCreateMode.equals(JMSBindingConstants.CREATE_IF_NOT_EXIST)) { + // In this mode, the queue may nor may not exist. It will be created if it does not exist + if (dest == null) { + dest = jmsResourceFactory.createDestination(queueName); + } + + } else if (qCreateMode.equals(JMSBindingConstants.CREATE_NEVER)) { + // In this mode, the queue must have already been created. + if (dest == null) { + throw new JMSBindingException(queueType + queueName + + " not found but create mode of \"" + + qCreateMode + + "\" while registering binding " + + jmsBinding.getName() + + " invoker"); + } + } + + // Make sure we ended up with a queue + if (dest == null) { + throw new JMSBindingException(queueType + queueName + + " not found with create mode of \"" + + qCreateMode + + "\" while registering binding " + + jmsBinding.getName() + + " invoker"); + } + + return dest; + } + + public org.apache.tuscany.sca.invocation.Message invoke(org.apache.tuscany.sca.invocation.Message msg) { + try { + Object resp = invokeTarget((Object[])msg.getBody(), (short)0); + msg.setBody(resp); + } catch (InvocationTargetException e) { + msg.setFaultBody(e.getCause()); + } catch (Throwable e) { + msg.setFaultBody(e); + } + return msg; + } + + public Object invokeTarget(Object payload, final short sequence) throws InvocationTargetException { + try { + Session session = jmsResourceFactory.createSession(); + try { + + Destination replyToDest; + if (operation.isNonBlocking()) { + replyToDest = null; + } else { + replyToDest = (replyDest != null) ? replyDest : session.createTemporaryQueue(); + } + + Message requestMsg = sendRequest((Object[])payload, session, replyToDest); + if (replyToDest == null) { + return null; + } else { + Message replyMsg = receiveReply(session, replyToDest, requestMsg.getJMSMessageID()); + return ((Object[])responseMessageProcessor.extractPayloadFromJMSMessage(replyMsg))[0]; + } + + } finally { + session.close(); + } + } catch (JMSException e) { + throw new InvocationTargetException(e); + } catch (NamingException e) { + throw new InvocationTargetException(e); + } + } + + public void stop() throws NamingException, JMSException { + jmsResourceFactory.closeConnection(); + } + + protected Message sendRequest(Object payload, Session session, Destination replyToDest) throws JMSException { + + Message requestMsg = requestMessageProcessor.insertPayloadIntoJMSMessage(session, payload); + + requestMsg.setJMSDeliveryMode(jmsBinding.getDeliveryMode()); + requestMsg.setJMSPriority(jmsBinding.getPriority()); + + requestMessageProcessor.setOperationName(operationName, requestMsg); + requestMsg.setJMSReplyTo(replyToDest); + + MessageProducer producer = session.createProducer(requestDest); + try { + producer.send(requestMsg); + } finally { + producer.close(); + } + return requestMsg; + } + + protected Message receiveReply(Session session, Destination replyToDest, String requestMsgId) throws JMSException, + NamingException { + String msgSelector = "JMSCorrelationID = '" + requestMsgId + "'"; + MessageConsumer consumer = session.createConsumer(replyToDest, msgSelector); + Message replyMsg; + try { + jmsResourceFactory.startConnection(); + replyMsg = consumer.receive(jmsBinding.getTimeToLive()); + } finally { + consumer.close(); + } + if (replyMsg == null) { + throw new JMSBindingException("No reply message received on " + replyToDest + " for message id " + requestMsgId); + } + return replyMsg; + } + +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingListener.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingListener.java new file mode 100644 index 0000000000..1c01786c31 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingListener.java @@ -0,0 +1,155 @@ +/* + * 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.jms.provider; + +import java.lang.reflect.InvocationTargetException; +import java.util.List; + +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.naming.NamingException; + +import org.apache.tuscany.sca.binding.jms.impl.JMSBinding; +import org.apache.tuscany.sca.binding.jms.impl.JMSBindingConstants; +import org.apache.tuscany.sca.binding.jms.impl.JMSBindingException; +import org.apache.tuscany.sca.host.jms.JMSResourceFactory; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.runtime.RuntimeComponentService; + +public class JMSBindingListener implements MessageListener { + + private static final String ON_MESSAGE_METHOD_NAME = "onMessage"; + private JMSBinding jmsBinding; + private JMSResourceFactory jmsResourceFactory; + private RuntimeComponentService service; + private JMSMessageProcessor requestMessageProcessor; + private JMSMessageProcessor responseMessageProcessor; + private String correlationScheme; + + public JMSBindingListener(JMSBinding jmsBinding, + JMSResourceFactory jmsResourceFactory, + RuntimeComponentService service) throws NamingException { + this.jmsBinding = jmsBinding; + this.jmsResourceFactory = jmsResourceFactory; + this.service = service; + requestMessageProcessor = jmsBinding.getRequestMessageProcessor(); + responseMessageProcessor = jmsBinding.getResponseMessageProcessor(); + correlationScheme = jmsBinding.getCorrelationScheme(); + } + + public void onMessage(Message requestJMSMsg) { + try { + Object responsePayload = invokeService(requestJMSMsg); + sendReply(requestJMSMsg, responsePayload); + } catch (Exception e) { + sendFaultReply(requestJMSMsg, e); + } + } + + /** + * Turn the JMS message back into a Tuscany message and invoke the target component + * + * @param requestJMSMsg + * @return + * @throws JMSException + * @throws InvocationTargetException + */ + protected Object invokeService(Message requestJMSMsg) throws JMSException, InvocationTargetException { + + String operationName = requestMessageProcessor.getOperationName(requestJMSMsg); + Object requestPayload = requestMessageProcessor.extractPayloadFromJMSMessage(requestJMSMsg); + + List<Operation> opList = service.getInterfaceContract().getInterface().getOperations(); + + Operation operation = null; + + if (opList.size() == 1) { + // SCA JMS Binding Specification - Rule 1.5.1 line 203 + operation = opList.get(0); + } else if (operationName != null) { + // SCA JMS Binding Specification - Rule 1.5.1 line 205 + for (Operation op : opList) { + if (op.getName().equals(operationName)) { + operation = op; + break; + } + } + } else { + // SCA JMS Binding Specification - Rule 1.5.1 line 207 + for (Operation op : opList) { + if (op.getName().equals(ON_MESSAGE_METHOD_NAME)) { + operation = op; + break; + } + } + } + + if (operation != null) { + return service.getRuntimeWire(jmsBinding).invoke(operation, (Object[])requestPayload); + } else { + throw new JMSBindingException("Can't find operation " + (operationName != null ? operationName + : ON_MESSAGE_METHOD_NAME)); + } + + } + + protected void sendReply(Message requestJMSMsg, Object responsePayload) { + try { + + if (requestJMSMsg.getJMSReplyTo() == null) { + // assume no reply is expected + return; + } + + Session session = jmsResourceFactory.createSession(); + Message replyJMSMsg = responseMessageProcessor.insertPayloadIntoJMSMessage(session, responsePayload); + + replyJMSMsg.setJMSDeliveryMode(requestJMSMsg.getJMSDeliveryMode()); + replyJMSMsg.setJMSPriority(requestJMSMsg.getJMSPriority()); + + if (correlationScheme == null || JMSBindingConstants.CORRELATE_MSG_ID.equalsIgnoreCase(correlationScheme)) { + replyJMSMsg.setJMSCorrelationID(requestJMSMsg.getJMSMessageID()); + } else if (JMSBindingConstants.CORRELATE_CORRELATION_ID.equalsIgnoreCase(correlationScheme)) { + replyJMSMsg.setJMSCorrelationID(requestJMSMsg.getJMSCorrelationID()); + } + + Destination destination = requestJMSMsg.getJMSReplyTo(); + MessageProducer producer = session.createProducer(destination); + + producer.send(replyJMSMsg); + + producer.close(); + session.close(); + + } catch (JMSException e) { + throw new JMSBindingException(e); + } catch (NamingException e) { + throw new JMSBindingException(e); + } + } + + protected void sendFaultReply(Message requestJMSMsg, Exception e) { + sendReply(requestJMSMsg, new JMSBindingException("exception invoking JMS service", e)); + } + +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingProviderFactory.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingProviderFactory.java new file mode 100644 index 0000000000..06f5388bd1 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingProviderFactory.java @@ -0,0 +1,64 @@ +/* + * 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.jms.provider; + +import org.apache.tuscany.sca.binding.jms.impl.JMSBinding; +import org.apache.tuscany.sca.binding.jms.impl.JMSBindingException; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.host.jms.JMSHost; +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.RuntimeComponent; +import org.apache.tuscany.sca.runtime.RuntimeComponentReference; +import org.apache.tuscany.sca.runtime.RuntimeComponentService; + +/** + * A factory from creating the JMS binding provider. + * + * @version $Rev$ $Date$ + */ +public class JMSBindingProviderFactory implements BindingProviderFactory<JMSBinding> { + + private JMSHost jmsHost; + + public JMSBindingProviderFactory(ExtensionPointRegistry extensionPoints) { + jmsHost = extensionPoints.getExtensionPoint(JMSHost.class); + if (jmsHost == null) { + throw new JMSBindingException("No JMSHost extension point registered"); + } + } + + public ReferenceBindingProvider createReferenceBindingProvider(RuntimeComponent component, + RuntimeComponentReference reference, + JMSBinding binding) { + return new JMSBindingReferenceBindingProvider(component, reference, binding, jmsHost); + } + + public ServiceBindingProvider createServiceBindingProvider(RuntimeComponent component, + RuntimeComponentService service, + JMSBinding binding) { + return new JMSBindingServiceBindingProvider(component, service, binding, jmsHost); + } + + public Class<JMSBinding> getModelType() { + return JMSBinding.class; + } +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingReferenceBindingProvider.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingReferenceBindingProvider.java new file mode 100644 index 0000000000..eb22783813 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingReferenceBindingProvider.java @@ -0,0 +1,145 @@ +/* + * 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.jms.provider; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.tuscany.sca.binding.jms.impl.JMSBinding; +import org.apache.tuscany.sca.binding.jms.impl.JMSBindingConstants; +import org.apache.tuscany.sca.binding.jms.impl.JMSBindingException; +import org.apache.tuscany.sca.host.jms.JMSHost; +import org.apache.tuscany.sca.host.jms.JMSResourceFactory; +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.invocation.Invoker; +import org.apache.tuscany.sca.provider.ReferenceBindingProvider; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.runtime.RuntimeComponentReference; + +/** + * Implementation of the JMS reference binding provider. + * + * @version $Rev$ $Date$ + */ +public class JMSBindingReferenceBindingProvider implements ReferenceBindingProvider { + + private RuntimeComponentReference reference; + private JMSBinding jmsBinding; + private List<JMSBindingInvoker> jmsBindingInvokers = new ArrayList<JMSBindingInvoker>(); + private JMSResourceFactory jmsResourceFactory; + + public JMSBindingReferenceBindingProvider(RuntimeComponent component, + RuntimeComponentReference reference, + JMSBinding binding, JMSHost jmsHost) { + this.reference = reference; + this.jmsBinding = binding; + jmsResourceFactory = jmsHost.createJMSResourceFactory(binding.getConnectionFactoryName(), binding.getInitialContextFactoryName(), binding.getJndiURL()); + + if (jmsBinding.getXMLFormat()) { + setXMLDataBinding(reference); + } + + } + + protected void setXMLDataBinding(RuntimeComponentReference reference) { + try { + InterfaceContract ic = (InterfaceContract)reference.getInterfaceContract().clone(); + + Interface ii = (Interface)ic.getInterface().clone(); + ii.resetDataBinding("org.apache.axiom.om.OMElement"); + ic.setInterface(ii); + reference.setInterfaceContract(ic); + + } catch (CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } + + public Invoker createInvoker(Operation operation) { + + if (jmsBinding.getDestinationName().equals(JMSBindingConstants.DEFAULT_DESTINATION_NAME)) { + throw new JMSBindingException("No destination specified for reference " + reference.getName()); + } + + /* The following doesn't work as I can't get to the + * target list on the composite reference + // if the default destination queue name is set + // set the destination queue name to the wired service name + // so that any wires can be assured a unique endpoint. + + if (jmsBinding.getDestinationName().equals(JMSBindingConstants.DEFAULT_DESTINATION_NAME)){ + // get the name of the target service + List<ComponentService> targets = reference.getTargets(); + + if (targets.size() < 1){ + throw new JMSBindingException("No target specified for reference " + + reference.getName() + + " so destination queue name can't be determined"); + } + + if (targets.size() > 1){ + throw new JMSBindingException("More than one target specified for reference " + + reference.getName() + + " so destination queue name can't be determined"); + } + + ComponentService service = targets.get(0); + jmsBinding.setDestinationName(service.getName()); + } + + + // if the default response queue name is set + // set the response queue to the names of this + // reference + if (jmsBinding.getResponseDestinationName().equals(JMSBindingConstants.DEFAULT_RESPONSE_DESTINATION_NAME)){ + jmsBinding.setResponseDestinationName(reference.getName()); + } + */ + JMSBindingInvoker invoker = new JMSBindingInvoker(jmsBinding, operation, jmsResourceFactory); + jmsBindingInvokers.add(invoker); + return invoker; + } + + public boolean supportsOneWayInvocation() { + return true; + } + + public InterfaceContract getBindingInterfaceContract() { + return reference.getInterfaceContract(); + } + + public void start() { + + } + + public void stop() { + try { + for (JMSBindingInvoker invoker : jmsBindingInvokers) { + invoker.stop(); + + } + } catch (Exception e) { + throw new JMSBindingException("Error stopping JMSReferenceBinding", e); + } + } + +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingServiceBindingProvider.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingServiceBindingProvider.java new file mode 100644 index 0000000000..33e2d32663 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingServiceBindingProvider.java @@ -0,0 +1,194 @@ +/* + * 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.jms.provider; + +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.MessageConsumer; +import javax.jms.Session; +import javax.naming.NamingException; + +import org.apache.tuscany.sca.binding.jms.impl.JMSBinding; +import org.apache.tuscany.sca.binding.jms.impl.JMSBindingConstants; +import org.apache.tuscany.sca.binding.jms.impl.JMSBindingException; +import org.apache.tuscany.sca.host.jms.JMSHost; +import org.apache.tuscany.sca.host.jms.JMSResourceFactory; +import org.apache.tuscany.sca.interfacedef.Interface; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; +import org.apache.tuscany.sca.provider.ServiceBindingProvider; +import org.apache.tuscany.sca.runtime.RuntimeComponent; +import org.apache.tuscany.sca.runtime.RuntimeComponentService; + +/** + * Implementation of the JMS service binding provider. + * + * @version $Rev$ $Date$ + */ +public class JMSBindingServiceBindingProvider implements ServiceBindingProvider { + + private RuntimeComponentService service; + private JMSBinding jmsBinding; + private JMSResourceFactory jmsResourceFactory; + private MessageConsumer consumer; + + public JMSBindingServiceBindingProvider(RuntimeComponent component, + RuntimeComponentService service, + JMSBinding binding, JMSHost jmsHost) { + this.service = service; + this.jmsBinding = binding; + + jmsResourceFactory = jmsHost.createJMSResourceFactory(binding.getConnectionFactoryName(), binding.getInitialContextFactoryName(), binding.getJndiURL()); + jmsResourceFactory.startBroker(); + + // if the default destination queue names is set + // set the destinate queue name to the reference name + // so that any wires can be assured a unique endpoint. + if (jmsBinding.getDestinationName().equals(JMSBindingConstants.DEFAULT_DESTINATION_NAME)) { + // jmsBinding.setDestinationName(service.getName()); + throw new JMSBindingException("No destination specified for service " + service.getName()); + } + + if (jmsBinding.getXMLFormat()) { + setXMLDataBinding(service); + } + + } + + protected void setXMLDataBinding(RuntimeComponentService service) { + if (service.getInterfaceContract() != null) { + try { + InterfaceContract ic = (InterfaceContract)service.getInterfaceContract().clone(); + + Interface ii = (Interface)ic.getInterface().clone(); + ii.resetDataBinding("org.apache.axiom.om.OMElement"); + ic.setInterface(ii); + service.setInterfaceContract(ic); + + } catch (CloneNotSupportedException e) { + throw new RuntimeException(e); + } + } + } + + public InterfaceContract getBindingInterfaceContract() { + return service.getInterfaceContract(); + } + + public boolean supportsOneWayInvocation() { + return true; + } + + public void start() { + + try { + registerListerner(); + } catch (Exception e) { + throw new JMSBindingException("Error starting JMSServiceBinding", e); + } + } + + public void stop() { + try { + consumer.close(); + jmsResourceFactory.closeConnection(); + } catch (Exception e) { + throw new JMSBindingException("Error stopping JMSServiceBinding", e); + } + } + + private void registerListerner() throws NamingException, JMSException { + + Session session = jmsResourceFactory.createSession(); + Destination destination = lookupDestinationQueue(); + + consumer = session.createConsumer(destination); + + consumer.setMessageListener(new JMSBindingListener(jmsBinding, jmsResourceFactory, service)); + + jmsResourceFactory.startConnection(); + + } + + /** + * Looks up the Destination Queue for the JMS Binding. + * <p> + * What happens in the look up will depend on the create mode specified for the JMS Binding: + * <ul> + * <li>always - the JMS queue is always created. It is an error if the queue already exists + * <li>ifnotexist - the JMS queue is created if it does not exist. It is not an error if the queue already exists + * <li>never - the JMS queue is never created. It is an error if the queue does not exist + * </ul> + * See the SCA JMS Binding specification for more information. + * <p> + * + * @return The Destination queue. + * @throws NamingException Failed to lookup JMS queue + * @throws JMSBindingException Failed to lookup JMS Queue. Probable cause is that the JMS queue's current + * existance/non-existance is not compatible with the create mode specified on the binding + */ + private Destination lookupDestinationQueue() throws NamingException, JMSBindingException { + Destination destination = jmsResourceFactory.lookupDestination(jmsBinding.getDestinationName()); + + String qCreateMode = jmsBinding.getDestinationCreate(); + if (qCreateMode.equals(JMSBindingConstants.CREATE_ALWAYS)) { + // In this mode, the queue must not already exist as we are creating it + if (destination != null) { + throw new JMSBindingException("JMS Destination " + jmsBinding.getDestinationName() + + " already exists but has create mode of \"" + + qCreateMode + + "\" while registering service " + + service.getName() + + " listener"); + } + + // Create the queue + destination = jmsResourceFactory.createDestination(jmsBinding.getDestinationName()); + + } else if (qCreateMode.equals(JMSBindingConstants.CREATE_IF_NOT_EXIST)) { + // In this mode, the queue may nor may not exist. It will be created if it does not exist + if (destination == null) { + destination = jmsResourceFactory.createDestination(jmsBinding.getDestinationName()); + } + + } else if (qCreateMode.equals(JMSBindingConstants.CREATE_NEVER)) { + // In this mode, the queue must have already been created. + if (destination == null) { + throw new JMSBindingException("JMS Destination " + jmsBinding.getDestinationName() + + " not found but create mode of \"" + + qCreateMode + + "\" while registering service " + + service.getName() + + " listener"); + } + } + + // Make sure we ended up with a queue + if (destination == null) { + throw new JMSBindingException("JMS Destination " + jmsBinding.getDestinationName() + + " not found with create mode of \"" + + qCreateMode + + "\" while registering service " + + service.getName() + + " listener"); + } + + return destination; + } +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSMessageProcessor.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSMessageProcessor.java new file mode 100644 index 0000000000..29ea78e906 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSMessageProcessor.java @@ -0,0 +1,48 @@ +/* + * 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.jms.provider; + +import javax.jms.Message; +import javax.jms.Session; + +/** + * Interface for a component that does operation selection and message payload processing + */ +public interface JMSMessageProcessor { + + /** + * Get the operation name from a JMS Message + */ + public abstract String getOperationName(Message message); + + /** + * Set the operation name on a JMS Message + */ + public abstract void setOperationName(String operationName, Message message); + + /** + * Extracts the payload from a JMS Message + */ + public abstract Object extractPayloadFromJMSMessage(Message msg); + + /** + * Create a JMS Message containing the payload + */ + public abstract Message insertPayloadIntoJMSMessage(Session session, Object payload); +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSMessageProcessorImpl.java b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSMessageProcessorImpl.java new file mode 100644 index 0000000000..57ba81106f --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/java/org/apache/tuscany/sca/binding/jms/provider/JMSMessageProcessorImpl.java @@ -0,0 +1,161 @@ +/* + * 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.jms.provider; + +import java.io.Serializable; +import java.io.StringReader; + +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.ObjectMessage; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.axiom.om.OMElement; +import org.apache.axiom.om.impl.builder.StAXOMBuilder; +import org.apache.tuscany.sca.binding.jms.impl.JMSBinding; +import org.apache.tuscany.sca.binding.jms.impl.JMSBindingException; + +public class JMSMessageProcessorImpl implements JMSMessageProcessor { + + protected String operationPropertyName; + protected boolean xmlFormat; + + public JMSMessageProcessorImpl(JMSBinding jmsBinding) { + this.operationPropertyName = jmsBinding.getOperationSelectorPropertyName(); + this.xmlFormat = jmsBinding.getXMLFormat(); + } + + /* + * (non-Javadoc) + * + * @see org.apache.tuscany.binding.jms.OperationAndDataBinding#getOperationName(javax.jms.Message) + */ + public String getOperationName(Message message) { + try { + + return message.getStringProperty(operationPropertyName); + + } catch (JMSException e) { + throw new JMSBindingException("Exception retreiving operation name from message", e); + } + } + + /* + * (non-Javadoc) + * + * @see org.apache.tuscany.binding.jms.OperationAndDataBinding#setOperationName(javax.jms.Message, java.lang.String) + */ + public void setOperationName(String operationName, Message message) { + try { + + message.setStringProperty(operationPropertyName, operationName); + + } catch (JMSException e) { + throw new JMSBindingException("Exception setting the operation name on message", e); + } + } + + /* + * (non-Javadoc) + * + * @see org.apache.tuscany.binding.jms.OperationAndDataBinding#extractPayload(javax.jms.Session, java.lang.Object) + */ + public Message insertPayloadIntoJMSMessage(Session session, Object o) { + if (xmlFormat) { + return createXMLJMSMessage(session, o); + } else { + return createObjectJMSMessage(session, o); + } + } + + /* + * (non-Javadoc) + * + * @see org.apache.tuscany.binding.jms.OperationAndDataBinding#extractPayload(javax.jms.Message) + */ + public Object extractPayloadFromJMSMessage(Message msg) { + if (xmlFormat) { + return extractXMLPayload(msg); + } else { + return extractObjectPayload(msg); + } + } + + protected Object extractXMLPayload(Message msg) { + try { + + String xml = ((TextMessage)msg).getText(); + + XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(new StringReader(xml)); + StAXOMBuilder builder = new StAXOMBuilder(reader); + OMElement omElement = builder.getDocumentElement(); + + return new Object[] {omElement}; + + } catch (XMLStreamException e) { + throw new JMSBindingException(e); + } catch (JMSException e) { + throw new JMSBindingException(e); + } + } + + protected Object extractObjectPayload(Message msg) { + try { + + return ((ObjectMessage)msg).getObject(); + + } catch (JMSException e) { + throw new JMSBindingException(e); + } + } + + protected Message createXMLJMSMessage(Session session, Object o) { + try { + + TextMessage message = session.createTextMessage(); + + if (o instanceof OMElement) { + message.setText(o.toString()); + } else { + message.setText(((Object[])o)[0].toString()); + } + + return message; + + } catch (JMSException e) { + throw new JMSBindingException(e); + } + } + + protected Message createObjectJMSMessage(Session session, Object o) { + try { + + ObjectMessage message = session.createObjectMessage(); // default + message.setObject((Serializable)o); + return message; + + } catch (JMSException e) { + throw new JMSBindingException(e); + } + } +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor b/branches/sca-java-1.1/modules/binding-jms/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor new file mode 100644 index 0000000000..ac37a0f26b --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor @@ -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 artifact processor extension +org.apache.tuscany.sca.binding.jms.impl.JMSBindingProcessor;qname=http://www.osoa.org/xmlns/sca/1.0#binding.jms,model=org.apache.tuscany.sca.binding.jms.impl.JMSBinding diff --git a/branches/sca-java-1.1/modules/binding-jms/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.BindingProviderFactory b/branches/sca-java-1.1/modules/binding-jms/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.BindingProviderFactory new file mode 100644 index 0000000000..dec0991984 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/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.jms.provider.JMSBindingProviderFactory;model=org.apache.tuscany.sca.binding.jms.impl.JMSBinding
diff --git a/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/HelloWorldClientImpl.java b/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/HelloWorldClientImpl.java new file mode 100644 index 0000000000..86d4719646 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/HelloWorldClientImpl.java @@ -0,0 +1,41 @@ +/* + * 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.jms; + +import org.osoa.sca.annotations.Reference; +import org.osoa.sca.annotations.Service; + +/** + * This class implements the HelloWorld service. + */ +@Service(HelloWorldService.class) +public class HelloWorldClientImpl implements HelloWorldService { + + private HelloWorldService serviceA; + + @Reference + public void setServiceA(HelloWorldService service) { + this.serviceA = service; + } + + public String sayHello(String name) { + return serviceA.sayHello(name); + } + +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/HelloWorldService.java b/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/HelloWorldService.java new file mode 100644 index 0000000000..abb29aec4c --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/HelloWorldService.java @@ -0,0 +1,26 @@ +/* + * 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.jms; + +import org.osoa.sca.annotations.Remotable; + +@Remotable +public interface HelloWorldService { + String sayHello(String name); +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/HelloWorldServiceImpl.java b/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/HelloWorldServiceImpl.java new file mode 100644 index 0000000000..daa3d551df --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/HelloWorldServiceImpl.java @@ -0,0 +1,27 @@ +/* + * 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.jms; + +public class HelloWorldServiceImpl implements HelloWorldService { + + public String sayHello(String name) { + return "jmsHello " + name; + } + +} diff --git a/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/OperationSelectionTestCase.java b/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/OperationSelectionTestCase.java new file mode 100644 index 0000000000..85106968f8 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/OperationSelectionTestCase.java @@ -0,0 +1,230 @@ +/*
+ * 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.jms;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.jms.TextMessage;
+
+import org.apache.tuscany.sca.binding.jms.impl.JMSBinding;
+import org.apache.tuscany.sca.binding.jms.provider.JMSBindingListener;
+import org.apache.tuscany.sca.host.jms.JMSResourceFactory;
+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.impl.OperationImpl;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+import org.apache.tuscany.sca.runtime.RuntimeWire;
+import org.easymock.EasyMock;
+import org.junit.Test;
+
+/**
+ * This unit test is used to ensure that a JMS Message delivered to a Component will select the correct operation based
+ * on the details in section 1.5 of the JMS Binding specification.
+ */
+public class OperationSelectionTestCase {
+ /**
+ * This test attempts to invoke a Service with a Single method where scaOperationName is not specified in the JMS
+ * Message
+ * <p>
+ * Expected behaviour is that the single method will be invoked as scaOperationName is ignored
+ *
+ * @throws Exception Failed
+ */
+ @Test
+ public void testServiceWithOnlyOneOperationScaOperationNameNotSpecified() throws Exception {
+ // Create the operation we should match
+ final Operation expectedOperation = new OperationImpl("myOperation");
+
+ // Create the list of operations for the Service
+ final List<Operation> operations = new ArrayList<Operation>();
+ operations.add(expectedOperation);
+
+ // The name of the Operation in the JMS Message - not specified
+ final String scaOperationName = null;
+
+ // Do the test
+ doTestJMSBinding(expectedOperation, operations, scaOperationName);
+ }
+
+ /**
+ * This test attempts to invoke a Service with a Single method where scaOperationName in the JMS Message matches the
+ * method name on the Service
+ * <p>
+ * Expected behaviour is that the single method will be invoked as scaOperationName is ignored
+ *
+ * @throws Exception Failed
+ */
+ @Test
+ public void testServiceWithOnlyOneOperationScaOperationNameMatches() throws Exception {
+ // Create the operation we should match
+ final Operation expectedOperation = new OperationImpl("myOperation");
+
+ // Create the list of operations for the Service
+ final List<Operation> operations = new ArrayList<Operation>();
+ operations.add(expectedOperation);
+
+ // The name of the Operation in the JMS Message - matches operation name
+ final String scaOperationName = expectedOperation.getName();
+
+ // Do the test
+ doTestJMSBinding(expectedOperation, operations, scaOperationName);
+ }
+
+ /**
+ * This test attempts to invoke a Service with a Single method where scaOperationName in the JMS Message is
+ * different the method name on the Service
+ * <p>
+ * Expected behaviour is that the single method will be invoked as scaOperationName is ignored
+ *
+ * @throws Exception Failed
+ */
+ @Test
+ public void testServiceWithOnlyOneOperationScaOperationNameDifferent() throws Exception {
+ // Create the operation we should match
+ final Operation expectedOperation = new OperationImpl("myOperation");
+
+ // Create the list of operations for the Service
+ final List<Operation> operations = new ArrayList<Operation>();
+ operations.add(expectedOperation);
+
+ // The name of the Operation in the JMS Message - different to operation name
+ final String scaOperationName = "Does Not Match Opeation Name";
+
+ // Do the test
+ doTestJMSBinding(expectedOperation, operations, scaOperationName);
+ }
+
+ /**
+ * This test attempts to invoke a Service with a multiple operations where scaOperationName specified in the JMS
+ * Message matches an operation name
+ * <p>
+ * Expected behaviour is that the named method will be invoked.
+ *
+ * @throws Exception Failed
+ */
+ @Test
+ public void testServiceWithMultipleOperationsScaOperationNameSpecified() throws Exception {
+ // Create the list of operations for the Service
+ final List<Operation> operations = new ArrayList<Operation>();
+ for (int i = 0; i < 5; i++) {
+ operations.add(new OperationImpl("operation" + i));
+ }
+
+ // Now try and invoke each operation
+ for (Operation expectedOperation : operations) {
+ // The name of the Operation in the JMS Message
+ final String scaOperationName = expectedOperation.getName();
+
+ // Do the test
+ doTestJMSBinding(expectedOperation, operations, scaOperationName);
+ }
+ }
+
+ /**
+ * This test attempts to invoke a Service with a multiple operations where scaOperationName specified in the JMS
+ * Message is not set so we invoke the onMessage() method
+ * <p>
+ * Expected behaviour is that the onMessage() method should be used instead
+ *
+ * @throws Exception Failed
+ */
+ @Test
+ public void testServiceWithMultipleOperationsScaOperationNotSpecified() throws Exception {
+ // Create the list of operations for the Service
+ final List<Operation> operations = new ArrayList<Operation>();
+ for (int i = 0; i < 5; i++) {
+ operations.add(new OperationImpl("operation" + i));
+ }
+
+ // Add the onMessage operation to the Service Contract
+ final Operation onMessageOperation = new OperationImpl("onMessage");
+ operations.add(onMessageOperation);
+
+ // The name of the Operation in the JMS Message is not set so it will attempt
+ // to invoke the onMessage() method
+ final String scaOperationName = null;
+
+ // Do the test
+ doTestJMSBinding(onMessageOperation, operations, scaOperationName);
+ }
+
+ /**
+ * This is the test method that will attempt to unit test invoking a Service with the specified operations using a
+ * JMS Message with the specified scaOperationName to ensure that it invokes the expectedOperation
+ *
+ * @param expectedOperation The Operation we are expecting to be invoked over JMS
+ * @param operations The list of Operations supported by the Service
+ * @param scaOperationName The value to set scaOperationName in the JMS Message
+ * @throws Exception Failed
+ */
+ private void doTestJMSBinding(Operation expectedOperation, List<Operation> operations, String scaOperationName)
+ throws Exception {
+ // Create the test JMS Binding
+ final JMSBinding jmsBinding = new JMSBinding();
+ JMSResourceFactory jmsResourceFactory = null;
+
+ // Extra information for the method we are invoking
+ final String operationParams = "Hello";
+ final Object operationReturnValue = "Operation Success";
+
+ // Mock up the Service. Basically, it is going to call:
+ // List<Operation> opList = service.getInterfaceContract().getInterface().getOperations();
+ final InterfaceContract ifaceContract = EasyMock.createStrictMock(InterfaceContract.class);
+ final RuntimeComponentService service = EasyMock.createStrictMock(RuntimeComponentService.class);
+ final Interface iface = EasyMock.createStrictMock(Interface.class);
+ EasyMock.expect(iface.getOperations()).andReturn(operations);
+ EasyMock.expect(ifaceContract.getInterface()).andReturn(iface);
+ EasyMock.expect(service.getInterfaceContract()).andReturn(ifaceContract);
+
+ // Mock up getting and invoking the RuntimeWire. It is going to call:
+ // service.getRuntimeWire(jmsBinding).invoke(operation, (Object[])requestPayload);
+ final RuntimeWire runtimeWire = EasyMock.createStrictMock(RuntimeWire.class);
+ EasyMock.expect(service.getRuntimeWire(jmsBinding)).andReturn(runtimeWire);
+ EasyMock.expect(runtimeWire.invoke(expectedOperation, new Object[] {operationParams}))
+ .andReturn(operationReturnValue);
+
+ // Create the JMS Binding Listener
+ final JMSBindingListener bindingListener = new JMSBindingListener(jmsBinding, jmsResourceFactory, service);
+
+ // Simulate a message
+ final TextMessage requestJMSMsg = EasyMock.createStrictMock(TextMessage.class);
+ EasyMock.expect(requestJMSMsg.getStringProperty("scaOperationName")).andReturn(scaOperationName);
+ EasyMock.expect(requestJMSMsg.getText()).andReturn(operationParams);
+ EasyMock.expect(requestJMSMsg.getJMSReplyTo()).andReturn(null);
+
+ // Lets put all the mocks into replay mode
+ // EasyMock.replay(iface);
+ EasyMock.replay(ifaceContract);
+ EasyMock.replay(service);
+ EasyMock.replay(requestJMSMsg);
+ EasyMock.replay(runtimeWire);
+
+ // Do the test
+ bindingListener.onMessage(requestJMSMsg);
+
+ // Verify our Mock objects
+ // EasyMock.verify(iface);
+ // EasyMock.verify(ifaceContract);
+ // EasyMock.verify(service);
+ // EasyMock.verify(requestJMSMsg);
+ // EasyMock.verify(runtimeWire);
+ }
+}
diff --git a/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/mock/MockJMSResourceFactory.java b/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/mock/MockJMSResourceFactory.java new file mode 100644 index 0000000000..c58bf72031 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/mock/MockJMSResourceFactory.java @@ -0,0 +1,94 @@ +/*
+ * 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.jms.mock;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.Session;
+import javax.naming.NamingException;
+
+import org.apache.tuscany.sca.host.jms.JMSResourceFactory;
+import org.easymock.EasyMock;
+
+/**
+ * Mock JMSResourceFactory base class for testing purposes.
+ */
+public abstract class MockJMSResourceFactory implements JMSResourceFactory {
+
+ /**
+ * Throws UnsupportedOperationException
+ */
+ public void closeConnection() throws JMSException, NamingException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Creates a Mock Destination
+ *
+ * @param jndiName Ignored
+ * @return A Mock Destination
+ */
+ public Destination createDestination(String jndiName) throws NamingException {
+ final Destination d = EasyMock.createMock(Destination.class);
+ EasyMock.replay(d);
+ return d;
+ }
+
+ /**
+ * Creates a Mock Session.
+ *
+ * @return A Mock Session
+ */
+ public Session createSession() throws JMSException, NamingException {
+ final Session session = EasyMock.createMock(Session.class);
+ final MessageConsumer consumer = EasyMock.createMock(MessageConsumer.class);
+ final MessageListener listener = EasyMock.createMock(MessageListener.class);
+ EasyMock.expect(session.createConsumer((Destination)EasyMock.anyObject())).andReturn(consumer);
+ consumer.setMessageListener((MessageListener)EasyMock.anyObject());
+ EasyMock.replay(session);
+ EasyMock.replay(consumer);
+ EasyMock.replay(listener);
+ return session;
+ }
+
+ /**
+ * Throws UnsupportedOperationException
+ */
+ public Connection getConnection() throws NamingException, JMSException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Throws UnsupportedOperationException
+ *
+ * @param jndiName Ignored
+ */
+ public Destination lookupDestination(String jndiName) throws NamingException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Does nothing
+ */
+ public void startConnection() throws JMSException, NamingException {
+ }
+}
diff --git a/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/mock/MockJMSResourceFactoryQueueExist.java b/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/mock/MockJMSResourceFactoryQueueExist.java new file mode 100644 index 0000000000..5fa8d39f5d --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/mock/MockJMSResourceFactoryQueueExist.java @@ -0,0 +1,50 @@ +/*
+ * 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.jms.mock;
+
+import javax.jms.Destination;
+import javax.naming.NamingException;
+
+import org.apache.tuscany.sca.binding.jms.impl.JMSBinding;
+import org.easymock.EasyMock;
+
+/**
+ * This mock JMSResourceFactory will create a mock Destination when the lookupDestination() method is called
+ */
+public class MockJMSResourceFactoryQueueExist extends MockJMSResourceFactory {
+ /**
+ * Constructor
+ *
+ * @param jmsBinding Ignored
+ */
+ public MockJMSResourceFactoryQueueExist(JMSBinding jmsBinding) {
+ }
+
+ /**
+ * Return a mock Destination object
+ */
+ public Destination lookupDestination(String jndiName) throws NamingException {
+ final Destination d = EasyMock.createMock(Destination.class);
+ EasyMock.replay(d);
+ return d;
+ }
+
+ public void startBroker() {
+ }
+}
diff --git a/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/mock/MockJMSResourceFactoryQueueNotExist.java b/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/mock/MockJMSResourceFactoryQueueNotExist.java new file mode 100644 index 0000000000..a14fd5b5bd --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/mock/MockJMSResourceFactoryQueueNotExist.java @@ -0,0 +1,47 @@ +/*
+ * 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.jms.mock;
+
+import javax.jms.Destination;
+import javax.naming.NamingException;
+
+import org.apache.tuscany.sca.binding.jms.impl.JMSBinding;
+
+/**
+ * This mock JMSResourceFactory will always return <code>null</code> when the lookupDestination() method is called
+ */
+public class MockJMSResourceFactoryQueueNotExist extends MockJMSResourceFactory {
+ /**
+ * Constructor
+ *
+ * @param jmsBinding Ignored
+ */
+ public MockJMSResourceFactoryQueueNotExist(JMSBinding jmsBinding) {
+ }
+
+ /**
+ * Always returns null
+ */
+ public Destination lookupDestination(String jndiName) throws NamingException {
+ return null;
+ }
+
+ public void startBroker() {
+ }
+}
diff --git a/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingReferenceQueueCreateModeTestCaseFIXME.java b/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingReferenceQueueCreateModeTestCaseFIXME.java new file mode 100644 index 0000000000..79e762be63 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingReferenceQueueCreateModeTestCaseFIXME.java @@ -0,0 +1,328 @@ +/*
+ * 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.jms.provider;
+
+import junit.framework.Assert;
+
+import org.apache.tuscany.sca.binding.jms.impl.JMSBinding;
+import org.apache.tuscany.sca.binding.jms.impl.JMSBindingException;
+import org.apache.tuscany.sca.binding.jms.mock.MockJMSResourceFactoryQueueExist;
+import org.apache.tuscany.sca.binding.jms.mock.MockJMSResourceFactoryQueueNotExist;
+import org.apache.tuscany.sca.host.jms.JMSHost;
+import org.apache.tuscany.sca.host.jms.JMSResourceFactory;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.impl.OperationImpl;
+import org.junit.Test;
+
+/**
+ * This unit test tests various combinations of the JMS Binding create modes for both request and response queues.
+ * <p>
+ * The SCA JMS Binding specification lists 3 create modes:
+ * <ul>
+ * <li>always - the JMS queue is always created. It is an error if the queue already exists
+ * <li>ifnotexist - the JMS queue is created if it does not exist. It is not an error if the queue already exists
+ * <li>never - the JMS queue is never created. It is an error if the queue does not exist
+ * </ul>
+ * See the SCA JMS Binding specification for more information.
+ */
+public class JMSBindingReferenceQueueCreateModeTestCaseFIXME {
+
+ /**
+ * Test creating a request queue in "never" mode where the queue does not exist. We are expecting an exception
+ */
+ @Test
+ public void testRequestCreateNeverQueueNotExist() {
+ String requestCreateMode = "never";
+ String responseCreateMode = "ifnotexist";
+ boolean preCreateQueue = false;
+ boolean expectingRequestException = true;
+ boolean expectingResponseException = false;
+
+ doTestCase(requestCreateMode,
+ responseCreateMode,
+ preCreateQueue,
+ expectingRequestException,
+ expectingResponseException);
+ }
+
+ /**
+ * Test creating a request queue in "never" mode where the queue exists. We are expecting this to work
+ */
+ @Test
+ public void testRequestCreateNeverQueueExists() {
+ String requestCreateMode = "never";
+ String responseCreateMode = "ifnotexist";
+ boolean preCreateQueue = true;
+ boolean expectingRequestException = false;
+ boolean expectingResponseException = false;
+
+ doTestCase(requestCreateMode,
+ responseCreateMode,
+ preCreateQueue,
+ expectingRequestException,
+ expectingResponseException);
+ }
+
+ /**
+ * Test creating a request queue in "ifnotexist" mode where the queue does not exist. We are expecting this to work
+ */
+ @Test
+ public void testRequestCreateIfNotExistQueueNotExist() {
+ String requestCreateMode = "ifnotexist";
+ String responseCreateMode = "ifnotexist";
+ boolean preCreateQueue = false;
+ boolean expectingRequestException = false;
+ boolean expectingResponseException = false;
+
+ doTestCase(requestCreateMode,
+ responseCreateMode,
+ preCreateQueue,
+ expectingRequestException,
+ expectingResponseException);
+ }
+
+ /**
+ * Test creating a request queue in "ifnotexist" mode where the queue exists. We are expecting this to work
+ */
+ @Test
+ public void testRequestCreateIfNotExistQueueExist() {
+ String requestCreateMode = "ifnotexist";
+ String responseCreateMode = "ifnotexist";
+ boolean preCreateQueue = true;
+ boolean expectingRequestException = false;
+ boolean expectingResponseException = false;
+
+ doTestCase(requestCreateMode,
+ responseCreateMode,
+ preCreateQueue,
+ expectingRequestException,
+ expectingResponseException);
+ }
+
+ /**
+ * Test creating a request queue in "always" mode where the queue does not exist. We are expecting this to work
+ */
+ @Test
+ public void testRequestCreateAlwaysQueueNotExist() {
+ String requestCreateMode = "always";
+ String responseCreateMode = "ifnotexist";
+ boolean preCreateQueue = false;
+ boolean expectingRequestException = false;
+ boolean expectingResponseException = false;
+
+ doTestCase(requestCreateMode,
+ responseCreateMode,
+ preCreateQueue,
+ expectingRequestException,
+ expectingResponseException);
+ }
+
+ /**
+ * Test creating a request queue in "always" mode where the queue exists. We are expecting an exception
+ */
+ @Test
+ public void testRequestCreateAlwaysQueueExists() {
+ String requestCreateMode = "always";
+ String responseCreateMode = "ifnotexist";
+ boolean preCreateQueue = true;
+ boolean expectingRequestException = true;
+ boolean expectingResponseException = false;
+
+ doTestCase(requestCreateMode,
+ responseCreateMode,
+ preCreateQueue,
+ expectingRequestException,
+ expectingResponseException);
+ }
+
+ /**
+ * Test creating a response queue in "never" mode where the queue does not exist. We are expecting an exception
+ */
+ @Test
+ public void testResponseCreateNeverQueueNotExist() {
+ String requestCreateMode = "ifnotexist";
+ String responseCreateMode = "never";
+ boolean preCreateQueue = false;
+ boolean expectingRequestException = false;
+ boolean expectingResponseException = true;
+
+ doTestCase(requestCreateMode,
+ responseCreateMode,
+ preCreateQueue,
+ expectingRequestException,
+ expectingResponseException);
+ }
+
+ /**
+ * Test creating a response queue in "never" mode where the queue exists. We are expecting this to work
+ */
+ @Test
+ public void testResponseCreateNeverQueueExists() {
+ String requestCreateMode = "ifnotexist";
+ String responseCreateMode = "never";
+ boolean preCreateQueue = true;
+ boolean expectingRequestException = false;
+ boolean expectingResponseException = false;
+
+ doTestCase(requestCreateMode,
+ responseCreateMode,
+ preCreateQueue,
+ expectingRequestException,
+ expectingResponseException);
+ }
+
+ /**
+ * Test creating a response queue in "ifnotexist" mode where the queue does not exist. We are expecting this to work
+ */
+ @Test
+ public void testResponseCreateIfNotExistQueueNotExist() {
+ String requestCreateMode = "ifnotexist";
+ String responseCreateMode = "ifnotexist";
+ boolean preCreateQueue = false;
+ boolean expectingRequestException = false;
+ boolean expectingResponseException = false;
+
+ doTestCase(requestCreateMode,
+ responseCreateMode,
+ preCreateQueue,
+ expectingRequestException,
+ expectingResponseException);
+ }
+
+ /**
+ * Test creating a response queue in "ifnotexist" mode where the queue not exists. We are expecting this to work
+ */
+ @Test
+ public void testResponseCreateIfNotExistQueueExist() {
+ String requestCreateMode = "ifnotexist";
+ String responseCreateMode = "ifnotexist";
+ boolean preCreateQueue = true;
+ boolean expectingRequestException = false;
+ boolean expectingResponseException = false;
+
+ doTestCase(requestCreateMode,
+ responseCreateMode,
+ preCreateQueue,
+ expectingRequestException,
+ expectingResponseException);
+ }
+
+ /**
+ * Test creating a response queue in "always" mode where the queue does not exist. We are expecting this to work
+ */
+ @Test
+ public void testResponseCreateAlwaysQueueNotExist() {
+ String requestCreateMode = "ifnotexist";
+ String responseCreateMode = "always";
+ boolean preCreateQueue = false;
+ boolean expectingRequestException = false;
+ boolean expectingResponseException = false;
+
+ doTestCase(requestCreateMode,
+ responseCreateMode,
+ preCreateQueue,
+ expectingRequestException,
+ expectingResponseException);
+ }
+
+ /**
+ * Test creating a response queue in "always" mode where the queue exists. We are expecting an exception
+ */
+ @Test
+ public void testResponseCreateAlwaysQueueExists() {
+ String requestCreateMode = "ifnotexist";
+ String responseCreateMode = "always";
+ boolean preCreateQueue = true;
+ boolean expectingRequestException = false;
+ boolean expectingResponseException = true;
+
+ doTestCase(requestCreateMode,
+ responseCreateMode,
+ preCreateQueue,
+ expectingRequestException,
+ expectingResponseException);
+ }
+
+ /**
+ * This is the main test method for the various test scenarios for the JMS Binding.
+ *
+ * @param requestCreateMode The required create mode for the request destination queue
+ * @param responseCreateMode The required create mode for the response destination queue
+ * @param preCreateQueue Whether the queue should be pre-created.
+ * @param expectingRequestException true if we are expecting an exception because the request queue configuration is
+ * invalid; false otherwise
+ * @param expectingResponseException true if we are expecting an exception because the request queue configuration
+ * is invalid; false otherwise
+ */
+ private void doTestCase(String requestCreateMode,
+ String responseCreateMode,
+ boolean preCreateQueue,
+ boolean expectingRequestException,
+ boolean expectingResponseException) {
+ String requestDestinationName = "SomeRequestDestination";
+ String responseDestinationName = "SomeResponseDestination";
+ String jmsBindingName = "MyJMSBinding";
+
+ // Create a JMS Binding with the required test parameters
+ JMSBinding jmsBinding = new JMSBinding();
+ jmsBinding.setDestinationCreate(requestCreateMode);
+ jmsBinding.setResponseDestinationCreate(responseCreateMode);
+ if (preCreateQueue) {
+ jmsBinding.setJmsResourceFactoryName(MockJMSResourceFactoryQueueExist.class.getName());
+ } else {
+ jmsBinding.setJmsResourceFactoryName(MockJMSResourceFactoryQueueNotExist.class.getName());
+ }
+ jmsBinding.setDestinationName(requestDestinationName);
+ jmsBinding.setResponseDestinationName(responseDestinationName);
+ jmsBinding.setName(jmsBindingName);
+
+ // Create the operation
+ Operation operation = new OperationImpl();
+ operation.setName("OperationName");
+
+ // Try and create the JMS Binding Invoker for the JMS Binding
+ try {
+ new JMSBindingInvoker(jmsBinding, operation, null);
+
+ // Check whether we were expecting an exception
+ if (expectingRequestException || expectingResponseException) {
+ // We were expecting an exception
+ Assert.fail("This binding should have failed as it is invalid");
+ }
+ } catch (JMSBindingException ex) {
+ // Were we expecting an exception
+ if (!expectingRequestException && !expectingResponseException) {
+ // No we were not expecting an exception
+ Assert.fail("Unexpected exception of " + ex);
+ }
+
+ // Validate that the expected exception has the text we expect
+ if (expectingRequestException) {
+ Assert.assertTrue(ex.getMessage().indexOf("JMS Destination") != -1);
+ Assert.assertTrue(ex.getMessage().indexOf(requestCreateMode) != -1);
+ Assert.assertTrue(ex.getMessage().indexOf(requestDestinationName) != -1);
+ } else if (expectingResponseException) {
+ Assert.assertTrue(ex.getMessage().indexOf("JMS Response Destination") != -1);
+ Assert.assertTrue(ex.getMessage().indexOf(responseCreateMode) != -1);
+ Assert.assertTrue(ex.getMessage().indexOf(responseDestinationName) != -1);
+ }
+ Assert.assertTrue(ex.getMessage().indexOf("registering binding " + jmsBindingName + " invoker") != -1);
+ }
+ }
+}
diff --git a/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingServiceQueueCreateModeTestCaseFIXME.java b/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingServiceQueueCreateModeTestCaseFIXME.java new file mode 100644 index 0000000000..6e3a70d904 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/test/java/org/apache/tuscany/sca/binding/jms/provider/JMSBindingServiceQueueCreateModeTestCaseFIXME.java @@ -0,0 +1,179 @@ +/*
+ * 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.jms.provider;
+
+import junit.framework.Assert;
+
+import org.apache.tuscany.sca.binding.jms.impl.JMSBinding;
+import org.apache.tuscany.sca.binding.jms.impl.JMSBindingException;
+import org.apache.tuscany.sca.binding.jms.mock.MockJMSResourceFactoryQueueExist;
+import org.apache.tuscany.sca.binding.jms.mock.MockJMSResourceFactoryQueueNotExist;
+import org.apache.tuscany.sca.core.assembly.RuntimeComponentServiceImpl;
+import org.apache.tuscany.sca.host.jms.JMSHost;
+import org.apache.tuscany.sca.host.jms.JMSResourceFactory;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+import org.junit.Test;
+
+/**
+ * This method tests various combinations of the JMS Binding create modes.
+ * <p>
+ * The SCA JMS Binding specification lists 3 create modes:
+ * <ul>
+ * <li>always - the JMS queue is always created. It is an error if the queue already exists
+ * <li>ifnotexist - the JMS queue is created if it does not exist. It is not an error if the queue already exists
+ * <li>never - the JMS queue is never created. It is an error if the queue does not exist
+ * </ul>
+ * See the SCA JMS Binding specification for more information.
+ */
+public class JMSBindingServiceQueueCreateModeTestCaseFIXME {
+ /**
+ * Test creating a queue in "never" mode where the queue does not exist. We are expecting an exception
+ */
+ @Test
+ public void testCreateNeverQueueNotExist() {
+ String createMode = "never";
+ boolean preCreateQueue = false;
+ boolean expectingException = true;
+
+ doTestCase(createMode, preCreateQueue, expectingException);
+ }
+
+ /**
+ * Test creating a queue in "never" mode where the queue exists. We are expecting this to work
+ */
+ @Test
+ public void testCreateNeverQueueExist() {
+ String createMode = "never";
+ boolean preCreateQueue = true;
+ boolean expectingException = false;
+
+ doTestCase(createMode, preCreateQueue, expectingException);
+ }
+
+ /**
+ * Test creating a queue in "ifnotexist" mode where the queue does not exist. We are expecting this to work
+ */
+ @Test
+ public void testCreateIfNotExistQueueNotExist() {
+ String createMode = "ifnotexist";
+ boolean preCreateQueue = false;
+ boolean expectingException = false;
+
+ doTestCase(createMode, preCreateQueue, expectingException);
+ }
+
+ /**
+ * Test creating a queue in "ifnotexist" mode where the queue exists. We are expecting this to work
+ */
+ @Test
+ public void testCreateIfNotExistQueueExist() {
+ String createMode = "ifnotexist";
+ boolean preCreateQueue = true;
+ boolean expectingException = false;
+
+ doTestCase(createMode, preCreateQueue, expectingException);
+ }
+
+ /**
+ * Test creating a queue in "always" mode where the queue does not exist. We are expecting this to work
+ */
+ @Test
+ public void testCreateAlwaysQueueNotExist() {
+ String createMode = "always";
+ boolean preCreateQueue = false;
+ boolean expectingException = false;
+
+ doTestCase(createMode, preCreateQueue, expectingException);
+ }
+
+ /**
+ * Test creating a queue in "always" mode where the queue exists. We are expecting an exception
+ */
+ @Test
+ public void testCreateAlwaysQueueExist() {
+ String createMode = "always";
+ boolean preCreateQueue = true;
+ boolean expectingException = true;
+
+ doTestCase(createMode, preCreateQueue, expectingException);
+ }
+
+ /**
+ * This is the main test method for the various test scenarios for the JMS Binding.
+ *
+ * @param createMode The required create mode for the destination queue
+ * @param preCreateQueue Whether the queue should be pre-created.
+ * @param expectingException true if test should throw an exception
+ */
+ private void doTestCase(String createMode, boolean preCreateQueue, boolean expectingException) {
+ String destinationName = "SomeDestination";
+ String jmsBindingName = "MyJMSBinding";
+ String serviceName = "MyServiceName";
+
+ // Create a JMS Binding with the required test parameters
+ JMSBinding jmsBinding = new JMSBinding();
+ jmsBinding.setDestinationCreate(createMode);
+ if (preCreateQueue) {
+ jmsBinding.setJmsResourceFactoryName(MockJMSResourceFactoryQueueExist.class.getName());
+ } else {
+ jmsBinding.setJmsResourceFactoryName(MockJMSResourceFactoryQueueNotExist.class.getName());
+ }
+ jmsBinding.setDestinationName(destinationName);
+ jmsBinding.setName(jmsBindingName);
+
+ RuntimeComponentService service = new RuntimeComponentServiceImpl();
+ service.setName(serviceName);
+
+ JMSHost jmsHost = new JMSHost(){
+ public JMSResourceFactory createJMSResourceFactory(String connectionFactoryName, String initialContextFactoryName, String jndiURL) {
+ return null;
+ }};
+
+ // Try and create the JMS Binding Service for the JMS Binding
+ try {
+ JMSBindingServiceBindingProvider jmsService =
+ new JMSBindingServiceBindingProvider(null, service, jmsBinding, jmsHost);
+ jmsService.start();
+
+ // Check whether we were expecting an exception
+ if (expectingException) {
+ // We were expecting an exception
+ Assert.fail("This binding should have failed as it is invalid");
+ }
+ } catch (JMSBindingException ex) {
+ // Were we expecting an exception
+ if (!expectingException) {
+ ex.printStackTrace();
+ // No we were not expecting an exception
+ Assert.fail("Unexpected exception of " + ex);
+ }
+
+ // We should get a JMSBindingException
+ Assert.assertTrue(ex.getMessage().indexOf("Error starting JMSServiceBinding") != -1);
+
+ // Validate that the expected chained exception exception has the text we expect
+ Assert.assertNotNull(ex.getCause());
+ Assert.assertTrue(ex.getCause().getMessage().indexOf("JMS Destination") != -1);
+ Assert.assertTrue(ex.getCause().getMessage().indexOf(createMode) != -1);
+ Assert.assertTrue(ex.getCause().getMessage().indexOf(destinationName) != -1);
+ Assert
+ .assertTrue(ex.getCause().getMessage().indexOf("registering service " + serviceName + " listener") != -1);
+ }
+ }
+}
diff --git a/branches/sca-java-1.1/modules/binding-jms/src/test/resources/simple/client.composite b/branches/sca-java-1.1/modules/binding-jms/src/test/resources/simple/client.composite new file mode 100644 index 0000000000..dcea428493 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/test/resources/simple/client.composite @@ -0,0 +1,38 @@ +<?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://www.osoa.org/xmlns/sca/1.0"
+ name="RPCComposite">
+
+ <component name="HelloWorldClient">
+ <implementation.java class="org.apache.tuscany.sca.binding.jms.HelloWorldClientImpl"/>
+ <reference name="serviceA" />
+ </component>
+
+ <reference name="serviceA" promote="HelloWorldClient/serviceA">
+ <interface.java interface="org.apache.tuscany.sca.binding.jms.HelloWorldService" />
+ <binding.jms initialContextFactory="org.apache.activemq.jndi.ActiveMQInitialContextFactory" jndiURL="tcp://localhost:61616">
+ <destination name="DestQueueA"/>
+ <response>
+ <destination name="RespQueueA"/>
+ </response>
+ </binding.jms>
+ </reference>
+
+</composite>
diff --git a/branches/sca-java-1.1/modules/binding-jms/src/test/resources/simple/service.composite b/branches/sca-java-1.1/modules/binding-jms/src/test/resources/simple/service.composite new file mode 100644 index 0000000000..44b7b29610 --- /dev/null +++ b/branches/sca-java-1.1/modules/binding-jms/src/test/resources/simple/service.composite @@ -0,0 +1,35 @@ +<?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://www.osoa.org/xmlns/sca/1.0"
+ name="RPCComposite">
+
+ <component name="HelloWorldService">
+ <implementation.java class="org.apache.tuscany.sca.binding.jms.HelloWorldServiceImpl"/>
+ <service name="HelloWorldService">
+ <binding.jms initialContextFactory="org.apache.activemq.jndi.ActiveMQInitialContextFactory" jndiURL="tcp://localhost:61616">
+ <destination name="DestQueueA" create="always"/>
+ <response>
+ <destination name="RespQueueA" create="always"/>
+ </response>
+ </binding.jms>
+ </service>
+ </component>
+
+</composite>
|