diff --git a/adapter/pom.xml b/adapter/pom.xml new file mode 100644 index 000000000..2fda046e7 --- /dev/null +++ b/adapter/pom.xml @@ -0,0 +1,49 @@ + + + 4.0.0 + + org.switchyard + switchyard-core-parent + 1.0.0-SNAPSHOT + + switchyard-adapter + SwitchYard: Adapter + The SwitchYard Adapter library. + http://switchyard.org + + + org.switchyard + switchyard-config + + + org.switchyard + switchyard-api + + + org.switchyard + switchyard-extensions-wsdl + + + + org.mockito + mockito-all + test + + + + + jboss-public-repository + JBoss Public Maven Repository + http://repository.jboss.org/nexus/content/groups/public + + + + + jboss-public-repository + JBoss Public Maven Repository + http://repository.jboss.org/nexus/content/groups/public + + + diff --git a/adapter/src/main/java/org/switchyard/adapter/AdapterUtil.java b/adapter/src/main/java/org/switchyard/adapter/AdapterUtil.java new file mode 100644 index 000000000..7b54795f9 --- /dev/null +++ b/adapter/src/main/java/org/switchyard/adapter/AdapterUtil.java @@ -0,0 +1,215 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.switchyard.adapter; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +import org.switchyard.adapter.config.model.JavaAdapterModel; +import org.switchyard.common.type.Classes; +import org.switchyard.config.model.composite.InterfaceModel; +import org.switchyard.config.model.extensions.adapter.AdapterModel; +import org.switchyard.config.model.switchyard.EsbInterfaceModel; +import org.switchyard.exception.SwitchYardException; +import org.switchyard.extensions.wsdl.WSDLReaderException; +import org.switchyard.extensions.wsdl.WSDLService; +import org.switchyard.metadata.InOnlyOperation; +import org.switchyard.metadata.InOnlyService; +import org.switchyard.metadata.InOutOperation; +import org.switchyard.metadata.InOutService; +import org.switchyard.metadata.ServiceInterface; +import org.switchyard.metadata.ServiceOperation; +import org.switchyard.metadata.java.JavaService; + + +/** + * Utility class to create adapters. + * + * @author Christoph Gostner <christoph.gostner@objectbay.com> © 2013 Objectbay + */ +public final class AdapterUtil { + private AdapterUtil() {} + + /** + * Create a new adapter based on an adapter model. + * @param adapterModel the adapter's model used to create the adapter + * @return instance of an adapter based on the data from the adapter's model + */ + public static Adapter newAdapter(AdapterModel adapterModel) { + if (adapterModel instanceof JavaAdapterModel) { + JavaAdapterModel jAdapterModel = (JavaAdapterModel) adapterModel; + Class clazz = loadClass(jAdapterModel.getClazz()); + if (clazz == null) { + throw new SwitchYardException("Failed to load Adapter class '" + clazz + "'."); + } + return createAdapter(clazz, adapterModel.getInterfaceModel()); + } + return null; + } + + private static ServiceInterface createServiceInterface(InterfaceModel intfModel) { + if (isJavaInterface(intfModel.getType())) { + String interfaceClass = intfModel.getInterface(); + Class serviceInterfaceType = loadClass(interfaceClass); + + if (serviceInterfaceType == null) { + throw new SwitchYardException("Failed to load Service interface class '" + interfaceClass + "'."); + } + return JavaService.fromClass(serviceInterfaceType); + } else if (InterfaceModel.WSDL.equals(intfModel.getType())) { + try { + return WSDLService.fromWSDL(intfModel.getInterface()); + } catch (WSDLReaderException wsdlre) { + throw new SwitchYardException(wsdlre); + } + } else if (EsbInterfaceModel.ESB.equals(intfModel.getType())) { + EsbInterfaceModel esbIntf = (EsbInterfaceModel)intfModel; + validateEsbInterface(esbIntf); + if (esbIntf.getOutputType() == null) { + return new InOnlyService(new InOnlyOperation( + ServiceInterface.DEFAULT_OPERATION, esbIntf.getInputType())); + } else { + return new InOutService(new InOutOperation( + ServiceInterface.DEFAULT_OPERATION, + esbIntf.getInputType(), esbIntf.getOutputType(), esbIntf.getFaultType())); + } + } + throw new SwitchYardException("Failed to create Service interface from model '" + intfModel + "'."); + } + + // Checks for invalid input/output/fault combinations on ESB interfaces. + private static void validateEsbInterface(EsbInterfaceModel esbIntf) { + if (esbIntf.getInputType() == null) { + throw new SwitchYardException("inputType required on ESB interface definition: " + esbIntf); + } + + if (esbIntf.getFaultType() != null && esbIntf.getOutputType() == null) { + throw new SwitchYardException("faultType must be acommpanied by outputType in ESB interface: " + esbIntf); + } + } + + private static boolean isJavaInterface(final String type) { + return InterfaceModel.JAVA.equals(type); + } + + private static Class loadClass(String clazz) { + return Classes.forName(clazz); + } + + private static Method getAdapterMethod(Class clazz) { + if (!isAdapter(clazz)) { + throw new SwitchYardException("Invalid Adapter class '" + clazz + "'."); + } + for (Method publicMethod : clazz.getMethods()) { + if (isAdapterMethod(publicMethod)) { + return publicMethod; + } + } + throw new SwitchYardException("Failed to locate Adapter method in class '" + clazz + "'."); + } + + private static boolean isAdapterMethod(Method publicMethod) { + Class returnType = publicMethod.getReturnType(); + Class[] parameterTypes = publicMethod.getParameterTypes(); + + if (parameterTypes.length != 2) { + return false; + } + return ServiceOperation.class.equals(returnType) && String.class.equals(parameterTypes[0]) && ServiceInterface.class.equals(parameterTypes[1]); + } + + static boolean isAdapter(Class clazz) { + if (clazz.isInterface()) { + return false; + } + if (clazz.isAnnotation()) { + return false; + } + if (Modifier.isAbstract(clazz.getModifiers())) { + return false; + } + try { + // Must have a default constructor... + clazz.getConstructor(); + } catch (NoSuchMethodException e) { + return false; + } + if (org.switchyard.adapter.Adapter.class.isAssignableFrom(clazz)) { + return true; + } + + Method[] publicMethods = clazz.getMethods(); + for (Method publicMethod : publicMethods) { + if (publicMethod.isAnnotationPresent(org.switchyard.annotations.Adapter.class)) { + return true; + } + } + return false; + } + + private static Adapter createAdapter(Class clazz, InterfaceModel interfaceModel) { + ServiceInterface serviceInterface = createServiceInterface(interfaceModel); + Object instance = newInstance(clazz); + Adapter adapter = null; + if (instance instanceof Adapter) { + adapter = (Adapter) instance; + } else { + adapter = createAnnotatedAdapter(instance, interfaceModel); + } + adapter.setServiceInterface(serviceInterface); + return adapter; + } + + private static Object newInstance(Class clazz) { + try { + return clazz.newInstance(); + } catch (Exception e) { + throw new SwitchYardException("Error constructing Adapter instance of type '" + clazz + "'. Class must have a public default constructor.", e); + } + } + + private static Adapter createAnnotatedAdapter(final Object instance, InterfaceModel interfaceModel) { + if (!InterfaceModel.JAVA.equals(interfaceModel.getType())) { + throw new SwitchYardException("Annotated Adapters only supported for Java interfaces: " + interfaceModel + "."); + } + final Method adapterMethod = getAdapterMethod(instance.getClass()); + org.switchyard.annotations.Adapter adapter = adapterMethod.getAnnotation(org.switchyard.annotations.Adapter.class); + if (adapter == null) { + throw new SwitchYardException("Failed to locate Adapter annotation method: " + instance.getClass() + "."); + } + return new BaseAdapter() { + @Override + public ServiceOperation lookup(String consumerOperation, ServiceInterface targetInterface) { + Object[] parameters = new Object[] { + consumerOperation, targetInterface + }; + try { + return (ServiceOperation) adapterMethod.invoke(instance, parameters); + } catch (IllegalAccessException e) { + throw new SwitchYardException("Invokation of adpater method " + adapterMethod + " failed.", e); + } catch (IllegalArgumentException e) { + throw new SwitchYardException("Invokation of adpater method " + adapterMethod + " failed.", e); + } catch (InvocationTargetException e) { + throw new SwitchYardException("Invokation of adpater method " + adapterMethod + " failed.", e); + } + } + }; + } +} diff --git a/adapter/src/main/java/org/switchyard/adapter/config/model/JavaAdapterModel.java b/adapter/src/main/java/org/switchyard/adapter/config/model/JavaAdapterModel.java new file mode 100644 index 000000000..458ab35af --- /dev/null +++ b/adapter/src/main/java/org/switchyard/adapter/config/model/JavaAdapterModel.java @@ -0,0 +1,51 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.switchyard.adapter.config.model; + +import org.switchyard.config.model.extensions.adapter.AdapterModel; + +/** + * A "adapt.java" configuration model. + * + * @author Christoph Gostner <christoph.gostner@objectbay.com> © 2013 Objectbay + */ +public interface JavaAdapterModel extends AdapterModel { + + /** The "java" name. */ + public static final String JAVA = "java"; + + /** The "class" name. */ + public static final String CLASS = "class"; + + /** + * Gets the class attribute. + * + * @return the class attribute + */ + public String getClazz(); + + /** + * Sets the class attribute. + * + * @param clazz the class attribute + * @return this JavaAdaptModel (useful for chaining) + */ + public JavaAdapterModel setClazz(String clazz); + +} diff --git a/adapter/src/main/java/org/switchyard/adapter/config/model/v1/V1AdapterMarshaller.java b/adapter/src/main/java/org/switchyard/adapter/config/model/v1/V1AdapterMarshaller.java new file mode 100644 index 000000000..3f49026bc --- /dev/null +++ b/adapter/src/main/java/org/switchyard/adapter/config/model/v1/V1AdapterMarshaller.java @@ -0,0 +1,59 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.switchyard.adapter.config.model.v1; + +import org.switchyard.adapter.config.model.JavaAdapterModel; +import org.switchyard.config.Configuration; +import org.switchyard.config.model.BaseMarshaller; +import org.switchyard.config.model.Descriptor; +import org.switchyard.config.model.Model; +import org.switchyard.config.model.extensions.adapter.AdapterModel; + +/** + * Marshalls adapter Models. + * + * @author Christoph Gostner <christoph.gostner@objectbay.com> © 2013 Objectbay + */ +public class V1AdapterMarshaller extends BaseMarshaller { + + private static final String ADAPTER_JAVA = AdapterModel.ADAPTER + "." + JavaAdapterModel.JAVA; + + /** + * Constructs a new V1AdapterMarshaller with the specified Descriptor. + * + * @param desc the Descriptor + */ + protected V1AdapterMarshaller(Descriptor desc) { + super(desc); + } + + /** + * {@inheritDoc} + */ + @Override + public Model read(Configuration config) { + String name = config.getName(); + Descriptor desc = getDescriptor(); + + if (name.equals(ADAPTER_JAVA)) { + return new V1JavaAdapterModel(config, desc); + } + return null; + } +} diff --git a/adapter/src/main/java/org/switchyard/adapter/config/model/v1/V1JavaAdapterModel.java b/adapter/src/main/java/org/switchyard/adapter/config/model/v1/V1JavaAdapterModel.java new file mode 100644 index 000000000..3bd904c39 --- /dev/null +++ b/adapter/src/main/java/org/switchyard/adapter/config/model/v1/V1JavaAdapterModel.java @@ -0,0 +1,69 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.switchyard.adapter.config.model.v1; + +import javax.xml.namespace.QName; + +import org.switchyard.adapter.config.model.JavaAdapterModel; +import org.switchyard.config.Configuration; +import org.switchyard.config.model.Descriptor; +import org.switchyard.config.model.extensions.adapter.AdapterModel; +import org.switchyard.config.model.extensions.adapter.v1.V1BaseAdaptModel; + +/** + * A version 1 JavaAdaptModel. + * + * @author Christoph Gostner <christoph.gostner@objectbay.com> © 2013 Objectbay + */ +public class V1JavaAdapterModel extends V1BaseAdaptModel implements JavaAdapterModel { + + /** + * Constructs a new V1JavaAdaptModel. + */ + public V1JavaAdapterModel() { + super(new QName(AdapterModel.DEFAULT_NAMESPACE, AdapterModel.ADAPTER + '.' + JAVA)); + } + + /** + * Constructs a new V1JavaAdaptModel with the specified Configuration and Descriptor. + * + * @param config the Configuration + * @param desc the Descriptor + */ + public V1JavaAdapterModel(Configuration config, Descriptor desc) { + super(config, desc); + } + + /** + * {@inheritDoc} + */ + @Override + public String getClazz() { + return getModelAttribute(CLASS); + } + + /** + * {@inheritDoc} + */ + @Override + public JavaAdapterModel setClazz(String clazz) { + setModelAttribute(CLASS, clazz); + return this; + } +} diff --git a/adapter/src/main/resources/org/switchyard/adapter/config/model/v1/adapter-v1.xsd b/adapter/src/main/resources/org/switchyard/adapter/config/model/v1/adapter-v1.xsd new file mode 100644 index 000000000..dfd498e35 --- /dev/null +++ b/adapter/src/main/resources/org/switchyard/adapter/config/model/v1/adapter-v1.xsd @@ -0,0 +1,49 @@ + + + + + + + + + + + Generic/Custom Java Adapter Configuration. + + + + + + + + The name of the Java Adapter implementation class. + + + + + + + + + diff --git a/adapter/src/main/resources/org/switchyard/config/model/descriptor.properties b/adapter/src/main/resources/org/switchyard/config/model/descriptor.properties new file mode 100644 index 000000000..b45a868a5 --- /dev/null +++ b/adapter/src/main/resources/org/switchyard/config/model/descriptor.properties @@ -0,0 +1,21 @@ +# JBoss, Home of Professional Open Source +# Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors +# as indicated by the @authors tag. All rights reserved. +# See the copyright.txt in the distribution for a +# full listing of individual contributors. +# +# This copyrighted material is made available to anyone wishing to use, +# modify, copy, or redistribute it subject to the terms and conditions +# of the GNU Lesser General Public License, v. 2.1. +# This program is distributed in the hope that it will be useful, but WITHOUT A +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +# You should have received a copy of the GNU Lesser General Public License, +# v.2.1 along with this distribution; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. + +adpt1.namespace=urn\:switchyard-config\:adapter\:1.0 +adpt1.schema=adapter-v1.xsd +adpt1.location=/org/switchyard/adapter/config/model/v1/ +adpt1.marshaller=org.switchyard.adapter.config.model.v1.V1AdapterMarshaller diff --git a/adapter/src/test/java/org/switchyard/adapter/AdapterUtilTest.java b/adapter/src/test/java/org/switchyard/adapter/AdapterUtilTest.java new file mode 100644 index 000000000..4d7ec091b --- /dev/null +++ b/adapter/src/test/java/org/switchyard/adapter/AdapterUtilTest.java @@ -0,0 +1,81 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @authors tag. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.switchyard.adapter; + +import static org.junit.Assert.*; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.switchyard.adapter.config.model.adapters.AnnoV1toV2Adapter; +import org.switchyard.adapter.config.model.adapters.MockServiceContract; +import org.switchyard.adapter.config.model.adapters.NoAnnotationAdapter; +import org.switchyard.adapter.config.model.adapters.V1toV2Adapter; +import org.switchyard.adapter.config.model.v1.V1JavaAdapterModel; +import org.switchyard.config.model.composite.InterfaceModel; +import org.switchyard.config.model.composite.v1.V1InterfaceModel; +import org.switchyard.exception.SwitchYardException; + + +/** + * @author Christoph Gostner <christoph.gostner@objectbay.com> © 2013 Objectbay + */ +public class AdapterUtilTest { + + private V1JavaAdapterModel model; + + @Before + public void before() { + model = new V1JavaAdapterModel(); + InterfaceModel interfaceModel = new V1InterfaceModel(InterfaceModel.JAVA); + interfaceModel.setInterface(MockServiceContract.class.getName()); + model.setInterfaceModel(interfaceModel); + } + + @Test + public void testAnnotationBasedAdapter() { + model.setClazz(AnnoV1toV2Adapter.class.getName()); + + Adapter adapter = AdapterUtil.newAdapter(model); + assertNotNull(adapter); + assertNotNull(adapter.getServiceInterface()); + } + + @Test + public void testImplementationBasedAdapter() { + model.setClazz(V1toV2Adapter.class.getName()); + + Adapter adapter = AdapterUtil.newAdapter(model); + assertNotNull(adapter); + assertEquals(V1toV2Adapter.class, adapter.getClass()); + assertNotNull(adapter.getServiceInterface()); + } + + @Test + public void testNoAnnotationFoundAdapter() { + model.setClazz(NoAnnotationAdapter.class.getName()); + + try { + AdapterUtil.newAdapter(model); + fail(); + } catch (SwitchYardException e) { + Assert.assertEquals("Invalid Adapter class 'class org.switchyard.adapter.config.model.adapters.NoAnnotationAdapter'.", e.getMessage()); + } + } +} diff --git a/adapter/src/test/java/org/switchyard/adapter/config/model/AdapterModelTests.java b/adapter/src/test/java/org/switchyard/adapter/config/model/AdapterModelTests.java new file mode 100644 index 000000000..f83f96734 --- /dev/null +++ b/adapter/src/test/java/org/switchyard/adapter/config/model/AdapterModelTests.java @@ -0,0 +1,126 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.switchyard.adapter.config.model; + +import java.io.StringReader; +import java.util.List; + +import javax.xml.namespace.QName; + +import org.custommonkey.xmlunit.Diff; +import org.custommonkey.xmlunit.XMLUnit; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.switchyard.adapter.config.model.adapters.V1toV2Adapter; +import org.switchyard.adapter.config.model.v1.V1JavaAdapterModel; +import org.switchyard.common.io.pull.StringPuller; +import org.switchyard.common.xml.XMLHelper; +import org.switchyard.config.model.Model; +import org.switchyard.config.model.ModelPuller; +import org.switchyard.config.model.composite.CompositeServiceModel; +import org.switchyard.config.model.composite.InterfaceModel; +import org.switchyard.config.model.composite.v1.V1InterfaceModel; +import org.switchyard.config.model.extensions.ExtensionsModel; +import org.switchyard.config.model.extensions.adapter.AdapterModel; +import org.switchyard.config.model.extensions.v1.V1ExtensionsModel; +import org.switchyard.config.model.switchyard.SwitchYardModel; + +/** + * @author Christoph Gostner <christoph.gostner@objectbay.com> © 2013 Objectbay + */ +public class AdapterModelTests { + + private static final String XML = "/org/switchyard/adapter/config/model/AdapterModelTests.xml"; + private static final String CREATE_XML = "/org/switchyard/adapter/config/model/CreateAdapterModelTests.xml"; + + private ModelPuller _puller; + + @Before + public void before() throws Exception { + _puller = new ModelPuller(); + } + + @Test + public void testCreateInvalidEmptyModel() throws Exception { + String namespace = AdapterModel.DEFAULT_NAMESPACE; + String name = AdapterModel.ADAPTER + '.' + JavaAdapterModel.JAVA; + Model model = new ModelPuller().pull(XMLHelper.createQName(namespace, name)); + Assert.assertTrue(model instanceof JavaAdapterModel); + Assert.assertEquals(name, model.getModelConfiguration().getName()); + Assert.assertEquals(new QName(namespace, name), model.getModelConfiguration().getQName()); + Assert.assertFalse(model.isModelValid()); + } + + @Test + public void testCreate() throws Exception { + SwitchYardModel switchyard = _puller.pull(CREATE_XML, getClass()); + Assert.assertTrue(switchyard.isModelValid()); + + InterfaceModel interfaceModel = new V1InterfaceModel(InterfaceModel.JAVA); + interfaceModel.setInterface("org.switchyard.adapter.config.model.ServiceContractV1"); + JavaAdapterModel javaAdapter = new V1JavaAdapterModel(); + javaAdapter.setInterfaceModel(interfaceModel); + javaAdapter.setClazz(V1toV2Adapter.class.getName()); + ExtensionsModel extensionsModel = new V1ExtensionsModel(); + extensionsModel.setAdapterModel(javaAdapter); + switchyard.getComposite().getServices().get(0).setExtensions(extensionsModel); + + String new_xml = switchyard.toString(); + String old_xml = new ModelPuller().pull(XML, getClass()).toString(); + XMLUnit.setIgnoreWhitespace(true); + Diff diff = XMLUnit.compareXML(old_xml, new_xml); + Assert.assertTrue(diff.toString(), diff.identical()); + } + + @Test + public void testRead() throws Exception { + SwitchYardModel switchyard = _puller.pull(XML, getClass()); + List serviceModels = switchyard.getComposite().getServices(); + Assert.assertEquals(1, serviceModels.size()); + + CompositeServiceModel compositeServiceModel = serviceModels.get(0); + ExtensionsModel extensionsModel = compositeServiceModel.getExtensionsModel(); + Assert.assertNotNull(extensionsModel); + AdapterModel adapterModel = extensionsModel.getAdapterModel(); + Assert.assertNotNull(adapterModel); + Assert.assertTrue(adapterModel instanceof JavaAdapterModel); + InterfaceModel interfaceModel = adapterModel.getInterfaceModel(); + Assert.assertEquals(InterfaceModel.JAVA, interfaceModel.getType()); + Assert.assertEquals("org.switchyard.adapter.config.model.ServiceContractV1", interfaceModel.getInterface()); + JavaAdapterModel javaAdapterModel = (JavaAdapterModel) adapterModel; + Assert.assertEquals(V1toV2Adapter.class.getName(), javaAdapterModel.getClazz()); + } + + @Test + public void testWrite() throws Exception { + String old_xml = new StringPuller().pull(XML, getClass()); + SwitchYardModel switchyard = _puller.pull(new StringReader(old_xml)); + String new_xml = switchyard.toString(); + XMLUnit.setIgnoreWhitespace(true); + Diff diff = XMLUnit.compareXML(old_xml, new_xml); + Assert.assertTrue(diff.toString(), diff.identical()); + } + + @Test + public void testValidation() throws Exception { + SwitchYardModel switchyard = _puller.pull(XML, getClass()); + switchyard.assertModelValid(); + } +} diff --git a/adapter/src/test/java/org/switchyard/adapter/config/model/AdapterSwitchYardScannerTest.java b/adapter/src/test/java/org/switchyard/adapter/config/model/AdapterSwitchYardScannerTest.java new file mode 100644 index 000000000..10d057d37 --- /dev/null +++ b/adapter/src/test/java/org/switchyard/adapter/config/model/AdapterSwitchYardScannerTest.java @@ -0,0 +1,71 @@ +///* +// * JBoss, Home of Professional Open Source +// * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors +// * as indicated by the @author tags. All rights reserved. +// * See the copyright.txt in the distribution for a +// * full listing of individual contributors. +// * +// * This copyrighted material is made available to anyone wishing to use, +// * modify, copy, or redistribute it subject to the terms and conditions +// * of the GNU Lesser General Public License, v. 2.1. +// * This program is distributed in the hope that it will be useful, but WITHOUT A +// * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// * You should have received a copy of the GNU Lesser General Public License, +// * v.2.1 along with this distribution; if not, write to the Free Software +// * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +// * MA 02110-1301, USA. +// */ +//package org.switchyard.adapter.config.model; +// +//import java.io.File; +//import java.io.IOException; +//import java.net.MalformedURLException; +//import java.net.URL; +//import java.util.ArrayList; +//import java.util.List; +// +//import org.junit.Assert; +//import org.junit.Before; +//import org.junit.Test; +//import org.switchyard.adapter.config.model.adapters.AnnoV1toV2Adapter; +//import org.switchyard.config.model.ScannerInput; +//import org.switchyard.config.model.switchyard.SwitchYardModel; +//import org.switchyard.exception.DuplicateAdapterException; +// +///** +// * @author Christoph Gostner <christoph.gostner@objectbay.com> © 2013 Objectbay +// */ +//public class AdapterSwitchYardScannerTest { +// +// private AdapterSwitchYardScanner scanner; +// private ArrayList testUrls; +// +// @Before +// public void setUp() throws MalformedURLException { +// this.scanner = new AdapterSwitchYardScanner(); +// +// testUrls = new ArrayList(); +// // If running this test inside your IDE... you need to set the cwd to be the +// // root of the transform module !! +// testUrls.add(new File("./target/test-classes").toURI().toURL()); +// } +// +// @Test +// public void testAnnotatedAdapter() { +// List adapterTypes = scanner.adapterTypesFromAdapterAnnotation(AnnoV1toV2Adapter.class); +// +// Assert.assertEquals(2, adapterTypes.size()); +// } +// +// @Test +// public void testScanDuplicateAdapters() throws IOException { +// ScannerInput input = new ScannerInput().setURLs(testUrls); +// try { +// scanner.scan(input).getModel(); +// Assert.fail(); +// } catch (DuplicateAdapterException e) { +// Assert.assertEquals("An Adapter for the service is already registered: '{urn:org.switchyard.adapter.config.model}TestServiceV1'.", e.getMessage()); +// } +// } +//} diff --git a/adapter/src/test/java/org/switchyard/adapter/config/model/adapters/AnnoV1toV2Adapter.java b/adapter/src/test/java/org/switchyard/adapter/config/model/adapters/AnnoV1toV2Adapter.java new file mode 100644 index 000000000..326051af4 --- /dev/null +++ b/adapter/src/test/java/org/switchyard/adapter/config/model/adapters/AnnoV1toV2Adapter.java @@ -0,0 +1,37 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.switchyard.adapter.config.model.adapters; + +import org.switchyard.ExchangePattern; +import org.switchyard.annotations.Adapter; +import org.switchyard.metadata.BaseServiceOperation; +import org.switchyard.metadata.ServiceInterface; +import org.switchyard.metadata.ServiceOperation; +import org.switchyard.metadata.java.JavaService; + +/** + * @author Christoph Gostner <christoph.gostner@objectbay.com> © 2013 Objectbay + */ +public class AnnoV1toV2Adapter { + + @Adapter(contract = MockServiceContract.class) + public ServiceOperation lookup(String consumerOperation, ServiceInterface targetInterface) { + return new BaseServiceOperation(ExchangePattern.IN_ONLY, "test", JavaService.toMessageType(Void.class), JavaService.toMessageType(String.class), null); + } +} diff --git a/adapter/src/test/java/org/switchyard/adapter/config/model/adapters/MockServiceContract.java b/adapter/src/test/java/org/switchyard/adapter/config/model/adapters/MockServiceContract.java new file mode 100644 index 000000000..809356c7e --- /dev/null +++ b/adapter/src/test/java/org/switchyard/adapter/config/model/adapters/MockServiceContract.java @@ -0,0 +1,5 @@ +package org.switchyard.adapter.config.model.adapters; + +public interface MockServiceContract { + +} diff --git a/adapter/src/test/java/org/switchyard/adapter/config/model/adapters/NoAnnotationAdapter.java b/adapter/src/test/java/org/switchyard/adapter/config/model/adapters/NoAnnotationAdapter.java new file mode 100644 index 000000000..70033a043 --- /dev/null +++ b/adapter/src/test/java/org/switchyard/adapter/config/model/adapters/NoAnnotationAdapter.java @@ -0,0 +1,13 @@ +package org.switchyard.adapter.config.model.adapters; + +import org.switchyard.ExchangePattern; +import org.switchyard.metadata.BaseServiceOperation; +import org.switchyard.metadata.ServiceInterface; +import org.switchyard.metadata.ServiceOperation; +import org.switchyard.metadata.java.JavaService; + +public class NoAnnotationAdapter { + public ServiceOperation lookup(String consumerOperation, ServiceInterface targetInterface) { + return new BaseServiceOperation(ExchangePattern.IN_ONLY, "test", JavaService.toMessageType(Void.class), JavaService.toMessageType(String.class), null); + } +} diff --git a/adapter/src/test/java/org/switchyard/adapter/config/model/adapters/V1toV2Adapter.java b/adapter/src/test/java/org/switchyard/adapter/config/model/adapters/V1toV2Adapter.java new file mode 100644 index 000000000..8b12dd521 --- /dev/null +++ b/adapter/src/test/java/org/switchyard/adapter/config/model/adapters/V1toV2Adapter.java @@ -0,0 +1,34 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.switchyard.adapter.config.model.adapters; + +import org.switchyard.adapter.BaseAdapter; +import org.switchyard.metadata.ServiceInterface; +import org.switchyard.metadata.ServiceOperation; + +/** + * @author Christoph Gostner <christoph.gostner@objectbay.com> © 2013 Objectbay + */ +public class V1toV2Adapter extends BaseAdapter { + + @Override + public ServiceOperation lookup(String consumerOperation, ServiceInterface targetInterface) { + return null; + } +} diff --git a/adapter/src/test/resources/META-INF/beans.xml b/adapter/src/test/resources/META-INF/beans.xml new file mode 100644 index 000000000..e69de29bb diff --git a/adapter/src/test/resources/org/switchyard/adapter/config/model/AdapterModelTests.xml b/adapter/src/test/resources/org/switchyard/adapter/config/model/AdapterModelTests.xml new file mode 100644 index 000000000..381d6d68f --- /dev/null +++ b/adapter/src/test/resources/org/switchyard/adapter/config/model/AdapterModelTests.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/adapter/src/test/resources/org/switchyard/adapter/config/model/CreateAdapterModelTests.xml b/adapter/src/test/resources/org/switchyard/adapter/config/model/CreateAdapterModelTests.xml new file mode 100644 index 000000000..cc7819cbf --- /dev/null +++ b/adapter/src/test/resources/org/switchyard/adapter/config/model/CreateAdapterModelTests.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + diff --git a/api/src/main/java/org/switchyard/Service.java b/api/src/main/java/org/switchyard/Service.java index 586a3fa49..300981fe2 100644 --- a/api/src/main/java/org/switchyard/Service.java +++ b/api/src/main/java/org/switchyard/Service.java @@ -23,6 +23,7 @@ import javax.xml.namespace.QName; +import org.switchyard.adapter.Adapter; import org.switchyard.metadata.Registrant; import org.switchyard.metadata.ServiceInterface; import org.switchyard.policy.Policy; @@ -72,4 +73,24 @@ public interface Service { * @return provider metadata */ Registrant getProviderMetadata(); + + /** + * Indicates if an adapter is available. + * @see Adapter + * @return true if an adapter is available, otherwise false + */ + boolean hasAdapter(); + + /** + * Set the adapter for the service. + * @param adapter the adapter to set + * @return this Service (useful for chaining) + */ + Service setAdapter(Adapter adapter); + + /** + * Get the adapter registered for the service. + * @return The adapter registered for the service + */ + Adapter getAdapter(); } diff --git a/api/src/main/java/org/switchyard/ServiceDomain.java b/api/src/main/java/org/switchyard/ServiceDomain.java index 35c49d215..939fce8ea 100644 --- a/api/src/main/java/org/switchyard/ServiceDomain.java +++ b/api/src/main/java/org/switchyard/ServiceDomain.java @@ -38,7 +38,7 @@ * resources, configuration, and policy definitions. The ServiceDomain * interface is used by software components to provide and/or consume * services. These software components include protocol gateways, service - * containers, translation engines, adapters, orchestration and routing + * containers, translation engines, orchestration and routing * engines. */ public interface ServiceDomain { diff --git a/api/src/main/java/org/switchyard/adapter/Adapter.java b/api/src/main/java/org/switchyard/adapter/Adapter.java new file mode 100644 index 000000000..65dc478a0 --- /dev/null +++ b/api/src/main/java/org/switchyard/adapter/Adapter.java @@ -0,0 +1,52 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.switchyard.adapter; + +import org.switchyard.metadata.ServiceInterface; +import org.switchyard.metadata.ServiceOperation; + +/** + * Handles changes (operation names) between service interfaces/contracts. + * Adapters are directly attached to a composite service. + * + * @author Christoph Gostner <christoph.gostner@objectbay.com> © 2013 Objectbay + */ +public interface Adapter { + + /** + * Set the service interface to adapt. + * @param serviceInterface service interface to adapts + * @return this Adapter (useful for chaining) + */ + public Adapter setServiceInterface(ServiceInterface serviceInterface); + + /** + * Get the adapted service interface. + * @return the adapted service interface + */ + public ServiceInterface getServiceInterface(); + + /** + * Lookup for a service operation in the targetInterface. + * @param consumerOperation The operation's name invoked by the consumer + * @param targetInterface The interface containing all available service operation + * @return service operation selected out of the target interface based on the cunsumerOperation. + */ + public ServiceOperation lookup(String consumerOperation, ServiceInterface targetInterface); +} diff --git a/api/src/main/java/org/switchyard/adapter/BaseAdapter.java b/api/src/main/java/org/switchyard/adapter/BaseAdapter.java new file mode 100644 index 000000000..efd94d513 --- /dev/null +++ b/api/src/main/java/org/switchyard/adapter/BaseAdapter.java @@ -0,0 +1,41 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.switchyard.adapter; + +import org.switchyard.metadata.ServiceInterface; + +/** + * Base adapter implementation. + * + * @author Christoph Gostner <christoph.gostner@objectbay.com> © 2013 Objectbay + */ +public abstract class BaseAdapter implements Adapter { + private ServiceInterface _serviceInterface; + + @Override + public Adapter setServiceInterface(ServiceInterface serviceInterface) { + _serviceInterface = serviceInterface; + return this; + } + + @Override + public ServiceInterface getServiceInterface() { + return _serviceInterface; + } +} diff --git a/api/src/main/java/org/switchyard/annotations/Adapter.java b/api/src/main/java/org/switchyard/annotations/Adapter.java new file mode 100644 index 000000000..ef1f7523d --- /dev/null +++ b/api/src/main/java/org/switchyard/annotations/Adapter.java @@ -0,0 +1,39 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @authors tag. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.switchyard.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * @author Christoph Gostner <christoph.gostner@objectbay.com> © 2013 Objectbay + */ +@Target({METHOD }) +@Retention(RUNTIME) +@Documented +public @interface Adapter { + /** + * Adapted service contract. + */ + Class contract(); +} diff --git a/api/src/main/java/org/switchyard/exception/DuplicateAdapterException.java b/api/src/main/java/org/switchyard/exception/DuplicateAdapterException.java new file mode 100644 index 000000000..dbbc202e7 --- /dev/null +++ b/api/src/main/java/org/switchyard/exception/DuplicateAdapterException.java @@ -0,0 +1,49 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @authors tag. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.switchyard.exception; + +/** + * A DuplicateAdapterException is thrown by SwitchYard when a duplicate adapter + * is trying to be registered for a 'from' server for which there already exists + * an adapter in the adapter registry. + * + * @author Christoph Gostner <christoph.gostner@objectbay.com> © 2013 Objectbay + */ +public class DuplicateAdapterException extends SwitchYardException { + private static final long serialVersionUID = 3368823467745672974L; + + /** + * Public constructor. + * + * @param message Exception message. + */ + public DuplicateAdapterException(final String message) { + super(message); + } + + /** + * Public constructor. + * + * @param message Exception message. + * @param cause Throwable cause. + */ + public DuplicateAdapterException(final String message, final Throwable cause) { + super(message, cause); + } +} diff --git a/bus/camel/src/test/java/org/switchyard/bus/camel/MockService.java b/bus/camel/src/test/java/org/switchyard/bus/camel/MockService.java index fc96111cb..75d3d599c 100644 --- a/bus/camel/src/test/java/org/switchyard/bus/camel/MockService.java +++ b/bus/camel/src/test/java/org/switchyard/bus/camel/MockService.java @@ -26,6 +26,7 @@ import org.switchyard.ExchangeHandler; import org.switchyard.Service; import org.switchyard.ServiceDomain; +import org.switchyard.adapter.Adapter; import org.switchyard.metadata.InOnlyService; import org.switchyard.metadata.Registrant; import org.switchyard.metadata.ServiceInterface; @@ -36,6 +37,7 @@ public class MockService implements Service { private QName _serviceName; private ServiceInterface _serviceInterface; private ExchangeHandler _handler; + private Adapter _adapter; public MockService(QName serviceName, ExchangeHandler handler) { this(serviceName, new InOnlyService(), handler); @@ -76,6 +78,21 @@ public List getRequiredPolicies() { public ExchangeHandler getProviderHandler() { return _handler; } + + @Override + public Service setAdapter(Adapter adapter) { + _adapter = adapter; + return this; + } + + public Adapter getAdapter() { + return _adapter; + } + + @Override + public boolean hasAdapter() { + return _adapter != null; + } @Override public Registrant getProviderMetadata() { diff --git a/config/src/main/java/org/switchyard/config/model/composite/CompositeServiceModel.java b/config/src/main/java/org/switchyard/config/model/composite/CompositeServiceModel.java index 71812dfc1..cb1b4753f 100644 --- a/config/src/main/java/org/switchyard/config/model/composite/CompositeServiceModel.java +++ b/config/src/main/java/org/switchyard/config/model/composite/CompositeServiceModel.java @@ -21,6 +21,7 @@ import java.util.List; import org.switchyard.config.model.NamedModel; +import org.switchyard.config.model.extensions.ExtensionsModel; /** * The "composite/service" model. @@ -52,7 +53,13 @@ public interface CompositeServiceModel extends NamedModel { * @return the child component service model */ public ComponentServiceModel getComponentService(); - + + /** + * Gets the child extensions model. + * @return the child extensions model + */ + public ExtensionsModel getExtensionsModel(); + /** * Gets the promote attribute. * @return the promote attribute @@ -91,5 +98,18 @@ public interface CompositeServiceModel extends NamedModel { * @return this CompositeServiceModel (useful for chaining) */ public CompositeServiceModel setInterface(InterfaceModel interfaze); + + /** + * Set the child extensions model. + * @param extensionsModel child extensions model + * @return this this CompositeServiceModel (useful for chaining) + */ + public CompositeServiceModel setExtensions(ExtensionsModel extensionsModel); + + /** + * Indicates if a service extension is available. + * @return true if a service extension is available, otherwise false + */ + public boolean hasExtensionsModel(); } diff --git a/config/src/main/java/org/switchyard/config/model/composite/v1/V1CompositeMarshaller.java b/config/src/main/java/org/switchyard/config/model/composite/v1/V1CompositeMarshaller.java index 3e9f2da75..5198a9ef9 100644 --- a/config/src/main/java/org/switchyard/config/model/composite/v1/V1CompositeMarshaller.java +++ b/config/src/main/java/org/switchyard/config/model/composite/v1/V1CompositeMarshaller.java @@ -31,6 +31,8 @@ import org.switchyard.config.model.composite.CompositeServiceModel; import org.switchyard.config.model.composite.InterfaceModel; import org.switchyard.config.model.composite.SCABindingModel; +import org.switchyard.config.model.extensions.ExtensionsModel; +import org.switchyard.config.model.extensions.v1.V1ExtensionsModel; import org.switchyard.config.model.property.PropertyModel; import org.switchyard.config.model.property.v1.V1PropertyModel; @@ -96,6 +98,8 @@ public Model read(Configuration config) { } } else if (name.equals(PropertyModel.PROPERTY)) { return new V1PropertyModel(config,desc); + } else if (name.equals(ExtensionsModel.EXTENSIONS)) { + return new V1ExtensionsModel(config, desc); } return null; diff --git a/config/src/main/java/org/switchyard/config/model/composite/v1/V1CompositeServiceModel.java b/config/src/main/java/org/switchyard/config/model/composite/v1/V1CompositeServiceModel.java index 016c5f537..69db62843 100644 --- a/config/src/main/java/org/switchyard/config/model/composite/v1/V1CompositeServiceModel.java +++ b/config/src/main/java/org/switchyard/config/model/composite/v1/V1CompositeServiceModel.java @@ -36,6 +36,7 @@ import org.switchyard.config.model.composite.CompositeModel; import org.switchyard.config.model.composite.CompositeServiceModel; import org.switchyard.config.model.composite.InterfaceModel; +import org.switchyard.config.model.extensions.ExtensionsModel; /** * A version 1 CompositeServiceModel. @@ -48,6 +49,7 @@ public class V1CompositeServiceModel extends BaseNamedModel implements Composite private List _bindings = new ArrayList(); private InterfaceModel _interface; + private ExtensionsModel _extensionsModel; /** * Constructs a new V1CompositeServiceModel. @@ -69,6 +71,20 @@ public V1CompositeServiceModel(Configuration config, Descriptor desc) { _bindings.add(binding); } } + List configs = config.getChildren(ExtensionsModel.EXTENSIONS); + for (Configuration extensions_config : configs) { + ExtensionsModel extensionsModel = (ExtensionsModel) readModel(extensions_config); + if (extensionsModel != null) { + _extensionsModel = extensionsModel; + break; + } + } + + } + + @Override + public ExtensionsModel getExtensionsModel() { + return _extensionsModel; } /** @@ -192,4 +208,16 @@ public CompositeServiceModel setInterface(InterfaceModel interfaze) { _interface = interfaze; return this; } + + @Override + public CompositeServiceModel setExtensions(ExtensionsModel extensionsModel) { + setChildModel(extensionsModel); + _extensionsModel = extensionsModel; + return this; + } + + @Override + public boolean hasExtensionsModel() { + return _extensionsModel != null; + } } diff --git a/config/src/main/java/org/switchyard/config/model/extensions/ExtensionsModel.java b/config/src/main/java/org/switchyard/config/model/extensions/ExtensionsModel.java new file mode 100644 index 000000000..f1c941a74 --- /dev/null +++ b/config/src/main/java/org/switchyard/config/model/extensions/ExtensionsModel.java @@ -0,0 +1,53 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.switchyard.config.model.extensions; + +import org.switchyard.config.model.TypedModel; +import org.switchyard.config.model.extensions.adapter.AdapterModel; + +/** + * The "composite/service/extensions" model. + * + * @author Christoph Gostner <christoph.gostner@objectbay.com> © 2013 Objectbay + */ +public interface ExtensionsModel extends TypedModel { + + /** The "extensions" name. */ + public static final String EXTENSIONS = "extensions"; + + /** + * Gets the child adapter model. + * + * @return the child adapter model + */ + public AdapterModel getAdapterModel(); + + /** + * Set the child adapter model. + * @param adapterModel child adapter model + * @return this ExtensionsModel (useful for chaining) + */ + public ExtensionsModel setAdapterModel(AdapterModel adapterModel); + + /** + * Indicates if an adapter model is present. + * @return true if an adapter model is present, otherwise false + */ + public boolean hasAdapterModel(); +} diff --git a/config/src/main/java/org/switchyard/config/model/extensions/adapter/AdapterModel.java b/config/src/main/java/org/switchyard/config/model/extensions/adapter/AdapterModel.java new file mode 100644 index 000000000..c1dca97be --- /dev/null +++ b/config/src/main/java/org/switchyard/config/model/extensions/adapter/AdapterModel.java @@ -0,0 +1,49 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.switchyard.config.model.extensions.adapter; + +import org.switchyard.config.model.TypedModel; +import org.switchyard.config.model.composite.InterfaceModel; + +/** + * The adapter model. + * + * @author Christoph Gostner <christoph.gostner@objectbay.com> © 2013 Objectbay + */ +public interface AdapterModel extends TypedModel { + + /** The default "adapter" namespace. */ + public static final String DEFAULT_NAMESPACE = "urn:switchyard-config:adapter:1.0"; + + /** The "adapter" name. */ + public static final String ADAPTER = "adapter"; + + /** + * Get the child interface model. + * @return child interface model + */ + public InterfaceModel getInterfaceModel(); + + /** + * Set the child interface model. + * @param interfaceModel child interface model + * @return this AdapterModel (useful for chaining) + */ + public AdapterModel setInterfaceModel(InterfaceModel interfaceModel); +} diff --git a/config/src/main/java/org/switchyard/config/model/extensions/adapter/v1/V1BaseAdaptModel.java b/config/src/main/java/org/switchyard/config/model/extensions/adapter/v1/V1BaseAdaptModel.java new file mode 100644 index 000000000..5cdd0dad6 --- /dev/null +++ b/config/src/main/java/org/switchyard/config/model/extensions/adapter/v1/V1BaseAdaptModel.java @@ -0,0 +1,72 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.switchyard.config.model.extensions.adapter.v1; + +import javax.xml.namespace.QName; + +import org.switchyard.config.Configuration; +import org.switchyard.config.model.BaseTypedModel; +import org.switchyard.config.model.Descriptor; +import org.switchyard.config.model.composite.InterfaceModel; +import org.switchyard.config.model.extensions.adapter.AdapterModel; +import org.switchyard.config.model.switchyard.SwitchYardModel; + +/** + * Basic adapter model. + * + * @author Christoph Gostner <christoph.gostner@objectbay.com> © 2013 Objectbay + */ +public abstract class V1BaseAdaptModel extends BaseTypedModel implements AdapterModel { + + protected static final String INTERFACE = "interface"; + private InterfaceModel _interfaceModel; + + protected V1BaseAdaptModel(String type) { + this(new QName(SwitchYardModel.DEFAULT_NAMESPACE, AdapterModel.ADAPTER + '.' + type)); + } + + protected V1BaseAdaptModel(QName qname) { + super(qname); + } + + protected V1BaseAdaptModel(Configuration config, Descriptor desc) { + super(config, desc); + + // only one interface is supported + for (Configuration adater_config : config.getChildrenStartsWith(InterfaceModel.INTERFACE)) { + InterfaceModel interfaceModel = (InterfaceModel)readModel(adater_config); + if (interfaceModel != null) { + _interfaceModel = interfaceModel; + break; + } + } + } + + @Override + public InterfaceModel getInterfaceModel() { + return _interfaceModel; + } + + @Override + public AdapterModel setInterfaceModel(InterfaceModel interfaceModel) { + setChildModel(interfaceModel); + _interfaceModel = interfaceModel; + return this; + } +} diff --git a/config/src/main/java/org/switchyard/config/model/extensions/v1/V1ExtensionsModel.java b/config/src/main/java/org/switchyard/config/model/extensions/v1/V1ExtensionsModel.java new file mode 100644 index 000000000..bdafed8d0 --- /dev/null +++ b/config/src/main/java/org/switchyard/config/model/extensions/v1/V1ExtensionsModel.java @@ -0,0 +1,81 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors + * as indicated by the @author tags. All rights reserved. + * See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This copyrighted material is made available to anyone wishing to use, + * modify, copy, or redistribute it subject to the terms and conditions + * of the GNU Lesser General Public License, v. 2.1. + * This program is distributed in the hope that it will be useful, but WITHOUT A + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. + * You should have received a copy of the GNU Lesser General Public License, + * v.2.1 along with this distribution; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +package org.switchyard.config.model.extensions.v1; + +import javax.xml.namespace.QName; + +import org.switchyard.config.Configuration; +import org.switchyard.config.model.BaseNamedModel; +import org.switchyard.config.model.Descriptor; +import org.switchyard.config.model.extensions.ExtensionsModel; +import org.switchyard.config.model.extensions.adapter.AdapterModel; + +/** + * V1 Extensions model. + * + * @author Christoph Gostner <christoph.gostner@objectbay.com> © 2013 Objectbay + */ +public class V1ExtensionsModel extends BaseNamedModel implements ExtensionsModel { + + private AdapterModel _adapterModel; + + + /** + * Creates a new ExtensionsModel with the specified configuration and descriptor. + * @param config the configuration + * @param desc the descriptor + */ + public V1ExtensionsModel(Configuration config, Descriptor desc) { + super(config, desc); + + // only one adapter is supported + for (Configuration adater_config : config.getChildrenStartsWith(AdapterModel.ADAPTER)) { + _adapterModel = (AdapterModel)readModel(adater_config); + if (_adapterModel != null) { + break; + } + } + } + + public V1ExtensionsModel() { + super(new QName(ExtensionsModel.EXTENSIONS)); + } + + @Override + public String getType() { + return EXTENSIONS; + } + + @Override + public AdapterModel getAdapterModel() { + return _adapterModel; + } + + @Override + public ExtensionsModel setAdapterModel(AdapterModel adapterModel) { + setChildModel(adapterModel); + _adapterModel = adapterModel; + return this; + } + + @Override + public boolean hasAdapterModel() { + return _adapterModel != null; + } +} diff --git a/config/src/main/resources/org/switchyard/config/model/descriptor.properties b/config/src/main/resources/org/switchyard/config/model/descriptor.properties index 1f4695a83..68706bf0b 100644 --- a/config/src/main/resources/org/switchyard/config/model/descriptor.properties +++ b/config/src/main/resources/org/switchyard/config/model/descriptor.properties @@ -24,3 +24,4 @@ sca.namespace=http://docs.oasis-open.org/ns/opencsa/sca/200912 sca.schema=sca-1.1-cd06.xsd sca.location=/org/oasis-open/docs/ns/opencsa/sca/200912/ sca.marshaller=org.switchyard.config.model.composite.v1.V1CompositeMarshaller + diff --git a/config/src/main/resources/org/switchyard/config/model/switchyard/v1/switchyard-v1.xsd b/config/src/main/resources/org/switchyard/config/model/switchyard/v1/switchyard-v1.xsd index f3223da88..fc12b3ddb 100644 --- a/config/src/main/resources/org/switchyard/config/model/switchyard/v1/switchyard-v1.xsd +++ b/config/src/main/resources/org/switchyard/config/model/switchyard/v1/switchyard-v1.xsd @@ -143,6 +143,13 @@ MA 02110-1301, USA. + + + + + + + diff --git a/deploy/base/pom.xml b/deploy/base/pom.xml index 190deee5b..a39cf05ce 100644 --- a/deploy/base/pom.xml +++ b/deploy/base/pom.xml @@ -63,6 +63,11 @@ org.switchyard switchyard-bus-camel + + org.switchyard + switchyard-adapter + ${project.version} + log4j diff --git a/deploy/base/src/main/java/org/switchyard/deploy/internal/AbstractDeployment.java b/deploy/base/src/main/java/org/switchyard/deploy/internal/AbstractDeployment.java index a7db2369c..208079f9c 100644 --- a/deploy/base/src/main/java/org/switchyard/deploy/internal/AbstractDeployment.java +++ b/deploy/base/src/main/java/org/switchyard/deploy/internal/AbstractDeployment.java @@ -164,7 +164,7 @@ public ServiceDomain getDomain() { return _parentDeployment.getDomain(); } } - + /** * Get the {@link TransformerRegistryLoader} associated with the deployment. * @return The TransformerRegistryLoader instance. diff --git a/deploy/base/src/main/java/org/switchyard/deploy/internal/Deployment.java b/deploy/base/src/main/java/org/switchyard/deploy/internal/Deployment.java index c590664a6..3f07029ab 100644 --- a/deploy/base/src/main/java/org/switchyard/deploy/internal/Deployment.java +++ b/deploy/base/src/main/java/org/switchyard/deploy/internal/Deployment.java @@ -34,6 +34,8 @@ import org.apache.log4j.Logger; import org.switchyard.Service; import org.switchyard.ServiceReference; +import org.switchyard.adapter.Adapter; +import org.switchyard.adapter.AdapterUtil; import org.switchyard.common.type.Classes; import org.switchyard.config.model.ModelPuller; import org.switchyard.config.model.composite.BindingModel; @@ -45,6 +47,7 @@ import org.switchyard.config.model.composite.CompositeReferenceModel; import org.switchyard.config.model.composite.CompositeServiceModel; import org.switchyard.config.model.composite.InterfaceModel; +import org.switchyard.config.model.extensions.ExtensionsModel; import org.switchyard.config.model.switchyard.EsbInterfaceModel; import org.switchyard.config.model.switchyard.SwitchYardModel; import org.switchyard.config.model.transform.TransformsModel; @@ -244,7 +247,7 @@ private Activator findActivator(ComponentModel component) throws SwitchYardExcep } return findActivator(component.getImplementation().getType()); } - + private void registerTransformers() { _log.debug("Registering configured Transformers for deployment " + getName()); TransformsModel transforms = getConfig().getTransforms(); @@ -469,11 +472,15 @@ private void deployImplementations() { for (CompositeServiceModel compositeService : getConfig().getComposite().getServices()) { ComponentServiceModel componentService = compositeService.getComponentService(); if (componentService != null && componentService.equals(service)) { + Adapter adapter = createAdapter(compositeService); + svc.setAdapter(adapter); // avoid duplicates if (!service.getQName().equals(compositeService.getQName())) { validateServiceRegistration(compositeService.getQName()); + Service promotedService = getDomain().registerService( compositeService.getQName(), serviceIntf, handler); + promotedService.setAdapter(adapter); activation.addPromotion(promotedService); } } @@ -491,6 +498,17 @@ private void deployImplementations() { } } + private Adapter createAdapter(CompositeServiceModel compositeService) { + if (compositeService == null) { + return null; + } + ExtensionsModel extensions = compositeService.getExtensionsModel(); + if ((extensions != null) && extensions.hasAdapterModel()) { + return AdapterUtil.newAdapter(extensions.getAdapterModel()); + } + return null; + } + private void deployServiceBindings() { _log.debug("Deploying service bindings for deployment " + getName()); // activate bindings for each service diff --git a/pom.xml b/pom.xml index 54e9d1dab..0be4b33dd 100644 --- a/pom.xml +++ b/pom.xml @@ -39,6 +39,7 @@ common/camel config api + serial/base serial/jackson