From 597723c796b5e58b40e33aa4f868afc56083b9df Mon Sep 17 00:00:00 2001 From: Savva Kolbachev Date: Mon, 29 Jun 2015 11:11:41 +0300 Subject: [PATCH 1/3] CAY-1873 | Add DataDomain cache configuration into DI --- .../org/apache/cayenne/access/DataDomain.java | 26 ++-- .../cayenne/access/DataRowStoreFactory.java | 38 ++++++ .../access/DefaultDataRowStoreFactory.java | 47 +++++++ .../cayenne/configuration/Constants.java | 8 ++ .../server/DataContextFactory.java | 18 ++- .../configuration/server/ServerModule.java | 5 + .../cayenne/access/DataRowStoreFactoryIT.java | 119 ++++++++++++++++++ .../server/DataContextFactoryTest.java | 7 ++ 8 files changed, 248 insertions(+), 20 deletions(-) create mode 100644 cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStoreFactory.java create mode 100644 cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java create mode 100644 cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreFactoryIT.java diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomain.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomain.java index e8ba6ff0d8..d3d0520569 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomain.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomain.java @@ -19,15 +19,6 @@ package org.apache.cayenne.access; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; - import org.apache.cayenne.CayenneRuntimeException; import org.apache.cayenne.DataChannel; import org.apache.cayenne.DataChannelFilter; @@ -54,6 +45,15 @@ import org.apache.cayenne.tx.TransactionalOperation; import org.apache.cayenne.util.ToStringBuilder; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; + /** * DataDomain performs query routing functions in Cayenne. DataDomain creates * single data source abstraction hiding multiple physical data sources from the @@ -92,6 +92,12 @@ public class DataDomain implements QueryEngine, DataChannel { @Inject protected TransactionManager transactionManager; + /** + * @since 4.0 + */ + @Inject + protected DataRowStoreFactory dataRowStoreFactory; + /** * @since 3.1 */ @@ -326,7 +332,7 @@ public DataRowStore getSharedSnapshotCache() { */ synchronized DataRowStore nonNullSharedSnapshotCache() { if (sharedSnapshotCache == null) { - this.sharedSnapshotCache = new DataRowStore(name, properties, eventManager); + this.sharedSnapshotCache = dataRowStoreFactory.createDataRowStore(name); } return sharedSnapshotCache; diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStoreFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStoreFactory.java new file mode 100644 index 0000000000..79394680bb --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStoreFactory.java @@ -0,0 +1,38 @@ +/***************************************************************** + * 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.access; + +/** + * A factory for creating {@link DataRowStore} + * + * @since 4.0 + */ +public interface DataRowStoreFactory { + + /** + * Create new {@link DataRowStore} object. + * + * @since 4.0 + * @param name DataRowStore name. Used to identify this DataRowStore in events, etc. + * Can't be null. + */ + DataRowStore createDataRowStore(String name); + +} diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java new file mode 100644 index 0000000000..f6f67fcd2c --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java @@ -0,0 +1,47 @@ +/***************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + ****************************************************************/ + +package org.apache.cayenne.access; + +import org.apache.cayenne.configuration.Constants; +import org.apache.cayenne.di.DIRuntimeException; +import org.apache.cayenne.di.Inject; +import org.apache.cayenne.event.EventManager; + +import java.util.Map; + +/** + * A default implementation of {@link DataRowStoreFactory} + * + * @since 4.0 + */ +public class DefaultDataRowStoreFactory implements DataRowStoreFactory { + + @Inject + protected EventManager eventManager; + + @Inject(Constants.DATA_ROW_STORE_PROPERTIES_MAP) + Map properties; + + @Override + public DataRowStore createDataRowStore(String name) throws DIRuntimeException { + return new DataRowStore(name, properties, eventManager); + } + +} \ No newline at end of file diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/Constants.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/Constants.java index e49f434d4f..371d3654b0 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/Constants.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/Constants.java @@ -204,4 +204,12 @@ public interface Constants { * */ public final static String QUERY_EXECUTION_TIME_LOGGING_THRESHOLD_PROPERTY = "cayenne.server.query_execution_time_logging_threshold"; + /** + * A DI container key for the Map<String, String> storing + * {@link org.apache.cayenne.access.DataRowStore} properties + * + * @since 4.0 + */ + public static final String DATA_ROW_STORE_PROPERTIES_MAP = "cayenne.server.data_row_store"; + } diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataContextFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataContextFactory.java index b6b51a164a..f5cca8b6d3 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataContextFactory.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataContextFactory.java @@ -23,13 +23,13 @@ import org.apache.cayenne.access.DataContext; import org.apache.cayenne.access.DataDomain; import org.apache.cayenne.access.DataRowStore; +import org.apache.cayenne.access.DataRowStoreFactory; import org.apache.cayenne.access.ObjectStore; import org.apache.cayenne.cache.NestedQueryCache; import org.apache.cayenne.cache.QueryCache; import org.apache.cayenne.configuration.ObjectContextFactory; import org.apache.cayenne.configuration.ObjectStoreFactory; import org.apache.cayenne.di.Inject; -import org.apache.cayenne.di.Injector; import org.apache.cayenne.event.EventManager; import org.apache.cayenne.tx.TransactionFactory; @@ -45,7 +45,7 @@ public class DataContextFactory implements ObjectContextFactory { protected EventManager eventManager; @Inject - protected Injector injector; + protected DataRowStoreFactory dataRowStoreFactory; @Inject protected ObjectStoreFactory objectStoreFactory; @@ -80,11 +80,9 @@ protected ObjectContext createFromGenericChannel(DataChannel parent) { // for new dataRowStores use the same name for all stores // it makes it easier to track the event subject - DataRowStore snapshotCache = (dataDomain.isSharedCacheEnabled()) ? dataDomain - .getSharedSnapshotCache() : new DataRowStore( - dataDomain.getName(), - dataDomain.getProperties(), - eventManager); + DataRowStore snapshotCache = (dataDomain.isSharedCacheEnabled()) + ? dataDomain.getSharedSnapshotCache() + : dataRowStoreFactory.createDataRowStore(dataDomain.getName()); DataContext context = newInstance( parent, objectStoreFactory.createObjectStore(snapshotCache)); @@ -112,9 +110,9 @@ protected ObjectContext createdFromDataDomain(DataDomain parent) { // for new dataRowStores use the same name for all stores // it makes it easier to track the event subject - DataRowStore snapshotCache = (parent.isSharedCacheEnabled()) ? parent - .getSharedSnapshotCache() : new DataRowStore(parent.getName(), parent - .getProperties(), eventManager); + DataRowStore snapshotCache = (parent.isSharedCacheEnabled()) + ? parent.getSharedSnapshotCache() + : dataRowStoreFactory.createDataRowStore(parent.getName()); DataContext context = newInstance( parent, objectStoreFactory.createObjectStore(snapshotCache)); diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java index 997a5799b4..381bc4b009 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java @@ -20,6 +20,8 @@ import org.apache.cayenne.DataChannel; import org.apache.cayenne.access.DataDomain; +import org.apache.cayenne.access.DataRowStoreFactory; +import org.apache.cayenne.access.DefaultDataRowStoreFactory; import org.apache.cayenne.access.DefaultObjectMapRetainStrategy; import org.apache.cayenne.access.ObjectMapRetainStrategy; import org.apache.cayenne.access.dbsync.SchemaUpdateStrategy; @@ -191,6 +193,9 @@ public void configure(Binder binder) { binder.bind(QueryCache.class).toProvider(MapQueryCacheProvider.class); + binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class); + binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP); + // a service to provide the main stack DataDomain binder.bind(DataDomain.class).toProvider(DataDomainProvider.class); diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreFactoryIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreFactoryIT.java new file mode 100644 index 0000000000..743368c2b6 --- /dev/null +++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreFactoryIT.java @@ -0,0 +1,119 @@ +/***************************************************************** + * 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.access; + +import org.apache.cayenne.configuration.Constants; +import org.apache.cayenne.configuration.DefaultRuntimeProperties; +import org.apache.cayenne.configuration.RuntimeProperties; +import org.apache.cayenne.configuration.server.ServerRuntime; +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.event.DefaultEventManager; +import org.apache.cayenne.event.EventManager; +import org.apache.cayenne.log.CommonsJdbcEventLogger; +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.apache.cayenne.unit.di.server.CayenneProjects; +import org.apache.cayenne.unit.di.server.ServerCase; +import org.apache.cayenne.unit.di.server.UseServerRuntime; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +@UseServerRuntime(CayenneProjects.MULTI_TIER_PROJECT) +public class DataRowStoreFactoryIT extends ServerCase { + + @Test + public void testGetDataRowStore() throws Exception { + ServerRuntime runtime = getUnitTestInjector().getInstance(ServerRuntime.class); + DataRowStore dataStore = runtime.getInjector().getInstance(DataRowStoreFactory.class) + .createDataRowStore("test"); + + assertNotNull(dataStore); + } + + @Test + public void testGetDataRowStoreWithParameters() { + final DataDomain DOMAIN = new DataDomain("test"); + final EventManager EVENT_MANAGER = new DefaultEventManager(); + final int CACHE_SIZE = 500; + final int EXPIRATION_PROPERTY = 60 * 60 * 24; + + Module testModule = new Module() { + + public void configure(Binder binder) { + binder.bindMap(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(CommonsJdbcEventLogger.class); + binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class); + binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class); + binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP) + .put(DataRowStore.SNAPSHOT_CACHE_SIZE_PROPERTY, String.valueOf(CACHE_SIZE)) + .put(DataRowStore.SNAPSHOT_EXPIRATION_PROPERTY, String.valueOf(EXPIRATION_PROPERTY)); + } + }; + + Injector injector = DIBootstrap.createInjector(testModule); + DataRowStore dataStore = injector.getInstance(DataRowStoreFactory.class) + .createDataRowStore("test"); + + assertNotNull(dataStore); + assertEquals(dataStore.maximumSize(), CACHE_SIZE); + } + + @Test + public void testGetDataRowStoreWithBridge() { + final DataDomain DOMAIN = new DataDomain("test"); + final EventManager EVENT_MANAGER = new DefaultEventManager(); + + Module testModule = new Module() { + + public void configure(Binder binder) { + binder.bindMap(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(CommonsJdbcEventLogger.class); + binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class); + binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class); + binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP); + } + }; + + Injector injector = DIBootstrap.createInjector(testModule); + DataRowStore dataStore = injector.getInstance(DataRowStoreFactory.class) + .createDataRowStore("test"); + + dataStore.stopListeners(); + dataStore.startListeners(); + dataStore.shutdown(); + } + +} diff --git a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java index cdb7e6bfdd..0304a2ed7e 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java @@ -20,10 +20,13 @@ import org.apache.cayenne.access.DataContext; import org.apache.cayenne.access.DataDomain; +import org.apache.cayenne.access.DataRowStoreFactory; +import org.apache.cayenne.access.DefaultDataRowStoreFactory; import org.apache.cayenne.access.DefaultObjectMapRetainStrategy; import org.apache.cayenne.access.ObjectMapRetainStrategy; import org.apache.cayenne.cache.MapQueryCache; import org.apache.cayenne.cache.QueryCache; +import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.configuration.DefaultObjectStoreFactory; import org.apache.cayenne.configuration.DefaultRuntimeProperties; import org.apache.cayenne.configuration.ObjectStoreFactory; @@ -74,6 +77,8 @@ public void configure(Binder binder) { binder.bind(ObjectStoreFactory.class).to(DefaultObjectStoreFactory.class); binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class); binder.bind(TransactionManager.class).to(DefaultTransactionManager.class); + binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class); + binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP); } }; @@ -111,6 +116,8 @@ public void configure(Binder binder) { binder.bind(ObjectStoreFactory.class).to(DefaultObjectStoreFactory.class); binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class); binder.bind(TransactionManager.class).to(DefaultTransactionManager.class); + binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class); + binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP); } }; From ea0b958144f9816d64bf287836b034481de3b398 Mon Sep 17 00:00:00 2001 From: Savva Kolbachev Date: Tue, 30 Jun 2015 12:05:06 +0300 Subject: [PATCH 2/3] CAY-1873 | Remove DataDomain cache configuration from the Modeler --- .../datadomain/CacheSyncConfigController.java | 337 ------------------ .../datadomain/CacheSyncConfigView.java | 103 ------ .../CustomRemoteEventsConfigPanel.java | 58 --- .../dialog/datadomain/JGroupsConfigPanel.java | 104 ------ .../dialog/datadomain/JMSConfigPanel.java | 58 --- .../modeler/editor/DataDomainView.java | 132 +------ 6 files changed, 11 insertions(+), 781 deletions(-) delete mode 100644 modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CacheSyncConfigController.java delete mode 100644 modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CacheSyncConfigView.java delete mode 100644 modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CustomRemoteEventsConfigPanel.java delete mode 100644 modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/JGroupsConfigPanel.java delete mode 100644 modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/JMSConfigPanel.java diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CacheSyncConfigController.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CacheSyncConfigController.java deleted file mode 100644 index bb43da9d2a..0000000000 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CacheSyncConfigController.java +++ /dev/null @@ -1,337 +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.modeler.dialog.datadomain; - -import java.awt.Component; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.HashMap; -import java.util.Map; - -import javax.swing.WindowConstants; - -import org.apache.cayenne.access.DataRowStore; -import org.apache.cayenne.configuration.DataChannelDescriptor; -import org.apache.cayenne.configuration.event.DomainEvent; -import org.apache.cayenne.event.JMSBridgeFactory; -import org.apache.cayenne.event.JavaGroupsBridgeFactory; -import org.apache.cayenne.modeler.ProjectController; -import org.apache.cayenne.modeler.util.CayenneController; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * A controller for CacheSyncConfigDialog and its subviews. This controller - * manages one main dialog view, and its subviews organized using CardLayout. - * - */ -public class CacheSyncConfigController extends CayenneController { - - private static Log logObj = LogFactory.getLog(CacheSyncConfigController.class); - - // using strings instead of the actioal factory classes, since we - // JMS and JavaGroups libraries may not be around, and Modeler - // may throw CNFE - private static final String JGROUPS_FACTORY_CLASS = "org.apache.cayenne.event.JavaGroupsBridgeFactory"; - private static final String JMS_FACTORY_CLASS = "org.apache.cayenne.event.JMSBridgeFactory"; - - public static final String SAVE_CONFIG_CONTROL = "Done"; - public static final String CANCEL_CONFIG_CONTROL = "Cancel"; - - public static final String JGROUPS_DEFAULT_CONTROL = "Standard Configuration"; - - public static final String JGROUPS_URL_CONTROL = "Use Configuration File"; - - public static final String JGROUPS_FACTORY_LABEL = "JavaGroups Multicast (Default)"; - public static final String JMS_FACTORY_LABEL = "JMS Transport"; - public static final String CUSTOM_FACTORY_LABEL = "Custom Transport"; - - protected Map existingCards; - protected Map properties; - protected boolean modified; - protected ProjectController eventController; - - protected CacheSyncConfigView view; - - public CacheSyncConfigController(ProjectController eventController) { - super(eventController); - this.eventController = eventController; - } - - /** - * Creates and shows a new modal dialog window. - */ - public void startup() { - DataChannelDescriptor domain = (DataChannelDescriptor)eventController.getProject().getRootNode(); - - String factory = (String) domain.getProperties().get( - DataRowStore.EVENT_BRIDGE_FACTORY_PROPERTY); - - view = new CacheSyncConfigView(); - initView(); - - properties = new HashMap(((DataChannelDescriptor)eventController.getProject() - .getRootNode()).getProperties()); - - // build cards, showing the one corresponding to DataDomain state - prepareChildren(factory); - - view.pack(); - view.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); - view.setModal(true); - makeCloseableOnEscape(); - centerView(); - view.setVisible(true); - } - - public Component getView() { - return this.view; - } - - private void initView() { - view.getCancelButton().addActionListener(new ActionListener() { - - public void actionPerformed(ActionEvent e) { - view.dispose(); - } - }); - view.getSaveButton().addActionListener(new ActionListener() { - - public void actionPerformed(ActionEvent e) { - commitChanges(); - } - }); - view.getTypeSelector().addActionListener(new ActionListener() { - - public void actionPerformed(ActionEvent e) { - selectCard(); - } - }); - } - - protected void selectCard() { - view.showCard((String)view.getTypeSelector().getSelectedItem()); - } - - protected void jgroupsDefaultConfig() { - JGroupsConfigPanel view = (JGroupsConfigPanel) existingCards - .get(JGROUPS_FACTORY_LABEL); - if (view != null) { - view.showDefaultConfig(); - } - } - - protected void jgroupsURLConfig() { - JGroupsConfigPanel view = (JGroupsConfigPanel) existingCards - .get(JGROUPS_FACTORY_LABEL); - if (view != null) { - view.showCustomConfig(); - } - } - - /** - * Stores configuration changes in the data domain properties. - */ - protected void commitChanges() { - DataChannelDescriptor domain = (DataChannelDescriptor)eventController.getProject().getRootNode(); - logObj.warn("domain properties BEFORE: " + domain.getProperties()); - - Map props = domain.getProperties(); - - String type = (String)view.getTypeSelector().getSelectedItem(); - if (JGROUPS_FACTORY_LABEL.equals(type)) { - JGroupsConfigPanel jgroupsPanel = (JGroupsConfigPanel) existingCards - .get(JGROUPS_FACTORY_LABEL); - props.put(DataRowStore.EVENT_BRIDGE_FACTORY_PROPERTY, JGROUPS_FACTORY_CLASS); - if (jgroupsPanel.useConfigFile.isSelected()) { - props.remove(JavaGroupsBridgeFactory.MCAST_ADDRESS_PROPERTY); - props.remove(JavaGroupsBridgeFactory.MCAST_PORT_PROPERTY); - if (!"".equals(jgroupsPanel.configURL.getText())) { - props.put(JavaGroupsBridgeFactory.JGROUPS_CONFIG_URL_PROPERTY, - jgroupsPanel.configURL.getText()); - } - else { - props.put(JavaGroupsBridgeFactory.JGROUPS_CONFIG_URL_PROPERTY, null); - } - } - else { - props.remove(JavaGroupsBridgeFactory.JGROUPS_CONFIG_URL_PROPERTY); - if (!"".equals(jgroupsPanel.multicastAddress.getText())) { - props.put(JavaGroupsBridgeFactory.MCAST_ADDRESS_PROPERTY, - jgroupsPanel.multicastAddress.getText()); - } - else { - props.put(JavaGroupsBridgeFactory.MCAST_ADDRESS_PROPERTY, null); - } - if (!"".equals(jgroupsPanel.multicastPort.getText())) { - props.put(JavaGroupsBridgeFactory.MCAST_PORT_PROPERTY, - jgroupsPanel.multicastPort.getText()); - } - else { - props.put(JavaGroupsBridgeFactory.MCAST_PORT_PROPERTY, null); - } - } - } - else if (JMS_FACTORY_LABEL.equals(type)) { - JMSConfigPanel jmsPanel = (JMSConfigPanel) existingCards - .get(JMS_FACTORY_LABEL); - props.put(DataRowStore.EVENT_BRIDGE_FACTORY_PROPERTY, JMS_FACTORY_CLASS); - if (!"".equals(jmsPanel.topicFactory.getText())) { - props.put(JMSBridgeFactory.TOPIC_CONNECTION_FACTORY_PROPERTY, - jmsPanel.topicFactory.getText()); - } - else { - props.put(JMSBridgeFactory.TOPIC_CONNECTION_FACTORY_PROPERTY, null); - } - } - else if (CUSTOM_FACTORY_LABEL.equals(type)) { - CustomRemoteEventsConfigPanel customPanel = (CustomRemoteEventsConfigPanel) existingCards - .get(CUSTOM_FACTORY_LABEL); - if (!"".equals(customPanel.factoryClass.getText())) { - props.put(DataRowStore.EVENT_BRIDGE_FACTORY_PROPERTY, customPanel.factoryClass.getText()); - } - else { - props.put(DataRowStore.EVENT_BRIDGE_FACTORY_PROPERTY, null); - } - } - - logObj.warn("domain properties: " + domain.getProperties()); - - eventController.fireDomainEvent(new DomainEvent(this, domain)); - - view.dispose(); - } - - protected void loadProperties(String factory) { - String configUrl = (String)properties.get(JavaGroupsBridgeFactory.JGROUPS_CONFIG_URL_PROPERTY); - String multicastAddress = (String)properties.get(JavaGroupsBridgeFactory.MCAST_ADDRESS_PROPERTY); - String multicastPort = (String)properties.get(JavaGroupsBridgeFactory.MCAST_PORT_PROPERTY); - String topicFactory = (String)properties.get(JMSBridgeFactory.TOPIC_CONNECTION_FACTORY_PROPERTY); - - JGroupsConfigPanel jgroupsPanel = (JGroupsConfigPanel) existingCards - .get(JGROUPS_FACTORY_LABEL); - - if (configUrl != null) { - jgroupsPanel.useConfigFile.setSelected(true); - jgroupsURLConfig(); - jgroupsPanel.configURL.setText(configUrl); - } - else { - jgroupsPanel.useDefaultConfig.setSelected(true); - jgroupsDefaultConfig(); - } - - if (multicastAddress != null) { - jgroupsPanel.multicastAddress.setText(multicastAddress); - } - else { - jgroupsPanel.multicastAddress.setText(JavaGroupsBridgeFactory.MCAST_ADDRESS_DEFAULT); - } - - if (multicastPort != null) { - jgroupsPanel.multicastPort.setText(multicastPort); - } - else { - jgroupsPanel.multicastPort.setText(JavaGroupsBridgeFactory.MCAST_PORT_DEFAULT); - } - - JMSConfigPanel jmsPanel = (JMSConfigPanel) existingCards - .get(JMS_FACTORY_LABEL); - - if (topicFactory != null) { - jmsPanel.topicFactory.setText(topicFactory); - } - else { - jmsPanel.topicFactory.setText(JMSBridgeFactory.TOPIC_CONNECTION_FACTORY_DEFAULT); - } - - CustomRemoteEventsConfigPanel customPanel = (CustomRemoteEventsConfigPanel) existingCards - .get(CUSTOM_FACTORY_LABEL); - String factoryClass = (String)properties.get(DataRowStore.EVENT_BRIDGE_FACTORY_PROPERTY); - if (factoryClass != null) { - customPanel.factoryClass.setText(factoryClass); - } - else { - customPanel.factoryClass.setText(DataRowStore.EVENT_BRIDGE_FACTORY_DEFAULT); - } - - if (JGROUPS_FACTORY_CLASS.equals(factory)) { - view.getTypeSelector().setSelectedItem(JGROUPS_FACTORY_LABEL); - } - else if (JMS_FACTORY_CLASS.equals(factory)) { - view.getTypeSelector().setSelectedItem(JMS_FACTORY_LABEL); - } - else { - view.getTypeSelector().setSelectedItem(CUSTOM_FACTORY_LABEL); - } - } - - protected void prepareChildren(String factory) { - existingCards = new HashMap(); - CacheSyncConfigView topView = (CacheSyncConfigView) getView(); - - // note that none of the panels need a controller - // if they issue controls, they will use this object taken from parent - - JGroupsConfigPanel jgroupsPanel = new JGroupsConfigPanel(); - existingCards.put(JGROUPS_FACTORY_LABEL, jgroupsPanel); - topView.addCard(jgroupsPanel, JGROUPS_FACTORY_LABEL); - - jgroupsPanel.getUseDefaultConfig().addActionListener(new ActionListener() { - - public void actionPerformed(ActionEvent e) { - jgroupsDefaultConfig(); - } - }); - jgroupsPanel.getUseConfigFile().addActionListener(new ActionListener() { - - public void actionPerformed(ActionEvent e) { - jgroupsURLConfig(); - } - }); - - JMSConfigPanel jmsPanel = new JMSConfigPanel(); - existingCards.put(JMS_FACTORY_LABEL, jmsPanel); - topView.addCard(jmsPanel, JMS_FACTORY_LABEL); - - CustomRemoteEventsConfigPanel customFactoryPanel = new CustomRemoteEventsConfigPanel(); - existingCards.put(CUSTOM_FACTORY_LABEL, customFactoryPanel); - topView.addCard(customFactoryPanel, CUSTOM_FACTORY_LABEL); - - if (factory == null) { - factory = DataRowStore.EVENT_BRIDGE_FACTORY_DEFAULT; - } - - if (JGROUPS_FACTORY_CLASS.equals(factory)) { - ((CacheSyncConfigView) getView()) - .showCard(JGROUPS_FACTORY_LABEL); - } - else if (JMS_FACTORY_CLASS.equals(factory)) { - ((CacheSyncConfigView) getView()) - .showCard(JMS_FACTORY_LABEL); - } - else { - ((CacheSyncConfigView) getView()) - .showCard(CUSTOM_FACTORY_LABEL); - } - - loadProperties(factory); - } -} diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CacheSyncConfigView.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CacheSyncConfigView.java deleted file mode 100644 index a9f0d51e37..0000000000 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CacheSyncConfigView.java +++ /dev/null @@ -1,103 +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.modeler.dialog.datadomain; - -import java.awt.BorderLayout; -import java.awt.CardLayout; -import java.awt.Component; -import java.awt.FlowLayout; - -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JDialog; -import javax.swing.JPanel; - -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; - -/** - */ -public class CacheSyncConfigView extends JDialog { - public static final String EMPTY_CARD_KEY = "Empty"; - - protected JPanel configPanel; - protected JComboBox typeSelector; - protected JButton saveButton; - protected JButton cancelButton; - - public CacheSyncConfigView() { - initView(); - } - - protected void initView() { - this.setLayout(new BorderLayout()); - this.setTitle("Configure Remote Cache Synchronization"); - - typeSelector = new JComboBox(); - typeSelector.addItem("JavaGroups Multicast (Default)"); - typeSelector.addItem("JMS Transport"); - typeSelector.addItem("Custom Transport"); - - saveButton = new JButton(CacheSyncConfigController.SAVE_CONFIG_CONTROL); - cancelButton = - new JButton(CacheSyncConfigController.CANCEL_CONFIG_CONTROL); - - // buttons panel - JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); - buttonPanel.add(saveButton); - buttonPanel.add(cancelButton); - - // type form - FormLayout layout = new FormLayout("right:150, 3dlu, left:200", ""); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - builder.setDefaultDialogBorder(); - builder.append("Notification Transport Type:", typeSelector); - - // config panel - configPanel = new JPanel(new CardLayout()); - addCard(new JPanel(), EMPTY_CARD_KEY); - - this.add(builder.getPanel(), BorderLayout.NORTH); - this.add(configPanel, BorderLayout.CENTER); - this.add(buttonPanel, BorderLayout.SOUTH); - - showCard(EMPTY_CARD_KEY); - } - - public void addCard(Component card, String key) { - configPanel.add(card, key); - } - - public void showCard(String key) { - ((CardLayout) configPanel.getLayout()).show(configPanel, key); - } - - public JButton getSaveButton() { - return this.saveButton; - } - - public JButton getCancelButton() { - return this.cancelButton; - } - - public JComboBox getTypeSelector() { - return this.typeSelector; - } -} diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CustomRemoteEventsConfigPanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CustomRemoteEventsConfigPanel.java deleted file mode 100644 index 82bcc4c8d4..0000000000 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/CustomRemoteEventsConfigPanel.java +++ /dev/null @@ -1,58 +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.modeler.dialog.datadomain; - -import java.awt.BorderLayout; - -import javax.swing.JPanel; -import javax.swing.JTextField; - -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; - -/** - */ -public class CustomRemoteEventsConfigPanel extends JPanel { - - protected JTextField factoryClass; - - public CustomRemoteEventsConfigPanel() { - super(); - initView(); - } - - protected void initView() { - setLayout(new BorderLayout()); - - factoryClass = new JTextField(30); - - // type form - FormLayout layout = new FormLayout("right:150, 3dlu, left:200", ""); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - builder.setDefaultDialogBorder(); - builder.appendSeparator("Custom EventBridge Factory"); - - // "1" at the end would enforce spanning the text field to - // the full width - builder.append("Factory Class:", factoryClass, 1); - - add(builder.getPanel(), BorderLayout.NORTH); - } -} diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/JGroupsConfigPanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/JGroupsConfigPanel.java deleted file mode 100644 index 0d38ef6491..0000000000 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/JGroupsConfigPanel.java +++ /dev/null @@ -1,104 +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.modeler.dialog.datadomain; - -import java.awt.BorderLayout; - -import javax.swing.ButtonGroup; -import javax.swing.JPanel; -import javax.swing.JRadioButton; -import javax.swing.JTextField; - -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; - -public class JGroupsConfigPanel extends JPanel { - - protected JTextField multicastAddress; - protected JTextField multicastPort; - protected JTextField configURL; - protected JRadioButton useDefaultConfig; - protected JRadioButton useConfigFile; - - public JGroupsConfigPanel() { - initView(); - } - - protected void initView() { - setLayout(new BorderLayout()); - - useDefaultConfig = new JRadioButton(CacheSyncConfigController.JGROUPS_DEFAULT_CONTROL); - useDefaultConfig.setSelected(true); - useConfigFile = new JRadioButton(CacheSyncConfigController.JGROUPS_URL_CONTROL); - - ButtonGroup radioGroup = new ButtonGroup(); - radioGroup.add(useConfigFile); - radioGroup.add(useDefaultConfig); - - multicastAddress = new JTextField(20); - multicastPort = new JTextField(5); - configURL = new JTextField(20); - - // type form - FormLayout layout = new FormLayout("right:150, 3dlu, left:200", ""); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - builder.setDefaultDialogBorder(); - builder.appendSeparator("JavaGroups Settings"); - - builder.append(useDefaultConfig); - builder.nextLine(); - - // "1" at the end would enforce spanning the text field to - // the full width - builder.append("Multicast Address:", multicastAddress, 1); - builder.append("Multicast Port:", multicastPort); - - builder.nextLine(); - builder.append(useConfigFile); - builder.nextLine(); - builder.append("JGroups Config File:", configURL, 1); - - add(builder.getPanel(), BorderLayout.NORTH); - } - - public void showDefaultConfig() { - multicastAddress.setEditable(true); - multicastPort.setEditable(true); - configURL.setEditable(false); - } - - public void showCustomConfig() { - multicastAddress.setEditable(false); - multicastPort.setEditable(false); - configURL.setEditable(true); - } - - public JRadioButton getUseDefaultConfig() { - return this.useDefaultConfig; - } - - public void setUseDefaultConfig(JRadioButton button) { - this.useDefaultConfig = button; - } - - public JRadioButton getUseConfigFile() { - return this.useConfigFile; - } -} diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/JMSConfigPanel.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/JMSConfigPanel.java deleted file mode 100644 index e896b533a0..0000000000 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/datadomain/JMSConfigPanel.java +++ /dev/null @@ -1,58 +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.modeler.dialog.datadomain; - -import java.awt.BorderLayout; - -import javax.swing.JPanel; -import javax.swing.JTextField; - -import com.jgoodies.forms.builder.DefaultFormBuilder; -import com.jgoodies.forms.layout.FormLayout; - -/** - */ -public class JMSConfigPanel extends JPanel { - - protected JTextField topicFactory; - - public JMSConfigPanel() { - super(); - initView(); - } - - protected void initView() { - setLayout(new BorderLayout()); - - topicFactory = new JTextField(30); - - // type form - FormLayout layout = new FormLayout("right:150, 3dlu, left:200", ""); - DefaultFormBuilder builder = new DefaultFormBuilder(layout); - builder.setDefaultDialogBorder(); - builder.appendSeparator("JMS Settings"); - - // "1" at the end would enforce spanning the text field to - // the full width - builder.append("Connection Factory Name:", topicFactory, 1); - - add(builder.getPanel(), BorderLayout.NORTH); - } -} diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainView.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainView.java index ebc5473164..7f225c8b7f 100644 --- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainView.java +++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/DataDomainView.java @@ -19,24 +19,14 @@ package org.apache.cayenne.modeler.editor; -import java.awt.BorderLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.Map; -import java.util.prefs.Preferences; - -import javax.swing.JButton; -import javax.swing.JCheckBox; -import javax.swing.JPanel; -import javax.swing.JTextField; - +import com.jgoodies.forms.builder.PanelBuilder; +import com.jgoodies.forms.layout.CellConstraints; +import com.jgoodies.forms.layout.FormLayout; import org.apache.cayenne.access.DataDomain; -import org.apache.cayenne.access.DataRowStore; import org.apache.cayenne.configuration.DataChannelDescriptor; import org.apache.cayenne.configuration.event.DomainEvent; import org.apache.cayenne.modeler.Application; import org.apache.cayenne.modeler.ProjectController; -import org.apache.cayenne.modeler.dialog.datadomain.CacheSyncConfigController; import org.apache.cayenne.modeler.event.DomainDisplayEvent; import org.apache.cayenne.modeler.event.DomainDisplayListener; import org.apache.cayenne.modeler.util.TextAdapter; @@ -44,9 +34,14 @@ import org.apache.cayenne.util.Util; import org.apache.cayenne.validation.ValidationException; -import com.jgoodies.forms.builder.PanelBuilder; -import com.jgoodies.forms.layout.CellConstraints; -import com.jgoodies.forms.layout.FormLayout; +import javax.swing.JCheckBox; +import javax.swing.JPanel; +import javax.swing.JTextField; +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Map; +import java.util.prefs.Preferences; /** * Panel for editing DataDomain. @@ -56,11 +51,7 @@ public class DataDomainView extends JPanel implements DomainDisplayListener { protected ProjectController projectController; protected TextAdapter name; - protected TextAdapter cacheSize; protected JCheckBox objectValidation; - protected JCheckBox sharedCache; - protected JCheckBox remoteUpdates; - protected JButton configRemoteUpdates; public DataDomainView(ProjectController projectController) { this.projectController = projectController; @@ -82,18 +73,7 @@ protected void updateModel(String text) { } }; - this.cacheSize = new TextAdapter(new JTextField(10)) { - - protected void updateModel(String text) { - setCacheSize(text); - } - }; - this.objectValidation = new JCheckBox(); - this.sharedCache = new JCheckBox(); - this.remoteUpdates = new JCheckBox(); - this.configRemoteUpdates = new JButton("Configure..."); - configRemoteUpdates.setEnabled(false); // assemble CellConstraints cc = new CellConstraints(); @@ -111,18 +91,6 @@ protected void updateModel(String text) { builder.addLabel("Object Validation:", cc.xy(1, 5)); builder.add(objectValidation, cc.xy(3, 5)); - builder.addSeparator("Cache Configuration", cc.xywh(1, 7, 7, 1)); - - builder.addLabel("Size of Object Cache:", cc.xy(1, 9)); - builder.add(cacheSize.getComponent(), cc.xy(3, 9)); - - builder.addLabel("Use Shared Cache:", cc.xy(1, 11)); - builder.add(sharedCache, cc.xy(3, 11)); - - builder.addLabel("Remote Change Notifications:", cc.xy(1, 13)); - builder.add(remoteUpdates, cc.xy(3, 13)); - builder.add(configRemoteUpdates, cc.xy(7, 13)); - this.setLayout(new BorderLayout()); this.add(builder.getPanel(), BorderLayout.CENTER); } @@ -142,55 +110,6 @@ public void actionPerformed(ActionEvent e) { } }); - sharedCache.addActionListener(new ActionListener() { - - public void actionPerformed(ActionEvent e) { - String value = sharedCache.isSelected() ? "true" : "false"; - setDomainProperty( - DataDomain.SHARED_CACHE_ENABLED_PROPERTY, - value, - Boolean.toString(DataDomain.SHARED_CACHE_ENABLED_DEFAULT)); - - // turning off shared cache should result in disabling remote events - - remoteUpdates.setEnabled(sharedCache.isSelected()); - - if (!sharedCache.isSelected()) { - // uncheck remote updates... - remoteUpdates.setSelected(false); - - setDomainProperty( - DataRowStore.REMOTE_NOTIFICATION_PROPERTY, - "false", - Boolean.toString(DataRowStore.REMOTE_NOTIFICATION_DEFAULT)); - } - - // depending on final remote updates status change button status - configRemoteUpdates.setEnabled(remoteUpdates.isSelected()); - } - }); - - remoteUpdates.addActionListener(new ActionListener() { - - public void actionPerformed(ActionEvent e) { - String value = remoteUpdates.isSelected() ? "true" : "false"; - - // update config button state - configRemoteUpdates.setEnabled(remoteUpdates.isSelected()); - - setDomainProperty( - DataRowStore.REMOTE_NOTIFICATION_PROPERTY, - value, - Boolean.toString(DataRowStore.REMOTE_NOTIFICATION_DEFAULT)); - } - }); - - configRemoteUpdates.addActionListener(new ActionListener() { - - public void actionPerformed(ActionEvent e) { - new CacheSyncConfigController(projectController).startup(); - } - }); } /** @@ -258,24 +177,9 @@ public void currentDomainChanged(DomainDisplayEvent e) { // extract values from the new domain object name.setText(domain.getName()); - cacheSize.setText(getDomainProperty( - DataRowStore.SNAPSHOT_CACHE_SIZE_PROPERTY, - Integer.toString(DataRowStore.SNAPSHOT_CACHE_SIZE_DEFAULT))); - objectValidation.setSelected(getDomainBooleanProperty( DataDomain.VALIDATING_OBJECTS_ON_COMMIT_PROPERTY, Boolean.toString(DataDomain.VALIDATING_OBJECTS_ON_COMMIT_DEFAULT))); - - sharedCache.setSelected(getDomainBooleanProperty( - DataDomain.SHARED_CACHE_ENABLED_PROPERTY, - Boolean.toString(DataDomain.SHARED_CACHE_ENABLED_DEFAULT))); - - remoteUpdates.setSelected(getDomainBooleanProperty( - DataRowStore.REMOTE_NOTIFICATION_PROPERTY, - Boolean.toString(DataRowStore.REMOTE_NOTIFICATION_DEFAULT))); - remoteUpdates.setEnabled(sharedCache.isSelected()); - configRemoteUpdates.setEnabled(remoteUpdates.isEnabled() - && remoteUpdates.isSelected()); } void setDomainName(String newName) { @@ -304,18 +208,4 @@ void setDomainName(String newName) { RenamedPreferences.copyPreferences(newName, prefs); projectController.fireDomainEvent(e); } - - void setCacheSize(String text) { - if (text.length() > 0) { - try { - Integer.parseInt(text); - } - catch (NumberFormatException ex) { - throw new ValidationException("Cache size must be an integer: " + text); - } - } - - setDomainProperty(DataRowStore.SNAPSHOT_CACHE_SIZE_PROPERTY, text, Integer - .toString(DataRowStore.SNAPSHOT_CACHE_SIZE_DEFAULT)); - } } From aa313fd94f47933c3c4ddfa2d2aa78d33d721b52 Mon Sep 17 00:00:00 2001 From: Savva Kolbachev Date: Thu, 2 Jul 2015 18:32:01 +0300 Subject: [PATCH 3/3] CAY-1873 | Move DataDomain cache configuration from the Modeler and into DI --- .../org/apache/cayenne/access/DataDomain.java | 19 ++- .../apache/cayenne/access/DataRowStore.java | 120 +++++++--------- .../access/DefaultDataRowStoreFactory.java | 20 ++- .../cayenne/configuration/Constants.java | 24 ++++ .../server/DataDomainProvider.java | 8 +- .../configuration/server/ServerModule.java | 4 + .../cayenne/event/EventBridgeFactory.java | 2 +- .../cayenne/event/EventBridgeProvider.java | 60 ++++++++ .../org/apache/cayenne/event/JMSBridge.java | 35 ++++- .../cayenne/event/JMSBridgeFactory.java | 19 +-- .../cayenne/event/JMSBridgeProvider.java | 50 +++++++ .../cayenne/event/JavaGroupsBridge.java | 33 ++++- .../event/JavaGroupsBridgeFactory.java | 109 +-------------- .../event/JavaGroupsBridgeProvider.java | 50 +++++++ .../org/apache/cayenne/event/XMPPBridge.java | 62 +++++++-- .../cayenne/event/XMPPBridgeFactory.java | 53 +------ .../cayenne/event/XMPPBridgeProvider.java | 50 +++++++ .../apache/cayenne/access/DataRowStoreIT.java | 33 ----- ...java => DefaultDataRowStoreFactoryIT.java} | 12 +- .../cayenne/access/MockDataRowStore.java | 7 +- .../server/DataContextFactoryTest.java | 7 + .../server/DataDomainProviderTest.java | 8 ++ .../cayenne/event/JMSBridgeFactoryTest.java | 77 +++++++++++ .../cayenne/event/JMSBridgeProviderTest.java | 119 ++++++++++++++++ .../event/JavaGroupsBridgeFactoryTest.java | 84 +++++++++++ .../event/JavaGroupsBridgeProviderTest.java | 123 +++++++++++++++++ ...Test.java => MockEventBridgeProvider.java} | 31 ++--- .../cayenne/event/XMPPBridgeFactoryTest.java | 47 ++++--- .../cayenne/event/XMPPBridgeProviderTest.java | 130 ++++++++++++++++++ 29 files changed, 1049 insertions(+), 347 deletions(-) create mode 100644 cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeProvider.java create mode 100644 cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java create mode 100644 cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java create mode 100644 cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java rename cayenne-server/src/test/java/org/apache/cayenne/access/{DataRowStoreFactoryIT.java => DefaultDataRowStoreFactoryIT.java} (91%) create mode 100644 cayenne-server/src/test/java/org/apache/cayenne/event/JMSBridgeFactoryTest.java create mode 100644 cayenne-server/src/test/java/org/apache/cayenne/event/JMSBridgeProviderTest.java create mode 100644 cayenne-server/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeFactoryTest.java create mode 100644 cayenne-server/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java rename cayenne-server/src/test/java/org/apache/cayenne/event/{JGroupsBridgeFactoryTest.java => MockEventBridgeProvider.java} (62%) create mode 100644 cayenne-server/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomain.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomain.java index d3d0520569..4a42d21033 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomain.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DataDomain.java @@ -92,12 +92,6 @@ public class DataDomain implements QueryEngine, DataChannel { @Inject protected TransactionManager transactionManager; - /** - * @since 4.0 - */ - @Inject - protected DataRowStoreFactory dataRowStoreFactory; - /** * @since 3.1 */ @@ -127,6 +121,11 @@ public class DataDomain implements QueryEngine, DataChannel { */ protected EventManager eventManager; + /** + * @since 4.0 + */ + protected DataRowStoreFactory dataRowStoreFactory; + /** * @since 1.2 */ @@ -255,6 +254,14 @@ public void setEventManager(EventManager eventManager) { } } + public DataRowStoreFactory getDataRowStoreFactory() { + return dataRowStoreFactory; + } + + public void setDataRowStoreFactory(DataRowStoreFactory dataRowStoreFactory) { + this.dataRowStoreFactory = dataRowStoreFactory; + } + /** * Returns "name" property value. */ diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStore.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStore.java index 54454734b6..e16d834333 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStore.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DataRowStore.java @@ -19,17 +19,6 @@ package org.apache.cayenne.access; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.Serializable; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentMap; - import org.apache.cayenne.CayenneRuntimeException; import org.apache.cayenne.DataObject; import org.apache.cayenne.DataRow; @@ -38,7 +27,6 @@ import org.apache.cayenne.Persistent; import org.apache.cayenne.access.event.SnapshotEvent; import org.apache.cayenne.event.EventBridge; -import org.apache.cayenne.event.EventBridgeFactory; import org.apache.cayenne.event.EventManager; import org.apache.cayenne.event.EventSubject; import org.apache.cayenne.util.concurrentlinkedhashmap.ConcurrentLinkedHashMap; @@ -46,9 +34,20 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentMap; + /** * A fixed size cache of DataRows keyed by ObjectId. - * + * * @since 1.1 */ public class DataRowStore implements Serializable { @@ -58,7 +57,18 @@ public class DataRowStore implements Serializable { // property keys public static final String SNAPSHOT_EXPIRATION_PROPERTY = "cayenne.DataRowStore.snapshot.expiration"; public static final String SNAPSHOT_CACHE_SIZE_PROPERTY = "cayenne.DataRowStore.snapshot.size"; + + /** + * @deprecated since 4.0.M3 does nothing. Previously it used to check + * if need to create {@link EventBridge}. + */ + @Deprecated public static final String REMOTE_NOTIFICATION_PROPERTY = "cayenne.DataRowStore.remote.notify"; + + /** + * @deprecated since 4.0.M3 {@link DataRowStoreFactory} establishes {@link EventBridge}. + */ + @Deprecated public static final String EVENT_BRIDGE_FACTORY_PROPERTY = "cayenne.DataRowStore.EventBridge.factory"; // default property values @@ -66,15 +76,24 @@ public class DataRowStore implements Serializable { // default expiration time is 2 hours public static final long SNAPSHOT_EXPIRATION_DEFAULT = 2 * 60 * 60; public static final int SNAPSHOT_CACHE_SIZE_DEFAULT = 10000; + + @Deprecated public static final boolean REMOTE_NOTIFICATION_DEFAULT = false; // use String for class name, since JavaGroups may not be around, // causing CNF exceptions + @Deprecated public static final String EVENT_BRIDGE_FACTORY_DEFAULT = "org.apache.cayenne.event.JavaGroupsBridgeFactory"; protected String name; private int maxSize; protected ConcurrentMap snapshots; + + /** + * @deprecated since 4.0.M3 does nothing. Previously it used to check + * if need to create {@link EventBridge}. + */ + @Deprecated protected boolean notifyingRemoteListeners; protected transient EventManager eventManager; @@ -87,13 +106,13 @@ public class DataRowStore implements Serializable { /** * Creates new DataRowStore with a specified name and a set of properties. If no * properties are defined, default values are used. - * - * @param name DataRowStore name. Used to idenitfy this DataRowStore in events, etc. - * Can't be null. - * @param properties Properties map used to configure DataRowStore parameters. Can be - * null. + * + * @param name DataRowStore name. Used to identify this DataRowStore in events, etc. + * Can't be null. + * @param properties Properties map used to configure DataRowStore parameters. Can be + * null. * @param eventManager EventManager that should be used for posting and receiving - * events. + * events. * @since 1.2 */ public DataRowStore(String name, Map properties, EventManager eventManager) { @@ -126,14 +145,6 @@ protected void initWithProperties(Map properties) { SNAPSHOT_CACHE_SIZE_PROPERTY, SNAPSHOT_CACHE_SIZE_DEFAULT); - boolean notifyRemote = propertiesWrapper.getBoolean( - REMOTE_NOTIFICATION_PROPERTY, - REMOTE_NOTIFICATION_DEFAULT); - - String eventBridgeFactory = propertiesWrapper.getString( - EVENT_BRIDGE_FACTORY_PROPERTY, - EVENT_BRIDGE_FACTORY_DEFAULT); - if (logger.isDebugEnabled()) { logger.debug("DataRowStore property " + SNAPSHOT_EXPIRATION_PROPERTY @@ -143,49 +154,25 @@ protected void initWithProperties(Map properties) { + SNAPSHOT_CACHE_SIZE_PROPERTY + " = " + maxSize); - logger.debug("DataRowStore property " - + REMOTE_NOTIFICATION_PROPERTY - + " = " - + notifyRemote); - logger.debug("DataRowStore property " - + EVENT_BRIDGE_FACTORY_PROPERTY - + " = " - + eventBridgeFactory); } - // init ivars from properties - this.notifyingRemoteListeners = notifyRemote; - this.snapshots = new ConcurrentLinkedHashMap.Builder() .maximumWeightedCapacity(maxSize) .build(); - // init event bridge only if we are notifying remote listeners - if (notifyingRemoteListeners) { - try { - EventBridgeFactory factory = (EventBridgeFactory) Class.forName( - eventBridgeFactory).newInstance(); - - Collection subjects = Collections - .singleton(getSnapshotEventSubject()); - String externalSubject = EventBridge - .convertToExternalSubject(getSnapshotEventSubject()); - this.remoteNotificationsHandler = factory.createEventBridge( - subjects, - externalSubject, - properties); - } - catch (Exception ex) { - throw new CayenneRuntimeException("Error initializing DataRowStore.", ex); - } + } - startListeners(); - } + protected void setEventBridge(EventBridge eventBridge) { + remoteNotificationsHandler = eventBridge; + } + + protected EventBridge getEventBridge() { + return remoteNotificationsHandler; } /** * Updates cached snapshots for the list of objects. - * + * * @since 1.2 */ void snapshotsUpdatedForObjects(List objects, List snapshots, boolean refresh) { @@ -235,8 +222,7 @@ void snapshotsUpdatedForObjects(List objects, List snapshots, boolean refresh) { ((DataObject) object).setSnapshotVersion(cachedSnapshot .getVersion()); continue; - } - else { + } else { newSnapshot.setReplacesVersion(cachedSnapshot.getVersion()); } } @@ -300,7 +286,7 @@ public void setName(String name) { /** * Returns an EventManager associated with this DataRowStore. - * + * * @since 1.2 */ public EventManager getEventManager() { @@ -309,7 +295,7 @@ public EventManager getEventManager() { /** * Sets an EventManager associated with this DataRowStore. - * + * * @since 1.2 */ public void setEventManager(EventManager eventManager) { @@ -554,10 +540,12 @@ private void sendUpdateNotification( } } + @Deprecated public boolean isNotifyingRemoteListeners() { return notifyingRemoteListeners; } + @Deprecated public void setNotifyingRemoteListeners(boolean notifyingRemoteListeners) { this.notifyingRemoteListeners = notifyingRemoteListeners; } @@ -580,8 +568,7 @@ void stopListeners() { if (remoteNotificationsHandler != null) { try { remoteNotificationsHandler.shutdown(); - } - catch (Exception ex) { + } catch (Exception ex) { logger.info("Exception shutting down EventBridge.", ex); } remoteNotificationsHandler = null; @@ -613,8 +600,7 @@ void startListeners() { remoteNotificationsHandler.startup( eventManager, EventBridge.RECEIVE_LOCAL_EXTERNAL); - } - catch (Exception ex) { + } catch (Exception ex) { throw new CayenneRuntimeException( "Error initializing DataRowStore.", ex); diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java index f6f67fcd2c..a3397b3e00 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/access/DefaultDataRowStoreFactory.java @@ -19,9 +19,12 @@ package org.apache.cayenne.access; +import org.apache.cayenne.CayenneRuntimeException; import org.apache.cayenne.configuration.Constants; import org.apache.cayenne.di.DIRuntimeException; import org.apache.cayenne.di.Inject; +import org.apache.cayenne.di.Injector; +import org.apache.cayenne.event.EventBridge; import org.apache.cayenne.event.EventManager; import java.util.Map; @@ -33,6 +36,9 @@ */ public class DefaultDataRowStoreFactory implements DataRowStoreFactory { + @Inject + protected Injector injector; + @Inject protected EventManager eventManager; @@ -41,7 +47,19 @@ public class DefaultDataRowStoreFactory implements DataRowStoreFactory { @Override public DataRowStore createDataRowStore(String name) throws DIRuntimeException { - return new DataRowStore(name, properties, eventManager); + DataRowStore store = new DataRowStore( + name, + properties, + eventManager); + + try { + store.setEventBridge(injector.getInstance(EventBridge.class)); + store.startListeners(); + } catch (Exception ex) { + throw new CayenneRuntimeException("Error initializing DataRowStore.", ex); + } + + return store; } } \ No newline at end of file diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/Constants.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/Constants.java index 371d3654b0..dcddb84053 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/Constants.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/Constants.java @@ -212,4 +212,28 @@ public interface Constants { */ public static final String DATA_ROW_STORE_PROPERTIES_MAP = "cayenne.server.data_row_store"; + /** + * A DI container key for the Map<String, String> storing + * {@link org.apache.cayenne.event.JMSBridge} properties + * + * @since 4.0 + */ + public static final String JMS_BRIDGE_PROPERTIES_MAP = "cayenne.server.jms_bridge"; + + /** + * 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"; + + /** + * 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"; + } diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataDomainProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataDomainProvider.java index 4815fe4c5d..6a62b8aa5f 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataDomainProvider.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/DataDomainProvider.java @@ -18,14 +18,12 @@ ****************************************************************/ package org.apache.cayenne.configuration.server; -import java.util.Collection; -import java.util.List; - import org.apache.cayenne.ConfigurationException; import org.apache.cayenne.DataChannel; import org.apache.cayenne.DataChannelFilter; import org.apache.cayenne.access.DataDomain; import org.apache.cayenne.access.DataNode; +import org.apache.cayenne.access.DataRowStoreFactory; import org.apache.cayenne.cache.NestedQueryCache; import org.apache.cayenne.cache.QueryCache; import org.apache.cayenne.configuration.ConfigurationTree; @@ -46,6 +44,9 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import java.util.Collection; +import java.util.List; + /** * A {@link DataChannel} provider that provides a single instance of DataDomain * configured per configuration supplied via injected @@ -122,6 +123,7 @@ protected DataDomain createAndInitDataDomain() throws Exception { dataDomain.setQueryCache(new NestedQueryCache(queryCache)); dataDomain.setEntitySorter(injector.getInstance(EntitySorter.class)); dataDomain.setEventManager(injector.getInstance(EventManager.class)); + dataDomain.setDataRowStoreFactory(injector.getInstance(DataRowStoreFactory.class)); dataDomain.initWithProperties(descriptor.getProperties()); diff --git a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java index 381bc4b009..fc647438d7 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/configuration/server/ServerModule.java @@ -91,6 +91,8 @@ import org.apache.cayenne.di.spi.DefaultAdhocObjectFactory; import org.apache.cayenne.di.spi.DefaultClassLoaderManager; import org.apache.cayenne.event.DefaultEventManager; +import org.apache.cayenne.event.EventBridgeProvider; +import org.apache.cayenne.event.EventBridge; import org.apache.cayenne.event.EventManager; import org.apache.cayenne.log.CommonsJdbcEventLogger; import org.apache.cayenne.log.JdbcEventLogger; @@ -193,6 +195,8 @@ public void configure(Binder binder) { binder.bind(QueryCache.class).toProvider(MapQueryCacheProvider.class); + binder.bind(EventBridge.class).toProvider(EventBridgeProvider.class); + binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class); binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP); diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeFactory.java index 7d5ecdc043..dc59d0d5e2 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeFactory.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeFactory.java @@ -30,7 +30,7 @@ public interface EventBridgeFactory { /** - * Creates an EventBridge with the specified parameters. + * Creates an {@link EventBridge} with the specified parameters. * * @since 1.2 */ diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeProvider.java new file mode 100644 index 0000000000..ef78fb7155 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/event/EventBridgeProvider.java @@ -0,0 +1,60 @@ +/***************************************************************** + * 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.di.DIRuntimeException; +import org.apache.cayenne.di.Inject; +import org.apache.cayenne.di.Provider; + +import java.util.Collections; + +public class EventBridgeProvider implements Provider { + + @Inject + protected DataDomain dataDomain; + + @Override + public EventBridge get() throws DIRuntimeException { + EventSubject snapshotEventSubject = EventSubject.getSubject(DataRowStore.class.getClass(), dataDomain.getName()); + + return new EventBridge( + Collections.singleton(snapshotEventSubject), + EventBridge.convertToExternalSubject(snapshotEventSubject)) { + + @Override + protected void startupExternal() throws Exception { + + } + + @Override + protected void shutdownExternal() throws Exception { + + } + + @Override + protected void sendExternalEvent(CayenneEvent localEvent) throws Exception { + + } + }; + } + +} diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridge.java b/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridge.java index 41ce7eb3ff..0b746fc7b6 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridge.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridge.java @@ -19,8 +19,7 @@ package org.apache.cayenne.event; -import java.io.Serializable; -import java.util.Collection; +import org.apache.cayenne.util.IDUtil; import javax.jms.Message; import javax.jms.MessageFormatException; @@ -37,8 +36,9 @@ import javax.naming.InitialContext; import javax.naming.NameNotFoundException; import javax.naming.NamingException; - -import org.apache.cayenne.util.IDUtil; +import java.io.Serializable; +import java.util.Collection; +import java.util.Map; /** * Implementation of EventBridge that passes and receives events via JMS (Java Messaging @@ -49,8 +49,14 @@ */ 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_PROPERRTY = "VM_ID"; + static final String VM_ID_PROPERTY = "VM_ID"; protected String topicConnectionFactoryName; @@ -71,6 +77,21 @@ public JMSBridge(Collection localSubjects, String externalSubject) super(localSubjects, externalSubject); } + /** + * @since 4.0 + */ + public JMSBridge(Collection localSubjects, String externalSubject, Map 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. @@ -78,7 +99,7 @@ public JMSBridge(Collection localSubjects, String externalSubject) public void onMessage(Message message) { try { - Object vmID = message.getObjectProperty(JMSBridge.VM_ID_PROPERRTY); + Object vmID = message.getObjectProperty(JMSBridge.VM_ID_PROPERTY); if (JMSBridge.VM_ID.equals(vmID)) { return; } @@ -235,7 +256,7 @@ protected void shutdownExternal() throws Exception { protected void sendExternalEvent(CayenneEvent localEvent) throws Exception { ObjectMessage message = sendSession .createObjectMessage(eventToMessageObject(localEvent)); - message.setObjectProperty(JMSBridge.VM_ID_PROPERRTY, JMSBridge.VM_ID); + message.setObjectProperty(JMSBridge.VM_ID_PROPERTY, JMSBridge.VM_ID); publisher.publish(message); } diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java index d727365511..b7772d8872 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeFactory.java @@ -29,26 +29,11 @@ */ public class JMSBridgeFactory implements EventBridgeFactory { - // 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"; - /** * @since 1.2 */ public EventBridge createEventBridge(Collection localSubjects, String externalSubject, Map properties) { - JMSBridge bridge = new JMSBridge(localSubjects, externalSubject); - - // configure properties - String topicConnectionFactory = properties - .get(TOPIC_CONNECTION_FACTORY_PROPERTY); - - bridge.setTopicConnectionFactoryName(topicConnectionFactory != null - ? topicConnectionFactory - : TOPIC_CONNECTION_FACTORY_DEFAULT); - - return bridge; + return new JMSBridge(localSubjects, externalSubject, properties); } + } diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.java new file mode 100644 index 0000000000..217c5b3517 --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/event/JMSBridgeProvider.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 JMSBridgeProvider implements Provider { + + @Inject + protected DataDomain dataDomain; + + @Inject(Constants.JMS_BRIDGE_PROPERTIES_MAP) + Map 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); + } + +} diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java b/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java index e7438effcb..44ea4f0a00 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridge.java @@ -19,15 +19,16 @@ package org.apache.cayenne.event; -import java.io.Serializable; -import java.util.Collection; - 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. @@ -36,6 +37,17 @@ */ public class JavaGroupsBridge extends EventBridge implements MessageListener { + public static final String MCAST_ADDRESS_DEFAULT = "228.0.0.5"; + public static final String MCAST_PORT_DEFAULT = "22222"; + + 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; @@ -59,6 +71,21 @@ public JavaGroupsBridge(Collection localSubjects, String externalS super(localSubjects, externalSubject); } + /** + * @since 4.0 + */ + public JavaGroupsBridge(Collection localSubjects, String externalSubject, Map 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; } diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java index 8ad7efe41e..302e5ca2bc 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeFactory.java @@ -19,35 +19,19 @@ package org.apache.cayenne.event; -import java.lang.reflect.Constructor; import java.util.Collection; -import java.util.Collections; import java.util.Map; -import org.apache.cayenne.CayenneRuntimeException; -import org.apache.cayenne.reflect.PropertyUtils; - /** * Factory to create JavaGroupsBridge instances. If JavaGroups library is not installed * this factory will return a noop EventBridge as a failover mechanism. - * + *

* For further information about JavaGroups consult the documentation. - * + * * @since 1.1 */ public class JavaGroupsBridgeFactory implements EventBridgeFactory { - public static final String MCAST_ADDRESS_DEFAULT = "228.0.0.5"; - public static final String MCAST_PORT_DEFAULT = "22222"; - - 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"; - /** * Creates a JavaGroupsBridge instance. Since JavaGroups is not shipped with Cayenne * and should be installed separately, a common misconfiguration problem may be the @@ -59,94 +43,7 @@ public EventBridge createEventBridge( Collection localSubjects, String externalSubject, Map properties) { - - try { - // sniff JavaGroups presence - Class.forName("org.jgroups.Channel"); - return createJavaGroupsBridge(localSubjects, externalSubject, properties); - } - catch (Exception ex) { - // recover from no JavaGroups - return createNoopBridge(); - } - } - - private EventBridge createNoopBridge() { - return new NoopEventBridge(); + return new JavaGroupsBridge(localSubjects, externalSubject, properties); } - private EventBridge createJavaGroupsBridge( - Collection localSubjects, - String externalSubject, - Map properties) { - - // create JavaGroupsBridge using reflection to avoid triggering - // ClassNotFound exceptions due to JavaGroups absence. - - try { - Constructor c = Class - .forName("org.apache.cayenne.event.JavaGroupsBridge") - .getConstructor(Collection.class, String.class); - - Object bridge = c.newInstance(localSubjects, externalSubject); - - // configure properties - String multicastAddress = properties.get(MCAST_ADDRESS_PROPERTY); - String multicastPort = properties.get(MCAST_PORT_PROPERTY); - String configURL = properties.get(JGROUPS_CONFIG_URL_PROPERTY); - - PropertyUtils.setProperty(bridge, "configURL", configURL); - PropertyUtils.setProperty( - bridge, - "multicastAddress", - multicastAddress != null ? multicastAddress : MCAST_ADDRESS_DEFAULT); - PropertyUtils.setProperty(bridge, "multicastPort", multicastPort != null - ? multicastPort - : MCAST_PORT_DEFAULT); - - return (EventBridge) bridge; - } - catch (Exception ex) { - throw new CayenneRuntimeException("Error creating JavaGroupsBridge", ex); - } - } - - // mockup EventBridge - class NoopEventBridge extends EventBridge { - - public NoopEventBridge() { - super(Collections.emptySet(), null); - } - - @Override - public boolean receivesExternalEvents() { - return false; - } - - @Override - public boolean receivesLocalEvents() { - return false; - } - - @Override - protected void startupExternal() { - } - - @Override - protected void shutdownExternal() { - } - - @Override - protected void sendExternalEvent(CayenneEvent localEvent) { - } - - @Override - public void startup(EventManager eventManager, int mode, Object eventsSource) { - this.eventManager = eventManager; - } - - @Override - public void shutdown() { - } - } } diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.java new file mode 100644 index 0000000000..191872d52c --- /dev/null +++ b/cayenne-server/src/main/java/org/apache/cayenne/event/JavaGroupsBridgeProvider.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 JavaGroupsBridgeProvider implements Provider { + + @Inject + protected DataDomain dataDomain; + + @Inject(Constants.JAVA_GROUPS_BRIDGE_PROPERTIES_MAP) + Map 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); + } + +} diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridge.java b/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridge.java index a533f0c365..10a1386531 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridge.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridge.java @@ -19,13 +19,9 @@ package org.apache.cayenne.event; -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 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; @@ -33,9 +29,14 @@ import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.Message; import org.jivesoftware.smack.packet.Packet; -import org.apache.cayenne.CayenneRuntimeException; -import org.apache.cayenne.util.Base64Codec; -import org.apache.cayenne.util.Util; + +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. @@ -52,6 +53,22 @@ */ 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; @@ -86,6 +103,31 @@ public XMPPBridge(Collection localSubjects, String externalSubject this.sessionHandle = "cayenne-xmpp-" + System.currentTimeMillis(); } + public XMPPBridge(Collection localSubjects, String externalSubject, Map 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); + int port = -1; + if (portString != null) { + + try { + this.xmppPort = Integer.parseInt(portString); + } + catch (NumberFormatException e) { + throw new CayenneRuntimeException("Invalid port: " + portString); + } + } + } + public String getXmppHost() { return xmppHost; } diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java b/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java index bb72158f46..79347529a7 100644 --- a/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java +++ b/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeFactory.java @@ -22,8 +22,6 @@ import java.util.Collection; import java.util.Map; -import org.apache.cayenne.CayenneRuntimeException; - /** * A factory of XMPPBridge. Note that to deploy an XMPPBridge, you need to have * smack.jar library in the runtime. @@ -32,59 +30,12 @@ */ public class XMPPBridgeFactory implements EventBridgeFactory { - 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"; - @Override public EventBridge createEventBridge( Collection localSubjects, String externalSubject, Map properties) { - - String chatService = properties.get(XMPP_CHAT_SERVICE_PROPERTY); - String host = properties.get(XMPP_HOST_PROPERTY); - - String loginId = properties.get(XMPP_LOGIN_PROPERTY); - String password = properties.get(XMPP_PASSWORD_PROPERTY); - - String secureConnectionString = properties - .get(XMPP_SECURE_CONNECTION_PROPERTY); - boolean secureConnection = "true".equalsIgnoreCase(secureConnectionString); - - String portString = properties.get(XMPP_PORT_PROPERTY); - int port = -1; - if (portString != null) { - - try { - port = Integer.parseInt(portString); - } - catch (NumberFormatException e) { - throw new CayenneRuntimeException("Invalid port: " + portString); - } - } - - XMPPBridge bridge = new XMPPBridge(localSubjects, externalSubject); - - bridge.setXmppHost(host); - bridge.setXmppPort(port); - bridge.setChatService(chatService); - bridge.setSecureConnection(secureConnection); - bridge.setLoginId(loginId); - bridge.setPassword(password); - - return bridge; + return new XMPPBridge(localSubjects, externalSubject, properties); } + } diff --git a/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java b/cayenne-server/src/main/java/org/apache/cayenne/event/XMPPBridgeProvider.java new file mode 100644 index 0000000000..ae577f23fd --- /dev/null +++ b/cayenne-server/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 { + + @Inject + protected DataDomain dataDomain; + + @Inject(Constants.XMPP_BRIDGE_PROPERTIES_MAP) + Map 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); + } + +} diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreIT.java index 6a15123611..747eeb1640 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreIT.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreIT.java @@ -49,39 +49,6 @@ public void testDefaultConstructor() { assertEquals("cacheXYZ", cache.getName()); assertNotNull(cache.getSnapshotEventSubject()); assertTrue(cache.getSnapshotEventSubject().getSubjectName().contains("cacheXYZ")); - - assertEquals(DataRowStore.REMOTE_NOTIFICATION_DEFAULT, cache - .isNotifyingRemoteListeners()); - } - - @Test - public void testConstructorWithProperties() { - Map props = new HashMap(); - props.put(DataRowStore.REMOTE_NOTIFICATION_PROPERTY, String - .valueOf(!DataRowStore.REMOTE_NOTIFICATION_DEFAULT)); - - DataRowStore cache = new DataRowStore( - "cacheXYZ", - props, - new DefaultEventManager()); - assertEquals("cacheXYZ", cache.getName()); - assertEquals(!DataRowStore.REMOTE_NOTIFICATION_DEFAULT, cache - .isNotifyingRemoteListeners()); - } - - @Test - public void testNotifyingRemoteListeners() { - DataRowStore cache = new DataRowStore( - "cacheXYZ", - Collections.EMPTY_MAP, - new DefaultEventManager()); - - assertEquals(DataRowStore.REMOTE_NOTIFICATION_DEFAULT, cache - .isNotifyingRemoteListeners()); - - cache.setNotifyingRemoteListeners(!DataRowStore.REMOTE_NOTIFICATION_DEFAULT); - assertEquals(!DataRowStore.REMOTE_NOTIFICATION_DEFAULT, cache - .isNotifyingRemoteListeners()); } /** diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreFactoryIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DefaultDataRowStoreFactoryIT.java similarity index 91% rename from cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreFactoryIT.java rename to cayenne-server/src/test/java/org/apache/cayenne/access/DefaultDataRowStoreFactoryIT.java index 743368c2b6..2621443d17 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/access/DataRowStoreFactoryIT.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DefaultDataRowStoreFactoryIT.java @@ -28,7 +28,11 @@ import org.apache.cayenne.di.Injector; import org.apache.cayenne.di.Module; import org.apache.cayenne.event.DefaultEventManager; +import org.apache.cayenne.event.EventBridge; +import org.apache.cayenne.event.EventBridgeProvider; import org.apache.cayenne.event.EventManager; +import org.apache.cayenne.event.MockEventBridge; +import org.apache.cayenne.event.MockEventBridgeProvider; import org.apache.cayenne.log.CommonsJdbcEventLogger; import org.apache.cayenne.log.JdbcEventLogger; import org.apache.cayenne.tx.DefaultTransactionFactory; @@ -44,7 +48,7 @@ import static org.junit.Assert.assertNotNull; @UseServerRuntime(CayenneProjects.MULTI_TIER_PROJECT) -public class DataRowStoreFactoryIT extends ServerCase { +public class DefaultDataRowStoreFactoryIT extends ServerCase { @Test public void testGetDataRowStore() throws Exception { @@ -72,6 +76,7 @@ public void configure(Binder binder) { binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class); binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class); binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class); + binder.bind(EventBridge.class).toProvider(EventBridgeProvider.class); binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class); binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP) .put(DataRowStore.SNAPSHOT_CACHE_SIZE_PROPERTY, String.valueOf(CACHE_SIZE)) @@ -102,6 +107,7 @@ public void configure(Binder binder) { binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class); binder.bind(JdbcEventLogger.class).to(CommonsJdbcEventLogger.class); binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class); + binder.bind(EventBridge.class).toProvider(MockEventBridgeProvider.class); binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class); binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP); } @@ -111,9 +117,7 @@ public void configure(Binder binder) { DataRowStore dataStore = injector.getInstance(DataRowStoreFactory.class) .createDataRowStore("test"); - dataStore.stopListeners(); - dataStore.startListeners(); - dataStore.shutdown(); + assertEquals(dataStore.getEventBridge().getClass(), MockEventBridge.class); } } diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/MockDataRowStore.java b/cayenne-server/src/test/java/org/apache/cayenne/access/MockDataRowStore.java index dba5c98068..76ac2cb0b6 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/access/MockDataRowStore.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/access/MockDataRowStore.java @@ -19,13 +19,13 @@ package org.apache.cayenne.access; -import java.util.HashMap; -import java.util.Map; - import org.apache.cayenne.DataRow; import org.apache.cayenne.ObjectId; import org.apache.cayenne.event.MockEventManager; +import java.util.HashMap; +import java.util.Map; + /** * A "lightweight" DataRowStore. */ @@ -35,7 +35,6 @@ public class MockDataRowStore extends DataRowStore { static { TEST_DEFAULTS.put(DataRowStore.SNAPSHOT_CACHE_SIZE_PROPERTY, new Integer(10)); - TEST_DEFAULTS.put(DataRowStore.REMOTE_NOTIFICATION_PROPERTY, Boolean.FALSE); } public MockDataRowStore() { diff --git a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java index 0304a2ed7e..32477cbb3c 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataContextFactoryTest.java @@ -35,6 +35,8 @@ import org.apache.cayenne.di.DIBootstrap; import org.apache.cayenne.di.Injector; import org.apache.cayenne.di.Module; +import org.apache.cayenne.event.EventBridgeProvider; +import org.apache.cayenne.event.EventBridge; import org.apache.cayenne.event.EventManager; import org.apache.cayenne.event.MockEventManager; import org.apache.cayenne.log.CommonsJdbcEventLogger; @@ -78,6 +80,8 @@ public void configure(Binder binder) { binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class); binder.bind(TransactionManager.class).to(DefaultTransactionManager.class); binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class); + binder.bind(EventBridge.class).toProvider(EventBridgeProvider.class); + binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class); binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP); } }; @@ -116,6 +120,7 @@ public void configure(Binder binder) { binder.bind(ObjectStoreFactory.class).to(DefaultObjectStoreFactory.class); binder.bind(TransactionFactory.class).to(DefaultTransactionFactory.class); binder.bind(TransactionManager.class).to(DefaultTransactionManager.class); + binder.bind(EventBridge.class).toProvider(EventBridgeProvider.class); binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class); binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP); } @@ -123,6 +128,8 @@ public void configure(Binder binder) { Injector injector = DIBootstrap.createInjector(testModule); + domain.setDataRowStoreFactory(injector.getInstance(DataRowStoreFactory.class)); + DataContextFactory factory = new DataContextFactory(); injector.injectMembers(factory); diff --git a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java index cc771b363f..b26fce4dd7 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/configuration/server/DataDomainProviderTest.java @@ -22,6 +22,8 @@ import org.apache.cayenne.DataChannel; import org.apache.cayenne.access.DataDomain; import org.apache.cayenne.access.DataNode; +import org.apache.cayenne.access.DataRowStoreFactory; +import org.apache.cayenne.access.DefaultDataRowStoreFactory; import org.apache.cayenne.access.dbsync.SchemaUpdateStrategy; import org.apache.cayenne.access.dbsync.SkipSchemaUpdateStrategy; import org.apache.cayenne.access.dbsync.ThrowOnPartialOrCreateSchemaStrategy; @@ -69,6 +71,8 @@ import org.apache.cayenne.di.Module; import org.apache.cayenne.di.spi.DefaultAdhocObjectFactory; import org.apache.cayenne.di.spi.DefaultClassLoaderManager; +import org.apache.cayenne.event.EventBridge; +import org.apache.cayenne.event.EventBridgeProvider; import org.apache.cayenne.event.EventManager; import org.apache.cayenne.event.MockEventManager; import org.apache.cayenne.log.CommonsJdbcEventLogger; @@ -206,6 +210,10 @@ public Collection findResources(String name) { binder.bind(RowReaderFactory.class).toInstance(mock(RowReaderFactory.class)); binder.bind(DataNodeFactory.class).to(DefaultDataNodeFactory.class); binder.bind(SQLTemplateProcessor.class).toInstance(mock(SQLTemplateProcessor.class)); + + binder.bind(EventBridge.class).toProvider(EventBridgeProvider.class); + binder.bind(DataRowStoreFactory.class).to(DefaultDataRowStoreFactory.class); + binder.bindMap(Constants.DATA_ROW_STORE_PROPERTIES_MAP); } }; diff --git a/cayenne-server/src/test/java/org/apache/cayenne/event/JMSBridgeFactoryTest.java b/cayenne-server/src/test/java/org/apache/cayenne/event/JMSBridgeFactoryTest.java new file mode 100644 index 0000000000..e098d4e988 --- /dev/null +++ b/cayenne-server/src/test/java/org/apache/cayenne/event/JMSBridgeFactoryTest.java @@ -0,0 +1,77 @@ +/***************************************************************** + * 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 JMSBridgeFactoryTest { + + protected Collection subjects = Collections.singleton(new EventSubject("test")); + protected String externalSubject = "subject"; + + @Test + public void testCreateEventBridge() throws Exception { + EventBridge bridge = new JMSBridgeFactory().createEventBridge( + subjects, + externalSubject, + Collections.EMPTY_MAP); + + assertNotNull(bridge); + assertTrue(bridge instanceof JMSBridge); + assertEquals(subjects, bridge.getLocalSubjects()); + assertEquals(externalSubject, bridge.getExternalSubject()); + } + + @Test + public void testUseProperties() throws Exception { + JMSBridgeFactory bridgeFactory = new JMSBridgeFactory(); + + Map properties = new HashMap(); + properties.put(JMSBridge.TOPIC_CONNECTION_FACTORY_PROPERTY, JMSBridgeProviderTest.TOPIC_CONNECTION_FACTORY_TEST); + + JMSBridge bridge = (JMSBridge) bridgeFactory.createEventBridge( + subjects, + externalSubject, + properties); + + assertEquals(bridge.getTopicConnectionFactoryName(), JMSBridgeProviderTest.TOPIC_CONNECTION_FACTORY_TEST); + } + + @Test + public void testUseDefaultProperties() throws Exception { + JMSBridgeFactory bridgeFactory = new JMSBridgeFactory(); + JMSBridge bridge = (JMSBridge) bridgeFactory.createEventBridge( + subjects, + externalSubject, + Collections.EMPTY_MAP); + + assertEquals(bridge.getTopicConnectionFactoryName(), JMSBridge.TOPIC_CONNECTION_FACTORY_DEFAULT); + } + +} diff --git a/cayenne-server/src/test/java/org/apache/cayenne/event/JMSBridgeProviderTest.java b/cayenne-server/src/test/java/org/apache/cayenne/event/JMSBridgeProviderTest.java new file mode 100644 index 0000000000..c683666b92 --- /dev/null +++ b/cayenne-server/src/test/java/org/apache/cayenne/event/JMSBridgeProviderTest.java @@ -0,0 +1,119 @@ +/***************************************************************** + * 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.CommonsJdbcEventLogger; +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 JMSBridgeProviderTest { + + private final DataDomain DOMAIN = new DataDomain("test"); + private final EventManager EVENT_MANAGER = new DefaultEventManager(); + protected static final String TOPIC_CONNECTION_FACTORY_TEST = "SomeTopicConnectionFactory"; + + @Test + public void testGetJMSBridge() throws Exception { + Module module = new Module() { + + public void configure(Binder binder) { + binder.bindMap(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(CommonsJdbcEventLogger.class); + binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class); + binder.bind(EventBridge.class).toProvider(JMSBridgeProvider.class); + binder.bindMap(Constants.JMS_BRIDGE_PROPERTIES_MAP); + } + }; + + Injector injector = DIBootstrap.createInjector(module); + EventBridge bridge = injector.getInstance(EventBridge.class); + + assertNotNull(bridge); + assertTrue(bridge instanceof JMSBridge); + } + + @Test + public void testUseProperties() throws Exception { + Module module = new Module() { + + public void configure(Binder binder) { + binder.bindMap(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(CommonsJdbcEventLogger.class); + binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class); + binder.bind(EventBridge.class).toProvider(JMSBridgeProvider.class); + binder.bindMap(Constants.JMS_BRIDGE_PROPERTIES_MAP) + .put(JMSBridge.TOPIC_CONNECTION_FACTORY_PROPERTY, TOPIC_CONNECTION_FACTORY_TEST); + } + }; + + Injector injector = DIBootstrap.createInjector(module); + JMSBridge bridge = (JMSBridge) injector.getInstance(EventBridge.class); + + assertEquals(JMSBridgeProviderTest.TOPIC_CONNECTION_FACTORY_TEST, bridge.getTopicConnectionFactoryName()); + } + + @Test + public void testUseDefaultProperties() throws Exception { + Module module = new Module() { + + public void configure(Binder binder) { + binder.bindMap(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(CommonsJdbcEventLogger.class); + binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class); + binder.bind(EventBridge.class).toProvider(JMSBridgeProvider.class); + binder.bindMap(Constants.JMS_BRIDGE_PROPERTIES_MAP); + } + }; + + Injector injector = DIBootstrap.createInjector(module); + JMSBridge bridge = (JMSBridge) injector.getInstance(EventBridge.class); + + assertEquals(bridge.getTopicConnectionFactoryName(), JMSBridge.TOPIC_CONNECTION_FACTORY_DEFAULT); + } + +} diff --git a/cayenne-server/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeFactoryTest.java b/cayenne-server/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeFactoryTest.java new file mode 100644 index 0000000000..3497888f21 --- /dev/null +++ b/cayenne-server/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeFactoryTest.java @@ -0,0 +1,84 @@ +/***************************************************************** + * 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 subjects = Collections.singleton(new EventSubject("test")); + protected String externalSubject = "subject"; + + @Test + public void testCreateEventBridge() throws Exception { + EventBridge bridge = new JavaGroupsBridgeFactory().createEventBridge( + subjects, + externalSubject, + Collections.EMPTY_MAP); + + 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 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.EMPTY_MAP); + + assertEquals(bridge.getMulticastAddress(), JavaGroupsBridge.MCAST_ADDRESS_DEFAULT); + assertEquals(bridge.getMulticastPort(), JavaGroupsBridge.MCAST_PORT_DEFAULT); + assertEquals(bridge.getConfigURL(), null); + } +} diff --git a/cayenne-server/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java b/cayenne-server/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java new file mode 100644 index 0000000000..6e82cd5598 --- /dev/null +++ b/cayenne-server/src/test/java/org/apache/cayenne/event/JavaGroupsBridgeProviderTest.java @@ -0,0 +1,123 @@ +/***************************************************************** + * 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.CommonsJdbcEventLogger; +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 { + Module module = new Module() { + public void configure(Binder binder) { + binder.bindMap(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(CommonsJdbcEventLogger.class); + binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class); + binder.bind(EventBridge.class).toProvider(JavaGroupsBridgeProvider.class); + binder.bindMap(Constants.JAVA_GROUPS_BRIDGE_PROPERTIES_MAP); + } + }; + + Injector injector = DIBootstrap.createInjector(module); + EventBridge bridge = injector.getInstance(EventBridge.class); + + assertNotNull(bridge); + assertTrue(bridge instanceof JavaGroupsBridge); + } + + @Test + public void testUseProperties() throws Exception { + Module module = new Module() { + public void configure(Binder binder) { + binder.bindMap(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(CommonsJdbcEventLogger.class); + binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class); + binder.bind(EventBridge.class).toProvider(JavaGroupsBridgeProvider.class); + binder.bindMap(Constants.JAVA_GROUPS_BRIDGE_PROPERTIES_MAP) + .put(JavaGroupsBridge.MCAST_ADDRESS_PROPERTY, MCAST_ADDRESS_TEST) + .put(JavaGroupsBridge.MCAST_PORT_PROPERTY, MCAST_PORT_TEST) + .put(JavaGroupsBridge.JGROUPS_CONFIG_URL_PROPERTY, CONFIG_URL_TEST); + } + }; + + Injector injector = DIBootstrap.createInjector(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 { + Module module = new Module() { + public void configure(Binder binder) { + binder.bindMap(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(CommonsJdbcEventLogger.class); + binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class); + binder.bind(EventBridge.class).toProvider(JavaGroupsBridgeProvider.class); + binder.bindMap(Constants.JAVA_GROUPS_BRIDGE_PROPERTIES_MAP); + } + }; + + Injector injector = DIBootstrap.createInjector(module); + JavaGroupsBridge bridge = (JavaGroupsBridge) injector.getInstance(EventBridge.class); + + assertEquals(bridge.getMulticastAddress(), JavaGroupsBridge.MCAST_ADDRESS_DEFAULT); + assertEquals(bridge.getMulticastPort(), JavaGroupsBridge.MCAST_PORT_DEFAULT); + assertEquals(bridge.getConfigURL(), null); + } +} diff --git a/cayenne-server/src/test/java/org/apache/cayenne/event/JGroupsBridgeFactoryTest.java b/cayenne-server/src/test/java/org/apache/cayenne/event/MockEventBridgeProvider.java similarity index 62% rename from cayenne-server/src/test/java/org/apache/cayenne/event/JGroupsBridgeFactoryTest.java rename to cayenne-server/src/test/java/org/apache/cayenne/event/MockEventBridgeProvider.java index 3a6b6c10af..2e99a63d00 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/event/JGroupsBridgeFactoryTest.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/event/MockEventBridgeProvider.java @@ -19,28 +19,25 @@ package org.apache.cayenne.event; -import org.junit.Test; +import org.apache.cayenne.access.DataDomain; +import org.apache.cayenne.di.DIRuntimeException; +import org.apache.cayenne.di.Inject; +import org.apache.cayenne.di.Provider; -import java.util.Collection; import java.util.Collections; -import static org.junit.Assert.*; +public class MockEventBridgeProvider implements Provider { -/** - */ -public class JGroupsBridgeFactoryTest { + @Inject + protected DataDomain dataDomain; - @Test - public void testCreateEventBridge() throws Exception { - Collection subjects = Collections.singleton(new EventSubject("test")); - EventBridge bridge = new JavaGroupsBridgeFactory().createEventBridge( - subjects, - "abcd", - Collections.EMPTY_MAP); + @Override + public EventBridge get() throws DIRuntimeException { + EventSubject snapshotEventSubject = EventSubject.getSubject(this.getClass(), dataDomain.getName());; - assertNotNull(bridge); - assertTrue(bridge instanceof JavaGroupsBridge); - assertEquals(subjects, bridge.getLocalSubjects()); - assertEquals("abcd", bridge.getExternalSubject()); + return new MockEventBridge( + Collections.singleton(snapshotEventSubject), + EventBridge.convertToExternalSubject(snapshotEventSubject), + Collections.EMPTY_MAP); } } diff --git a/cayenne-server/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java b/cayenne-server/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java index 4eac54ad6b..fb54edecf4 100644 --- a/cayenne-server/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java +++ b/cayenne-server/src/test/java/org/apache/cayenne/event/XMPPBridgeFactoryTest.java @@ -31,29 +31,42 @@ public class XMPPBridgeFactoryTest { + protected Collection subjects = Collections.singleton(new EventSubject("test")); + protected String externalSubject = "subject"; + @Test public void testCreateEventBridge() { - XMPPBridgeFactory factory = new XMPPBridgeFactory(); - - Collection subjects = Collections.singleton(EventSubject.getSubject( - getClass(), - "test")); - Map properties = new HashMap(); - properties.put(XMPPBridgeFactory.XMPP_HOST_PROPERTY, "somehost.com"); - properties.put(XMPPBridgeFactory.XMPP_PORT_PROPERTY, "12345"); - - EventBridge bridge = factory.createEventBridge( + EventBridge bridge = new XMPPBridgeFactory().createEventBridge( subjects, - "remote-subject", - properties); + externalSubject, + Collections.EMPTY_MAP); assertTrue(bridge instanceof XMPPBridge); + assertEquals(subjects, bridge.getLocalSubjects()); + assertEquals(externalSubject, bridge.getExternalSubject()); + } - XMPPBridge xmppBridge = (XMPPBridge) bridge; + @Test + public void testUseMapPropertiesSetter() throws Exception { + XMPPBridgeFactory bridgeFactory = new XMPPBridgeFactory(); + Map 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(subjects, xmppBridge.getLocalSubjects()); - assertEquals("remote-subject", xmppBridge.getExternalSubject()); - assertEquals("somehost.com", xmppBridge.getXmppHost()); - assertEquals(12345, xmppBridge.getXmppPort()); + 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); } } diff --git a/cayenne-server/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java b/cayenne-server/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java new file mode 100644 index 0000000000..7d225a5a63 --- /dev/null +++ b/cayenne-server/src/test/java/org/apache/cayenne/event/XMPPBridgeProviderTest.java @@ -0,0 +1,130 @@ +/***************************************************************** + * 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.CommonsJdbcEventLogger; +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 { + Module module = new Module() { + public void configure(Binder binder) { + binder.bindMap(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(CommonsJdbcEventLogger.class); + binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class); + binder.bind(EventBridge.class).toProvider(XMPPBridgeProvider.class); + binder.bindMap(Constants.XMPP_BRIDGE_PROPERTIES_MAP); + } + }; + + Injector injector = DIBootstrap.createInjector(module); + EventBridge bridge = injector.getInstance(EventBridge.class); + + assertNotNull(bridge); + assertTrue(bridge instanceof XMPPBridge); + } + + @Test + public void testUseProperties() throws Exception { + Module module = new Module() { + public void configure(Binder binder) { + binder.bindMap(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(CommonsJdbcEventLogger.class); + binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class); + binder.bind(EventBridge.class).toProvider(XMPPBridgeProvider.class); + binder.bindMap(Constants.XMPP_BRIDGE_PROPERTIES_MAP) + .put(XMPPBridge.XMPP_HOST_PROPERTY, HOST_TEST) + .put(XMPPBridge.XMPP_CHAT_SERVICE_PROPERTY, CHAT_SERVICE_TEST) + .put(XMPPBridge.XMPP_LOGIN_PROPERTY, LOGIN_TEST) + .put(XMPPBridge.XMPP_PASSWORD_PROPERTY, PASSWORD_TEST) + .put(XMPPBridge.XMPP_SECURE_CONNECTION_PROPERTY, String.valueOf(SECURE_CONNECTION_TEST)) + .put(XMPPBridge.XMPP_PORT_PROPERTY, String.valueOf(PORT_TEST)); + } + }; + + Injector injector = DIBootstrap.createInjector(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()); + } + + public void testUseDefaultProperties() throws Exception { + Module module = new Module() { + public void configure(Binder binder) { + binder.bindMap(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(CommonsJdbcEventLogger.class); + binder.bind(RuntimeProperties.class).to(DefaultRuntimeProperties.class); + binder.bind(EventBridge.class).toProvider(XMPPBridgeProvider.class); + binder.bindMap(Constants.XMPP_BRIDGE_PROPERTIES_MAP); + } + }; + + Injector injector = DIBootstrap.createInjector(module); + XMPPBridge bridge = (XMPPBridge) injector.getInstance(EventBridge.class); + + assertEquals(bridge.getChatService(), XMPPBridge.DEFAULT_CHAT_SERVICE); + assertEquals(bridge.getXmppPort(), XMPPBridge.DEFAULT_XMPP_PORT); + } +}