http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridge.java ---------------------------------------------------------------------- diff --git a/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridge.java b/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridge.java new file mode 100644 index 0000000..d506d6c --- /dev/null +++ b/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridge.java @@ -0,0 +1,308 @@ +/***************************************************************** + * 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.cayenne.event; + +import org.apache.cayenne.CayenneRuntimeException; +import org.apache.cayenne.util.Base64Codec; +import org.apache.cayenne.util.Util; +import org.jivesoftware.smack.GroupChat; +import org.jivesoftware.smack.PacketListener; +import org.jivesoftware.smack.SSLXMPPConnection; +import org.jivesoftware.smack.XMPPConnection; +import org.jivesoftware.smack.XMPPException; +import org.jivesoftware.smack.packet.Message; +import org.jivesoftware.smack.packet.Packet; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.Collection; +import java.util.Collections; +import java.util.Map; + +/** + * An EventBridge implementation based on XMPP protocol and Smack XMPP client library. + * What's good about XMPP (Extensible Messaging and Presence Protocol, an IETF standard + * protocol that grew up from Jabber IM) is that generally it has fewer or no deployment + * limitations (unlike JMS and JGroups that are generally a good solution for local + * controlled networks). Also it provides lots of additional information for free, such as + * presence, and much more. + * <p> + * This implementation is based on Smack XMPP client library from JiveSoftware. + * </p> + * + * @since 1.2 + */ +public class XMPPBridge extends EventBridge { + + public static final String XMPP_HOST_PROPERTY = "cayenne.XMPPBridge.xmppHost"; + + /** + * An optional property, port 5222 is used as default XMPP port. + */ + public static final String XMPP_PORT_PROPERTY = "cayenne.XMPPBridge.xmppPort"; + + /** + * An optional property, "conference" is used as default chat service. + */ + public static final String XMPP_CHAT_SERVICE_PROPERTY = "cayenne.XMPPBridge.xmppChatService"; + + public static final String XMPP_SECURE_CONNECTION_PROPERTY = "cayenne.XMPPBridge.xmppSecure"; + public static final String XMPP_LOGIN_PROPERTY = "cayenne.XMPPBridge.xmppLogin"; + public static final String XMPP_PASSWORD_PROPERTY = "cayenne.XMPPBridge.xmppPassword"; + + static final String DEFAULT_CHAT_SERVICE = "conference"; + static final int DEFAULT_XMPP_PORT = 5222; + static final int DEFAULT_XMPP_SECURE_PORT = 5223; + + protected boolean secureConnection; + protected String loginId; + protected String password; + protected String xmppHost; + protected int xmppPort; + protected String chatService; + protected String sessionHandle; + + protected XMPPConnection connection; + protected GroupChat groupChat; + protected boolean connected; + + /** + * Creates an XMPPBridge. External subject will be used as the chat group name. + */ + public XMPPBridge(EventSubject localSubject, String externalSubject) { + this(Collections.singleton(localSubject), externalSubject); + } + + /** + * Creates an XMPPBridge. External subject will be used as the chat group name. + */ + public XMPPBridge(Collection<EventSubject> localSubjects, String externalSubject) { + super(localSubjects, externalSubject); + + // generate a unique session handle... users can override it to use a specific + // handle... + this.sessionHandle = "cayenne-xmpp-" + System.currentTimeMillis(); + } + + public XMPPBridge(Collection<EventSubject> localSubjects, String externalSubject, Map<String, String> properties) { + this(localSubjects, externalSubject); + + this.chatService = properties.get(XMPP_CHAT_SERVICE_PROPERTY); + this.xmppHost = properties.get(XMPP_HOST_PROPERTY); + + this.loginId = properties.get(XMPP_LOGIN_PROPERTY); + this.password = properties.get(XMPP_PASSWORD_PROPERTY); + + String secureConnectionString = properties.get(XMPP_SECURE_CONNECTION_PROPERTY); + secureConnection = "true".equalsIgnoreCase(secureConnectionString); + + String portString = properties.get(XMPP_PORT_PROPERTY); + if (portString != null) { + try { + this.xmppPort = Integer.parseInt(portString); + } catch (NumberFormatException e) { + throw new CayenneRuntimeException("Invalid port: %s", portString); + } + } + } + + public String getXmppHost() { + return xmppHost; + } + + public void setXmppHost(String xmppHost) { + this.xmppHost = xmppHost; + } + + public int getXmppPort() { + return xmppPort; + } + + public void setXmppPort(int xmppPort) { + this.xmppPort = xmppPort; + } + + public String getLoginId() { + return loginId; + } + + public void setLoginId(String loginId) { + this.loginId = loginId; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public boolean isSecureConnection() { + return secureConnection; + } + + public void setSecureConnection(boolean secureConnection) { + this.secureConnection = secureConnection; + } + + public String getChatService() { + return chatService; + } + + public void setChatService(String chatService) { + this.chatService = chatService; + } + + public String getSessionHandle() { + return sessionHandle; + } + + public void setSessionHandle(String sessionHandle) { + this.sessionHandle = sessionHandle; + } + + @Override + protected void startupExternal() throws Exception { + + // validate settings + if (xmppHost == null) { + throw new CayenneRuntimeException("Null 'xmppHost', can't start XMPPBridge"); + } + + // shutdown old bridge + if (connected) { + shutdownExternal(); + } + + try { + // connect and log in to chat + if (secureConnection) { + int port = xmppPort > 0 ? xmppPort : DEFAULT_XMPP_SECURE_PORT; + this.connection = new SSLXMPPConnection(xmppHost, port); + } else { + int port = xmppPort > 0 ? xmppPort : DEFAULT_XMPP_PORT; + this.connection = new XMPPConnection(xmppHost, port); + } + + if (loginId != null) { + // it is important to provide a (pseudo) globally unique string as the + // third argument ("sessionHandle" is such string); without it same + // loginId can not be reused from the same machine. + connection.login(loginId, password, sessionHandle); + } else { + connection.loginAnonymously(); + } + } catch (XMPPException e) { + throw new CayenneRuntimeException("Error connecting to XMPP Server: %s", e.getLocalizedMessage()); + } + + String service = chatService != null ? chatService : DEFAULT_CHAT_SERVICE; + try { + groupChat = connection.createGroupChat(externalSubject + '@' + service + "." + connection.getHost()); + groupChat.join(sessionHandle); + groupChat.addMessageListener(new XMPPListener()); + } catch (XMPPException e) { + throw new CayenneRuntimeException("Error setting up a group chat: %s", e.getLocalizedMessage()); + } + + this.connected = true; + } + + @Override + protected void shutdownExternal() throws Exception { + if (groupChat != null) { + groupChat.leave(); + groupChat = null; + } + + if (connection != null) { + connection.close(); + connection = null; + } + + connected = false; + } + + @Override + protected void sendExternalEvent(CayenneEvent localEvent) throws Exception { + + Message message = groupChat.createMessage(); + message.setBody(serializeToString(localEvent)); + + // set thread to our session handle to be able to discard messages from self + message.setThread(sessionHandle); + + groupChat.sendMessage(message); + } + + class XMPPListener implements PacketListener { + + public void processPacket(Packet packet) { + + if (packet instanceof Message) { + Message message = (Message) packet; + + // filter our own messages + if (sessionHandle.equals(message.getThread())) { + String payload = message.getBody(); + try { + Object event = deserializeFromString(payload); + if (event instanceof CayenneEvent) { + onExternalEvent((CayenneEvent) event); + } + } catch (Exception ex) { + // ignore for now... need to add logging. + } + } + } + } + } + + /** + * Decodes the String (assuming it is using Base64 encoding), and then deserializes + * object from the byte array. + */ + static Object deserializeFromString(String string) throws Exception { + if (Util.isEmptyString(string)) { + return null; + } + + byte[] bytes = Base64Codec.decodeBase64(string.getBytes()); + ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes)); + Object object = in.readObject(); + in.close(); + return object; + } + + /** + * Serializes object and then encodes it using Base64 encoding. + */ + static String serializeToString(Object object) throws Exception { + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(bytes); + out.writeObject(object); + out.close(); + + return new String(Base64Codec.encodeBase64(bytes.toByteArray())); + } +}
http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java ---------------------------------------------------------------------- diff --git a/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java b/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java new file mode 100644 index 0000000..7934752 --- /dev/null +++ b/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.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.cayenne.event; + +import java.util.Collection; +import java.util.Map; + +/** + * A factory of XMPPBridge. Note that to deploy an XMPPBridge, you need to have + * <em>smack.jar</em> library in the runtime. + * + * @since 1.2 + */ +public class XMPPBridgeFactory implements EventBridgeFactory { + + @Override + public EventBridge createEventBridge( + Collection<EventSubject> localSubjects, + String externalSubject, + Map<String, String> properties) { + return new XMPPBridge(localSubjects, externalSubject, properties); + } + +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java ---------------------------------------------------------------------- diff --git a/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java b/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java new file mode 100644 index 0000000..38c9874 --- /dev/null +++ b/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.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.cayenne.event; + +import org.apache.cayenne.access.DataDomain; +import org.apache.cayenne.access.DataRowStore; +import org.apache.cayenne.configuration.Constants; +import org.apache.cayenne.di.DIRuntimeException; +import org.apache.cayenne.di.Inject; +import org.apache.cayenne.di.Provider; + +import java.util.Collections; +import java.util.Map; + +public class XMPPBridgeProvider implements Provider<EventBridge> { + + @Inject + protected DataDomain dataDomain; + + @Inject(XMPPModule.XMPP_BRIDGE_PROPERTIES_MAP) + Map<String, String> properties; + + @Override + public EventBridge get() throws DIRuntimeException { + EventSubject snapshotEventSubject = EventSubject.getSubject(DataRowStore.class.getClass(), dataDomain.getName()); + + return new XMPPBridge( + Collections.singleton(snapshotEventSubject), + EventBridge.convertToExternalSubject(snapshotEventSubject), + properties); + } + +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPModule.java ---------------------------------------------------------------------- diff --git a/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPModule.java b/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPModule.java new file mode 100644 index 0000000..83c8f0a --- /dev/null +++ b/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPModule.java @@ -0,0 +1,71 @@ +/***************************************************************** + * 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.cayenne.event; + +import org.apache.cayenne.di.Binder; +import org.apache.cayenne.di.MapBuilder; +import org.apache.cayenne.di.Module; + +/** + * @since 4.0 + */ +public class XMPPModule implements Module { + + /** + * A DI container key for the Map<String, String> storing + * {@link org.apache.cayenne.event.XMPPBridge} properties + * + * @since 4.0 + */ + public static final String XMPP_BRIDGE_PROPERTIES_MAP = "cayenne.server.xmpp_bridge"; + + public static void contributeHost(Binder binder, String host) { + contributeProperties(binder).put(XMPPBridge.XMPP_HOST_PROPERTY, host); + } + + public static void contributePort(Binder binder, int port) { + contributeProperties(binder).put(XMPPBridge.XMPP_PORT_PROPERTY, Integer.toString(port)); + } + + public static void contributeLogin(Binder binder, String login, String password) { + contributeProperties(binder).put(XMPPBridge.XMPP_LOGIN_PROPERTY, login); + contributeProperties(binder).put(XMPPBridge.XMPP_PASSWORD_PROPERTY, password); + } + + public static void contributeChatService(Binder binder, String chatService) { + contributeProperties(binder).put(XMPPBridge.XMPP_CHAT_SERVICE_PROPERTY, chatService); + } + + public static void contributeSecureConnection(Binder binder, boolean secure) { + contributeProperties(binder).put(XMPPBridge.XMPP_SECURE_CONNECTION_PROPERTY, Boolean.toString(secure)); + } + + private static MapBuilder<String> contributeProperties(Binder binder) { + return binder.bindMap(String.class, XMPP_BRIDGE_PROPERTIES_MAP); + } + + @Override + public void configure(Binder binder) { + // init properties' defaults + contributeChatService(binder, XMPPBridge.DEFAULT_CHAT_SERVICE); + + binder.bind(EventBridge.class).toProvider(XMPPBridgeProvider.class); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPServerModuleProvider.java ---------------------------------------------------------------------- diff --git a/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPServerModuleProvider.java b/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPServerModuleProvider.java new file mode 100644 index 0000000..e8cf3da --- /dev/null +++ b/cayenne-xmpp/src/main/java/org/apache/cayenne/event/XMPPServerModuleProvider.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.cayenne.event; + +import java.util.Collection; +import java.util.Collections; + +import org.apache.cayenne.configuration.server.CayenneServerModuleProvider; +import org.apache.cayenne.configuration.server.ServerModule; +import org.apache.cayenne.di.Module; + +/** + * @since 4.0 + */ +public class XMPPServerModuleProvider implements CayenneServerModuleProvider { + + @Override + public Module module() { + return new XMPPModule(); + } + + @Override + public Class<? extends Module> moduleType() { + return XMPPModule.class; + } + + @SuppressWarnings("unchecked") + @Override + public Collection<Class<? extends Module>> overrides() { + Collection modules = Collections.singletonList(ServerModule.class); + return modules; + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-xmpp/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider ---------------------------------------------------------------------- diff --git a/cayenne-xmpp/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider b/cayenne-xmpp/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider new file mode 100644 index 0000000..00bce56 --- /dev/null +++ b/cayenne-xmpp/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider @@ -0,0 +1,20 @@ +################################################################## +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +################################################################## + +org.apache.cayenne.event.XMPPServerModuleProvider \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-xmpp/src/test/java/org/apache/cayenne/event/CayenneXMPPModuleProviderTest.java ---------------------------------------------------------------------- diff --git a/cayenne-xmpp/src/test/java/org/apache/cayenne/event/CayenneXMPPModuleProviderTest.java b/cayenne-xmpp/src/test/java/org/apache/cayenne/event/CayenneXMPPModuleProviderTest.java new file mode 100644 index 0000000..0826f7c --- /dev/null +++ b/cayenne-xmpp/src/test/java/org/apache/cayenne/event/CayenneXMPPModuleProviderTest.java @@ -0,0 +1,36 @@ +/***************************************************************** + * 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.cayenne.event; + +import org.apache.cayenne.configuration.server.CayenneServerModuleProvider; +import org.apache.cayenne.unit.util.ModuleProviderChecker; +import org.junit.Test; + +/** + * @since 4.0 + */ +public class CayenneXMPPModuleProviderTest { + + @Test + public void testAutoLoadable() { + ModuleProviderChecker.testProviderPresent(XMPPServerModuleProvider.class, CayenneServerModuleProvider.class); + } + +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java ---------------------------------------------------------------------- diff --git a/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java b/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java new file mode 100644 index 0000000..b5aa80a --- /dev/null +++ b/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java @@ -0,0 +1,72 @@ +/***************************************************************** + * 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.cayenne.event; + +import org.junit.Test; + +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class XMPPBridgeFactoryTest { + + protected Collection<EventSubject> subjects = Collections.singleton(new EventSubject("test")); + protected String externalSubject = "subject"; + + @Test + public void testCreateEventBridge() { + EventBridge bridge = new XMPPBridgeFactory().createEventBridge( + subjects, + externalSubject, + Collections.<String, String>emptyMap()); + + assertTrue(bridge instanceof XMPPBridge); + assertEquals(subjects, bridge.getLocalSubjects()); + assertEquals(externalSubject, bridge.getExternalSubject()); + } + + @Test + public void testUseMapPropertiesSetter() throws Exception { + XMPPBridgeFactory bridgeFactory = new XMPPBridgeFactory(); + Map<String, String> properties = new HashMap<>(); + + properties.put(XMPPBridge.XMPP_HOST_PROPERTY, XMPPBridgeProviderTest.HOST_TEST); + properties.put(XMPPBridge.XMPP_CHAT_SERVICE_PROPERTY, XMPPBridgeProviderTest.CHAT_SERVICE_TEST); + properties.put(XMPPBridge.XMPP_LOGIN_PROPERTY, XMPPBridgeProviderTest.LOGIN_TEST); + properties.put(XMPPBridge.XMPP_PASSWORD_PROPERTY, XMPPBridgeProviderTest.PASSWORD_TEST); + properties.put(XMPPBridge.XMPP_SECURE_CONNECTION_PROPERTY, String.valueOf(XMPPBridgeProviderTest.SECURE_CONNECTION_TEST)); + properties.put(XMPPBridge.XMPP_PORT_PROPERTY, String.valueOf(XMPPBridgeProviderTest.PORT_TEST)); + + XMPPBridge bridge = (XMPPBridge) bridgeFactory.createEventBridge(subjects, + externalSubject, + properties); + + assertEquals(bridge.getXmppHost(), XMPPBridgeProviderTest.HOST_TEST); + assertEquals(bridge.getChatService(), XMPPBridgeProviderTest.CHAT_SERVICE_TEST); + assertEquals(bridge.getLoginId(), XMPPBridgeProviderTest.LOGIN_TEST); + assertEquals(bridge.getPassword(), XMPPBridgeProviderTest.PASSWORD_TEST); + assertEquals(bridge.getXmppPort(), XMPPBridgeProviderTest.PORT_TEST); + assertEquals(bridge.isSecureConnection(), XMPPBridgeProviderTest.SECURE_CONNECTION_TEST); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java ---------------------------------------------------------------------- diff --git a/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java b/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java new file mode 100644 index 0000000..f36d495 --- /dev/null +++ b/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java @@ -0,0 +1,105 @@ +/***************************************************************** + * 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.cayenne.event; + +import org.apache.cayenne.access.DataDomain; +import org.apache.cayenne.configuration.Constants; +import org.apache.cayenne.configuration.DefaultRuntimeProperties; +import org.apache.cayenne.configuration.RuntimeProperties; +import org.apache.cayenne.di.Binder; +import org.apache.cayenne.di.DIBootstrap; +import org.apache.cayenne.di.Injector; +import org.apache.cayenne.di.Module; +import org.apache.cayenne.log.Slf4jJdbcEventLogger; +import org.apache.cayenne.log.JdbcEventLogger; +import org.apache.cayenne.tx.DefaultTransactionFactory; +import org.apache.cayenne.tx.DefaultTransactionManager; +import org.apache.cayenne.tx.TransactionFactory; +import org.apache.cayenne.tx.TransactionManager; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class XMPPBridgeProviderTest { + + private final DataDomain DOMAIN = new DataDomain("test"); + private final EventManager EVENT_MANAGER = new DefaultEventManager(); + protected static final String HOST_TEST = "somehost.com"; + protected static final String CHAT_SERVICE_TEST = "conference"; + protected static final String LOGIN_TEST = "login"; + protected static final String PASSWORD_TEST = "password"; + protected static final boolean SECURE_CONNECTION_TEST = true; + protected static final int PORT_TEST = 12345; + + @Test + public void testGetXMPPBridge() throws Exception { + Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new XMPPModule()); + EventBridge bridge = injector.getInstance(EventBridge.class); + + assertNotNull(bridge); + assertTrue(bridge instanceof XMPPBridge); + } + + @Test + public void testUseProperties() throws Exception { + Module module = binder -> { + XMPPModule.contributeSecureConnection(binder, SECURE_CONNECTION_TEST); + XMPPModule.contributeHost(binder, HOST_TEST); + XMPPModule.contributePort(binder, PORT_TEST); + XMPPModule.contributeLogin(binder, LOGIN_TEST, PASSWORD_TEST); + XMPPModule.contributeChatService(binder, CHAT_SERVICE_TEST); + }; + + Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new XMPPModule(), module); + XMPPBridge bridge = (XMPPBridge) injector.getInstance(EventBridge.class); + + assertEquals(HOST_TEST, bridge.getXmppHost()); + assertEquals(CHAT_SERVICE_TEST, bridge.getChatService()); + assertEquals(LOGIN_TEST, bridge.getLoginId()); + assertEquals(PASSWORD_TEST, bridge.getPassword()); + assertEquals(SECURE_CONNECTION_TEST, bridge.isSecureConnection()); + assertEquals(PORT_TEST, bridge.getXmppPort()); + } + + @Test + public void testUseDefaultProperties() throws Exception { + Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new XMPPModule()); + XMPPBridge bridge = (XMPPBridge) injector.getInstance(EventBridge.class); + + assertEquals(XMPPBridge.DEFAULT_CHAT_SERVICE, bridge.getChatService()); + assertEquals(0, bridge.getXmppPort()); + assertEquals(false, bridge.isSecureConnection()); + } + + class DefaultBindings implements Module { + @Override + public void configure(Binder binder) { + binder.bindMap(String.class, Constants.PROPERTIES_MAP); + binder.bind(DataDomain.class).toInstance(DOMAIN); + binder.bind(EventManager.class).toInstance(EVENT_MANAGER); + binder.bind(TransactionManager.class).to(DefaultTransactionManager.class); + binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class); + binder.bind(JdbcEventLogger.class).to(Slf4jJdbcEventLogger.class); + binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class); + } + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeTest.java ---------------------------------------------------------------------- diff --git a/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeTest.java b/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeTest.java new file mode 100644 index 0000000..5422c3a --- /dev/null +++ b/cayenne-xmpp/src/test/java/org/apache/cayenne/event/XMPPBridgeTest.java @@ -0,0 +1,54 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ****************************************************************/ + +package org.apache.cayenne.event; + +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +/** + */ +public class XMPPBridgeTest { + + @Test + public void testEventSerialization() throws Exception { + Map<String, String> info = new HashMap<>(); + info.put("a", "b"); + CayenneEvent e = new CayenneEvent(this, this, info); + + String string = XMPPBridge.serializeToString(e); + assertNotNull(string); + + Object copy = XMPPBridge.deserializeFromString(string); + assertNotNull(copy); + assertTrue(copy instanceof CayenneEvent); + + CayenneEvent e2 = (CayenneEvent) copy; + assertEquals(info, e2.getInfo()); + assertNull(e2.getPostedBy()); + assertNull(e2.getSource()); + } +} http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jgroups/pom.xml ---------------------------------------------------------------------- diff --git a/eventbridges/cayenne-jgroups/pom.xml b/eventbridges/cayenne-jgroups/pom.xml deleted file mode 100644 index 3d0944e..0000000 --- a/eventbridges/cayenne-jgroups/pom.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ~ Licensed to the Apache Software Foundation (ASF) under one - ~ or more contributor license agreements. See the NOTICE file - ~ distributed with this work for additional information - ~ regarding copyright ownership. The ASF licenses this file - ~ to you under the Apache License, Version 2.0 (the - ~ "License"); you may not use this file except in compliance - ~ with the License. You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, - ~ software distributed under the License is distributed on an - ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - ~ KIND, either express or implied. See the License for the - ~ specific language governing permissions and limitations - ~ under the License. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--> - -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <parent> - <artifactId>cayenne-eventbridges-parent</artifactId> - <groupId>org.apache.cayenne</groupId> - <version>4.1.M2-SNAPSHOT</version> - </parent> - <modelVersion>4.0.0</modelVersion> - - <artifactId>cayenne-jgroups</artifactId> - <name>cayenne-jgroups: Cayenne JGroups Event bridge</name> - <packaging>jar</packaging> - - <dependencies> - <dependency> - <groupId>jgroups</groupId> - <artifactId>jgroups-all</artifactId> - <scope>provided</scope> - </dependency> - </dependencies> - -</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsModule.java ---------------------------------------------------------------------- diff --git a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsModule.java b/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsModule.java deleted file mode 100644 index 77738c3..0000000 --- a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsModule.java +++ /dev/null @@ -1,63 +0,0 @@ -/***************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - ****************************************************************/ - -package org.apache.cayenne.event; - -import org.apache.cayenne.di.Binder; -import org.apache.cayenne.di.MapBuilder; -import org.apache.cayenne.di.Module; - -/** - * @since 4.0 - */ -public class JGroupsModule implements Module { - - /** - * A DI container key for the Map<String, String> storing - * {@link org.apache.cayenne.event.JavaGroupsBridge} properties - * - * @since 4.0 - */ - public static final String JAVA_GROUPS_BRIDGE_PROPERTIES_MAP = "cayenne.server.java_group_bridge"; - - public static void contributeMulticastAddress(Binder binder, String address) { - contributeProperties(binder).put(JavaGroupsBridge.MCAST_ADDRESS_PROPERTY, address); - } - - public static void contributeMulticastPort(Binder binder, int port) { - contributeProperties(binder).put(JavaGroupsBridge.MCAST_PORT_PROPERTY, Integer.toString(port)); - } - - public static void contributeConfigUrl(Binder binder, String config) { - contributeProperties(binder).put(JavaGroupsBridge.JGROUPS_CONFIG_URL_PROPERTY, config); - } - - private static MapBuilder<String> contributeProperties(Binder binder) { - return binder.bindMap(String.class, JAVA_GROUPS_BRIDGE_PROPERTIES_MAP); - } - - @Override - public void configure(Binder binder) { - // init properties' defaults - contributeMulticastAddress(binder, JavaGroupsBridge.MCAST_ADDRESS_DEFAULT); - contributeMulticastPort(binder, JavaGroupsBridge.MCAST_PORT_DEFAULT_INT); - - binder.bind(EventBridge.class).toProvider(JavaGroupsBridgeProvider.class); - } -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsServerModuleProvider.java ---------------------------------------------------------------------- diff --git a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsServerModuleProvider.java b/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsServerModuleProvider.java deleted file mode 100644 index 60c5bcd..0000000 --- a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JGroupsServerModuleProvider.java +++ /dev/null @@ -1,50 +0,0 @@ -/***************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - ****************************************************************/ - -package org.apache.cayenne.event; - -import java.util.Collection; -import java.util.Collections; - -import org.apache.cayenne.configuration.server.CayenneServerModuleProvider; -import org.apache.cayenne.configuration.server.ServerModule; -import org.apache.cayenne.di.Module; - -/** - * @since 4.0 - */ -public class JGroupsServerModuleProvider implements CayenneServerModuleProvider { - - @Override - public Module module() { - return new JGroupsModule(); - } - - @Override - public Class<? extends Module> moduleType() { - return JGroupsModule.class; - } - - @SuppressWarnings("unchecked") - @Override - public Collection<Class<? extends Module>> overrides() { - Collection modules = Collections.singletonList(ServerModule.class); - return modules; - } -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java ---------------------------------------------------------------------- diff --git a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java b/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java deleted file mode 100644 index cd7bae2..0000000 --- a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java +++ /dev/null @@ -1,231 +0,0 @@ -/***************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - ****************************************************************/ - -package org.apache.cayenne.event; - -import org.jgroups.Channel; -import org.jgroups.JChannel; -import org.jgroups.Message; -import org.jgroups.MessageListener; -import org.jgroups.blocks.PullPushAdapter; - -import java.io.Serializable; -import java.util.Collection; -import java.util.Map; - -/** - * Implementation of EventBridge that passes and receives events via JavaGroups - * communication software. - * - * @since 1.1 - */ -public class JavaGroupsBridge extends EventBridge implements MessageListener { - - public static final String MCAST_ADDRESS_DEFAULT = "228.0.0.5"; - public static final int MCAST_PORT_DEFAULT_INT = 22222; - public static final String MCAST_PORT_DEFAULT = Integer.toString(MCAST_PORT_DEFAULT_INT); - - public static final String MCAST_ADDRESS_PROPERTY = "cayenne.JavaGroupsBridge.mcast.address"; - public static final String MCAST_PORT_PROPERTY = "cayenne.JavaGroupsBridge.mcast.port"; - - /** - * Defines a property for JavaGroups XML configuration file. - */ - public static final String JGROUPS_CONFIG_URL_PROPERTY = "javagroupsbridge.config.url"; - - // TODO: Meaning of "state" in JGroups is not yet clear to me - protected byte[] state; - - protected Channel channel; - protected PullPushAdapter adapter; - protected String multicastAddress; - protected String multicastPort; - protected String configURL; - - /** - * Creates new instance of JavaGroupsBridge. - */ - public JavaGroupsBridge(EventSubject localSubject, String externalSubject) { - super(localSubject, externalSubject); - } - - /** - * @since 1.2 - */ - public JavaGroupsBridge(Collection<EventSubject> localSubjects, String externalSubject) { - super(localSubjects, externalSubject); - } - - /** - * @since 4.0 - */ - public JavaGroupsBridge(Collection<EventSubject> localSubjects, String externalSubject, Map<String, String> properties) { - super(localSubjects, externalSubject); - - // configure properties - String multicastAddress = properties.get(MCAST_ADDRESS_PROPERTY); - String multicastPort = properties.get(MCAST_PORT_PROPERTY); - - this.configURL = properties.get(JGROUPS_CONFIG_URL_PROPERTY); - this.multicastAddress = (multicastAddress != null) ? multicastAddress : MCAST_ADDRESS_DEFAULT; - this.multicastPort = (multicastPort != null) ? multicastPort : MCAST_PORT_DEFAULT; - } - - public String getConfigURL() { - return configURL; - } - - public void setConfigURL(String configURL) { - this.configURL = configURL; - } - - public String getMulticastAddress() { - return multicastAddress; - } - - public void setMulticastAddress(String multicastAddress) { - this.multicastAddress = multicastAddress; - } - - public String getMulticastPort() { - return multicastPort; - } - - public void setMulticastPort(String multicastPort) { - this.multicastPort = multicastPort; - } - - public byte[] getState() { - return state; - } - - public void setState(byte[] state) { - this.state = state; - } - - /** - * Implementation of org.javagroups.MessageListener - a callback method to process - * incoming messages. - */ - public void receive(Message message) { - try { - CayenneEvent event = messageObjectToEvent((Serializable) message.getObject()); - if (event != null) { - - onExternalEvent(event); - } - } - catch (Exception ex) { - // TODO: Andrus, 2/8/2006 logging... Log4J was removed to make this usable on - // the client - } - } - - @Override - protected void startupExternal() throws Exception { - // TODO: need to do more research to figure out the best default transport - // settings - // to avoid fragmentation, etc. - - // if config file is set, use it, otherwise use a default - // set of properties, trying to configure multicast address and port - if (configURL != null) { - channel = new JChannel(configURL); - } - else { - String configString = buildConfigString(); - channel = new JChannel(configString); - } - - // Important - discard messages from self - channel.setOpt(Channel.LOCAL, Boolean.FALSE); - channel.connect(externalSubject); - - if (receivesExternalEvents()) { - adapter = new PullPushAdapter(channel, this); - } - } - - /** - * Creates JavaGroups configuration String, using preconfigured multicast port and - * address. - */ - protected String buildConfigString() { - if (multicastAddress == null) { - throw new IllegalStateException("'multcastAddress' is not set"); - } - - if (multicastPort == null) { - throw new IllegalStateException("'multcastPort' is not set"); - } - - return "UDP(mcast_addr=" - + multicastAddress - + ";mcast_port=" - + multicastPort - + ";ip_ttl=32):" - + "PING(timeout=3000;num_initial_members=6):" - + "FD(timeout=3000):" - + "VERIFY_SUSPECT(timeout=1500):" - + "pbcast.NAKACK(gc_lag=10;retransmit_timeout=600,1200,2400,4800):" - + "pbcast.STABLE(desired_avg_gossip=10000):" - + "FRAG:" - + "pbcast.GMS(join_timeout=5000;join_retry_timeout=2000;" - + "shun=true;print_local_addr=false)"; - } - - @Override - protected void shutdownExternal() throws Exception { - try { - if (adapter != null) { - adapter.stop(); - } - - channel.close(); - } - finally { - adapter = null; - channel = null; - } - } - - @Override - protected void sendExternalEvent(CayenneEvent localEvent) throws Exception { - Message message = new Message(null, null, eventToMessageObject(localEvent)); - channel.send(message); - } - - /** - * Converts CayenneEvent to a serializable object that will be sent via JMS. Default - * implementation simply returns the event, but subclasses can customize this - * behavior. - */ - protected Serializable eventToMessageObject(CayenneEvent event) throws Exception { - return event; - } - - /** - * Converts a Serializable instance to CayenneEvent. Returns null if the object is not - * supported. Default implementation simply tries to cast the object to CayenneEvent, - * but subclasses can customize this behavior. - */ - protected CayenneEvent messageObjectToEvent(Serializable object) throws Exception { - return (object instanceof CayenneEvent) ? (CayenneEvent) object : null; - } -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java ---------------------------------------------------------------------- diff --git a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java b/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java deleted file mode 100644 index 302e5ca..0000000 --- a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java +++ /dev/null @@ -1,49 +0,0 @@ -/***************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - ****************************************************************/ - -package org.apache.cayenne.event; - -import java.util.Collection; -import java.util.Map; - -/** - * Factory to create JavaGroupsBridge instances. If JavaGroups library is not installed - * this factory will return a noop EventBridge as a failover mechanism. - * <p/> - * For further information about JavaGroups consult the <a href="http://www.jgroups.org/">documentation</a>. - * - * @since 1.1 - */ -public class JavaGroupsBridgeFactory implements EventBridgeFactory { - - /** - * Creates a JavaGroupsBridge instance. Since JavaGroups is not shipped with Cayenne - * and should be installed separately, a common misconfiguration problem may be the - * absence of JavaGroups jar file. This factory returns a dummy noop EventBridge, if - * this is the case. This would allow the application to continue to run, but without - * remote notifications. - */ - public EventBridge createEventBridge( - Collection<EventSubject> localSubjects, - String externalSubject, - Map<String, String> properties) { - return new JavaGroupsBridge(localSubjects, externalSubject, properties); - } - -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java ---------------------------------------------------------------------- diff --git a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java b/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java deleted file mode 100644 index 983aa7f..0000000 --- a/eventbridges/cayenne-jgroups/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java +++ /dev/null @@ -1,50 +0,0 @@ -/***************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - ****************************************************************/ - -package org.apache.cayenne.event; - -import org.apache.cayenne.access.DataDomain; -import org.apache.cayenne.access.DataRowStore; -import org.apache.cayenne.configuration.Constants; -import org.apache.cayenne.di.DIRuntimeException; -import org.apache.cayenne.di.Inject; -import org.apache.cayenne.di.Provider; - -import java.util.Collections; -import java.util.Map; - -public class JavaGroupsBridgeProvider implements Provider<EventBridge> { - - @Inject - protected DataDomain dataDomain; - - @Inject(JGroupsModule.JAVA_GROUPS_BRIDGE_PROPERTIES_MAP) - Map<String, String> properties; - - @Override - public EventBridge get() throws DIRuntimeException { - EventSubject snapshotEventSubject = EventSubject.getSubject(DataRowStore.class, dataDomain.getName()); - - return new JavaGroupsBridge( - Collections.singleton(snapshotEventSubject), - EventBridge.convertToExternalSubject(snapshotEventSubject), - properties); - } - -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jgroups/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider ---------------------------------------------------------------------- diff --git a/eventbridges/cayenne-jgroups/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider b/eventbridges/cayenne-jgroups/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider deleted file mode 100644 index b6c6632..0000000 --- a/eventbridges/cayenne-jgroups/src/main/resources/META-INF/services/org.apache.cayenne.configuration.server.CayenneServerModuleProvider +++ /dev/null @@ -1,20 +0,0 @@ -################################################################## -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -################################################################## - -org.apache.cayenne.event.JGroupsServerModuleProvider \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/CayenneJGroupsModuleProviderTest.java ---------------------------------------------------------------------- diff --git a/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/CayenneJGroupsModuleProviderTest.java b/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/CayenneJGroupsModuleProviderTest.java deleted file mode 100644 index 320d490..0000000 --- a/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/CayenneJGroupsModuleProviderTest.java +++ /dev/null @@ -1,36 +0,0 @@ -/***************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - ****************************************************************/ - -package org.apache.cayenne.event; - -import org.apache.cayenne.configuration.server.CayenneServerModuleProvider; -import org.apache.cayenne.unit.util.ModuleProviderChecker; -import org.junit.Test; - -/** - * @since 4.0 - */ -public class CayenneJGroupsModuleProviderTest { - - @Test - public void testAutoLoadable() { - ModuleProviderChecker.testProviderPresent(JGroupsServerModuleProvider.class, CayenneServerModuleProvider.class); - } - -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeFactoryTest.java ---------------------------------------------------------------------- diff --git a/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeFactoryTest.java b/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeFactoryTest.java deleted file mode 100644 index 694dc24..0000000 --- a/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeFactoryTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/***************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - ****************************************************************/ - -package org.apache.cayenne.event; - -import org.junit.Test; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -/** - */ -public class JavaGroupsBridgeFactoryTest { - - protected Collection<EventSubject> subjects = Collections.singleton(new EventSubject("test")); - protected String externalSubject = "subject"; - - @Test - public void testCreateEventBridge() throws Exception { - EventBridge bridge = new JavaGroupsBridgeFactory().createEventBridge( - subjects, - externalSubject, - Collections.<String, String>emptyMap()); - - assertNotNull(bridge); - assertTrue(bridge instanceof JavaGroupsBridge); - assertEquals(subjects, bridge.getLocalSubjects()); - assertEquals(externalSubject, bridge.getExternalSubject()); - } - - @Test - public void testUseProperties() throws Exception { - JavaGroupsBridgeFactory bridgeFactory = new JavaGroupsBridgeFactory(); - - Map<String, String> properties = new HashMap<>(); - properties.put(JavaGroupsBridge.MCAST_ADDRESS_PROPERTY, JavaGroupsBridgeProviderTest.MCAST_ADDRESS_TEST); - properties.put(JavaGroupsBridge.MCAST_PORT_PROPERTY, JavaGroupsBridgeProviderTest.MCAST_PORT_TEST); - properties.put(JavaGroupsBridge.JGROUPS_CONFIG_URL_PROPERTY, JavaGroupsBridgeProviderTest.CONFIG_URL_TEST); - - JavaGroupsBridge bridge = (JavaGroupsBridge) bridgeFactory.createEventBridge( - subjects, - externalSubject, - properties); - - assertEquals(bridge.getMulticastAddress(), JavaGroupsBridgeProviderTest.MCAST_ADDRESS_TEST); - assertEquals(bridge.getMulticastPort(), JavaGroupsBridgeProviderTest.MCAST_PORT_TEST); - assertEquals(bridge.getConfigURL(), JavaGroupsBridgeProviderTest.CONFIG_URL_TEST); - } - - @Test - public void testUseDefaultProperties() throws Exception { - JavaGroupsBridgeFactory bridgeFactory = new JavaGroupsBridgeFactory(); - JavaGroupsBridge bridge = (JavaGroupsBridge) bridgeFactory.createEventBridge( - subjects, - externalSubject, - Collections.<String, String>emptyMap()); - - assertEquals(bridge.getMulticastAddress(), JavaGroupsBridge.MCAST_ADDRESS_DEFAULT); - assertEquals(bridge.getMulticastPort(), JavaGroupsBridge.MCAST_PORT_DEFAULT); - assertEquals(bridge.getConfigURL(), null); - } -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java ---------------------------------------------------------------------- diff --git a/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java b/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java deleted file mode 100644 index 00232d4..0000000 --- a/eventbridges/cayenne-jgroups/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java +++ /dev/null @@ -1,97 +0,0 @@ -/***************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - ****************************************************************/ - -package org.apache.cayenne.event; - -import org.apache.cayenne.access.DataDomain; -import org.apache.cayenne.configuration.Constants; -import org.apache.cayenne.configuration.DefaultRuntimeProperties; -import org.apache.cayenne.configuration.RuntimeProperties; -import org.apache.cayenne.di.Binder; -import org.apache.cayenne.di.DIBootstrap; -import org.apache.cayenne.di.Injector; -import org.apache.cayenne.di.Module; -import org.apache.cayenne.log.Slf4jJdbcEventLogger; -import org.apache.cayenne.log.JdbcEventLogger; -import org.apache.cayenne.tx.DefaultTransactionFactory; -import org.apache.cayenne.tx.DefaultTransactionManager; -import org.apache.cayenne.tx.TransactionFactory; -import org.apache.cayenne.tx.TransactionManager; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -public class JavaGroupsBridgeProviderTest { - - private final DataDomain DOMAIN = new DataDomain("test"); - private final EventManager EVENT_MANAGER = new DefaultEventManager(); - protected static final String MCAST_ADDRESS_TEST = "192.168.0.0"; - protected static final String MCAST_PORT_TEST = "1521"; - protected static final String CONFIG_URL_TEST = "somehost.com"; - - @Test - public void testGetJavaGroupsBridge() throws Exception { - Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new JGroupsModule()); - EventBridge bridge = injector.getInstance(EventBridge.class); - - assertNotNull(bridge); - assertTrue(bridge instanceof JavaGroupsBridge); - } - - @Test - public void testUseProperties() throws Exception { - Module module = binder -> { - JGroupsModule.contributeMulticastAddress(binder, MCAST_ADDRESS_TEST); - JGroupsModule.contributeMulticastPort(binder, Integer.parseInt(MCAST_PORT_TEST)); - JGroupsModule.contributeConfigUrl(binder, CONFIG_URL_TEST); - }; - - Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new JGroupsModule(), module); - JavaGroupsBridge bridge = (JavaGroupsBridge) injector.getInstance(EventBridge.class); - - assertEquals(MCAST_ADDRESS_TEST, bridge.getMulticastAddress()); - assertEquals(MCAST_PORT_TEST, bridge.getMulticastPort()); - assertEquals(CONFIG_URL_TEST, bridge.getConfigURL()); - } - - @Test - public void testUseDefaultProperties() throws Exception { - Injector injector = DIBootstrap.createInjector(new DefaultBindings(), new JGroupsModule()); - JavaGroupsBridge bridge = (JavaGroupsBridge) injector.getInstance(EventBridge.class); - - assertEquals(JavaGroupsBridge.MCAST_ADDRESS_DEFAULT, bridge.getMulticastAddress()); - assertEquals(JavaGroupsBridge.MCAST_PORT_DEFAULT, bridge.getMulticastPort()); - assertEquals(null, bridge.getConfigURL()); - } - - class DefaultBindings implements Module { - @Override - public void configure(Binder binder) { - binder.bindMap(String.class, Constants.PROPERTIES_MAP); - binder.bind(DataDomain.class).toInstance(DOMAIN); - binder.bind(EventManager.class).toInstance(EVENT_MANAGER); - binder.bind(TransactionManager.class).to(DefaultTransactionManager.class); - binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class); - binder.bind(JdbcEventLogger.class).to(Slf4jJdbcEventLogger.class); - binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class); - } - } -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jms/pom.xml ---------------------------------------------------------------------- diff --git a/eventbridges/cayenne-jms/pom.xml b/eventbridges/cayenne-jms/pom.xml deleted file mode 100644 index 6ae9192..0000000 --- a/eventbridges/cayenne-jms/pom.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ~ Licensed to the Apache Software Foundation (ASF) under one - ~ or more contributor license agreements. See the NOTICE file - ~ distributed with this work for additional information - ~ regarding copyright ownership. The ASF licenses this file - ~ to you under the Apache License, Version 2.0 (the - ~ "License"); you may not use this file except in compliance - ~ with the License. You may obtain a copy of the License at - ~ - ~ http://www.apache.org/licenses/LICENSE-2.0 - ~ - ~ Unless required by applicable law or agreed to in writing, - ~ software distributed under the License is distributed on an - ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - ~ KIND, either express or implied. See the License for the - ~ specific language governing permissions and limitations - ~ under the License. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--> - -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> - <parent> - <artifactId>cayenne-eventbridges-parent</artifactId> - <groupId>org.apache.cayenne</groupId> - <version>4.1.M2-SNAPSHOT</version> - </parent> - <modelVersion>4.0.0</modelVersion> - - <artifactId>cayenne-jms</artifactId> - <name>cayenne-jms: Cayenne JMS Event bridge</name> - <packaging>jar</packaging> - - <dependencies> - <dependency> - <groupId>org.apache.geronimo.specs</groupId> - <artifactId>geronimo-jms_1.1_spec</artifactId> - <scope>provided</scope> - </dependency> - </dependencies> - -</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridge.java ---------------------------------------------------------------------- diff --git a/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridge.java b/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridge.java deleted file mode 100644 index 0b746fc..0000000 --- a/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridge.java +++ /dev/null @@ -1,280 +0,0 @@ -/***************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - ****************************************************************/ - -package org.apache.cayenne.event; - -import org.apache.cayenne.util.IDUtil; - -import javax.jms.Message; -import javax.jms.MessageFormatException; -import javax.jms.MessageListener; -import javax.jms.ObjectMessage; -import javax.jms.Session; -import javax.jms.Topic; -import javax.jms.TopicConnection; -import javax.jms.TopicConnectionFactory; -import javax.jms.TopicPublisher; -import javax.jms.TopicSession; -import javax.jms.TopicSubscriber; -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NameNotFoundException; -import javax.naming.NamingException; -import java.io.Serializable; -import java.util.Collection; -import java.util.Map; - -/** - * Implementation of EventBridge that passes and receives events via JMS (Java Messaging - * Service). JMSBridge uses "publish/subscribe" model for communication with external - * agents. - * - * @since 1.1 - */ -public class JMSBridge extends EventBridge implements MessageListener { - - // this is an OpenJMS default for the factory name. Likely it won't work with - // anything else - public static final String TOPIC_CONNECTION_FACTORY_DEFAULT = "JmsTopicConnectionFactory"; - - public static final String TOPIC_CONNECTION_FACTORY_PROPERTY = "cayenne.JMSBridge.topic.connection.factory"; - - static final String VM_ID = new String(IDUtil.pseudoUniqueByteSequence16()); - static final String VM_ID_PROPERTY = "VM_ID"; - - protected String topicConnectionFactoryName; - - protected TopicConnection sendConnection; - protected TopicSession sendSession; - protected TopicConnection receivedConnection; - protected TopicPublisher publisher; - protected TopicSubscriber subscriber; - - public JMSBridge(EventSubject localSubject, String externalSubject) { - super(localSubject, externalSubject); - } - - /** - * @since 1.2 - */ - public JMSBridge(Collection<EventSubject> localSubjects, String externalSubject) { - super(localSubjects, externalSubject); - } - - /** - * @since 4.0 - */ - public JMSBridge(Collection<EventSubject> localSubjects, String externalSubject, Map<String, String> properties) { - super(localSubjects, externalSubject); - - // configure properties - String topicConnectionFactory = properties - .get(TOPIC_CONNECTION_FACTORY_PROPERTY); - - this.topicConnectionFactoryName = (topicConnectionFactory != null) - ? topicConnectionFactory - : TOPIC_CONNECTION_FACTORY_DEFAULT; - } - - /** - * JMS MessageListener implementation. Injects received events to the EventManager - * local event queue. - */ - public void onMessage(Message message) { - - try { - Object vmID = message.getObjectProperty(JMSBridge.VM_ID_PROPERTY); - if (JMSBridge.VM_ID.equals(vmID)) { - return; - } - - if (!(message instanceof ObjectMessage)) { - return; - } - - ObjectMessage objectMessage = (ObjectMessage) message; - CayenneEvent event = messageObjectToEvent(objectMessage.getObject()); - if (event != null) { - onExternalEvent(event); - } - - } - catch (MessageFormatException mfex) { - // TODO: Andrus, 2/8/2006 logging... Log4J was removed to make this usable on - // the client - } - catch (Exception ex) { - // TODO: Andrus, 2/8/2006 logging... Log4J was removed to make this usable on - // the client - } - } - - /** - * @return Name of javax.jms.TopicConnectionFactory accessible via JNDI. - */ - public String getTopicConnectionFactoryName() { - return topicConnectionFactoryName; - } - - public void setTopicConnectionFactoryName(String name) { - this.topicConnectionFactoryName = name; - } - - /** - * Starts up JMS machinery for "publish/subscribe" model. - */ - @Override - protected void startupExternal() throws Exception { - Context jndiContext = new InitialContext(); - TopicConnectionFactory connectionFactory = (TopicConnectionFactory) jndiContext - .lookup(topicConnectionFactoryName); - - Topic topic = null; - - try { - topic = (Topic) jndiContext.lookup(externalSubject); - } - catch (NameNotFoundException ex) { - // can't find topic, try to create it - topic = topicNotFound(jndiContext, ex); - - if (topic == null) { - throw ex; - } - } - - // config publisher - if (receivesLocalEvents()) { - this.sendConnection = connectionFactory.createTopicConnection(); - this.sendSession = sendConnection.createTopicSession( - false, - Session.AUTO_ACKNOWLEDGE); - this.publisher = sendSession.createPublisher(topic); - } - - // config subscriber - if (receivesExternalEvents()) { - this.receivedConnection = connectionFactory.createTopicConnection(); - this.subscriber = receivedConnection.createTopicSession( - false, - Session.AUTO_ACKNOWLEDGE).createSubscriber(topic); - this.subscriber.setMessageListener(this); - this.receivedConnection.start(); - } - } - - /** - * Attempts to create missing Topic. Since Topic creation is JMS-implementation - * specific, this task is left to subclasses. Current implementation simply rethrows - * the exception. - */ - protected Topic topicNotFound(Context jndiContext, NamingException ex) - throws Exception { - throw ex; - } - - /** - * Closes all resources used to communicate via JMS. - */ - @Override - protected void shutdownExternal() throws Exception { - Exception lastException = null; - - if (publisher != null) { - try { - publisher.close(); - } - catch (Exception ex) { - lastException = ex; - } - } - - if (subscriber != null) { - try { - subscriber.close(); - } - catch (Exception ex) { - lastException = ex; - } - } - - if (receivedConnection != null) { - try { - receivedConnection.close(); - } - catch (Exception ex) { - lastException = ex; - } - } - - if (sendSession != null) { - try { - sendSession.close(); - } - catch (Exception ex) { - lastException = ex; - } - } - - if (sendConnection != null) { - try { - sendConnection.close(); - } - catch (Exception ex) { - lastException = ex; - } - } - - publisher = null; - subscriber = null; - receivedConnection = null; - sendConnection = null; - sendSession = null; - - if (lastException != null) { - throw lastException; - } - } - - @Override - protected void sendExternalEvent(CayenneEvent localEvent) throws Exception { - ObjectMessage message = sendSession - .createObjectMessage(eventToMessageObject(localEvent)); - message.setObjectProperty(JMSBridge.VM_ID_PROPERTY, JMSBridge.VM_ID); - publisher.publish(message); - } - - /** - * Converts CayenneEvent to a serializable object that will be sent via JMS. Default - * implementation simply returns the event, but subclasses can customize this - * behavior. - */ - protected Serializable eventToMessageObject(CayenneEvent event) throws Exception { - return event; - } - - /** - * Converts a Serializable instance to CayenneEvent. Returns null if the object is not - * supported. Default implementation simply tries to cast the object to CayenneEvent, - * but subclasses can customize this behavior. - */ - protected CayenneEvent messageObjectToEvent(Serializable object) throws Exception { - return (object instanceof CayenneEvent) ? (CayenneEvent) object : null; - } -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java ---------------------------------------------------------------------- diff --git a/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java b/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java deleted file mode 100644 index b7772d8..0000000 --- a/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java +++ /dev/null @@ -1,39 +0,0 @@ -/***************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - ****************************************************************/ - -package org.apache.cayenne.event; - -import java.util.Collection; -import java.util.Map; - -/** - * Factory to create JMSBridge instances. - * - * @since 1.1 - */ -public class JMSBridgeFactory implements EventBridgeFactory { - - /** - * @since 1.2 - */ - public EventBridge createEventBridge(Collection<EventSubject> localSubjects, String externalSubject, Map<String, String> properties) { - return new JMSBridge(localSubjects, externalSubject, properties); - } - -} http://git-wip-us.apache.org/repos/asf/cayenne/blob/ab1fd0bf/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java ---------------------------------------------------------------------- diff --git a/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java b/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java deleted file mode 100644 index 6a06faa..0000000 --- a/eventbridges/cayenne-jms/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java +++ /dev/null @@ -1,50 +0,0 @@ -/***************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - ****************************************************************/ - -package org.apache.cayenne.event; - -import org.apache.cayenne.access.DataDomain; -import org.apache.cayenne.access.DataRowStore; -import org.apache.cayenne.configuration.Constants; -import org.apache.cayenne.di.DIRuntimeException; -import org.apache.cayenne.di.Inject; -import org.apache.cayenne.di.Provider; - -import java.util.Collections; -import java.util.Map; - -public class JMSBridgeProvider implements Provider<EventBridge> { - - @Inject - protected DataDomain dataDomain; - - @Inject(JMSModule.JMS_BRIDGE_PROPERTIES_MAP) - Map<String, String> properties; - - @Override - public EventBridge get() throws DIRuntimeException { - EventSubject snapshotEventSubject = EventSubject.getSubject(DataRowStore.class, dataDomain.getName()); - - return new JMSBridge( - Collections.singleton(snapshotEventSubject), - EventBridge.convertToExternalSubject(snapshotEventSubject), - properties); - } - -}