Author: tommaso Date: Fri Oct 3 09:33:20 2014 New Revision: 1629162 URL: http://svn.apache.org/r1629162 Log: SLING-3994 - simplified replication components' dependency management, minor javadoc adjustments
Added: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/ReplicationComponent.java (with props) sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/ReplicationComponentFactory.java (with props) sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/GenericReplicationComponentFactory.java (with props) sling/trunk/contrib/extensions/replication/it/src/main/resources/SLING-CONTENT/libs/test/install.author/org.apache.sling.replication.agent.impl.GenericReplicationComponentFactory-trigger-test-content-event.json sling/trunk/contrib/extensions/replication/it/src/main/resources/SLING-CONTENT/libs/test/install.author/org.apache.sling.replication.agent.impl.GenericReplicationComponentFactory-trigger-test-remote-event.json sling/trunk/contrib/extensions/replication/it/src/main/resources/SLING-CONTENT/libs/test/install.author/org.apache.sling.replication.agent.impl.GenericReplicationComponentFactory-trigger-test-replicate-event.json sling/trunk/contrib/extensions/replication/it/src/main/resources/SLING-CONTENT/libs/test/install.author/org.apache.sling.replication.agent.impl.GenericReplicationComponentFactory-trigger-test-scheduled-event.json sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.author/org.apache.sling.replication.agent.impl.GenericReplicationComponentFactory-trigger-remote-event.json sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.author/org.apache.sling.replication.agent.impl.SimpleReplicationAgentFactory-publish-reverse.json sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.author/org.apache.sling.replication.agent.impl.SimpleReplicationAgentFactory-publish.json sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.publish/org.apache.sling.replication.agent.impl.GenericReplicationComponentFactory-trigger-content-changed.json sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.publish/org.apache.sling.replication.agent.impl.SimpleReplicationAgentFactory-cache-flush.json sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.publish/org.apache.sling.replication.agent.impl.SimpleReplicationAgentFactory-reverse.json Removed: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/CompactSimpleReplicationAgentFactory.java sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/CoordinatingReplicationAgent.java sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/ReplicationComponentListener.java sling/trunk/contrib/extensions/replication/core/src/test/java/org/apache/sling/replication/agent/impl/SimpleReplicationAgentFactoryTest.java sling/trunk/contrib/extensions/replication/it/src/main/resources/SLING-CONTENT/libs/test/install.author/org.apache.sling.replication.agent.impl.DefaultReplicationComponentFactory-trigger-test-content-event.json sling/trunk/contrib/extensions/replication/it/src/main/resources/SLING-CONTENT/libs/test/install.author/org.apache.sling.replication.agent.impl.DefaultReplicationComponentFactory-trigger-test-remote-event.json sling/trunk/contrib/extensions/replication/it/src/main/resources/SLING-CONTENT/libs/test/install.author/org.apache.sling.replication.agent.impl.DefaultReplicationComponentFactory-trigger-test-replicate-event.json sling/trunk/contrib/extensions/replication/it/src/main/resources/SLING-CONTENT/libs/test/install.author/org.apache.sling.replication.agent.impl.DefaultReplicationComponentFactory-trigger-test-scheduled-event.json sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.author/org.apache.sling.replication.agent.impl.CompactSimpleReplicationAgentFactory-publish-reverse.json sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.author/org.apache.sling.replication.agent.impl.CompactSimpleReplicationAgentFactory-publish.json sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.author/org.apache.sling.replication.agent.impl.DefaultReplicationComponentFactory-trigger-remote-event.json sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.publish/org.apache.sling.replication.agent.impl.CompactSimpleReplicationAgentFactory-cache-flush.json sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.publish/org.apache.sling.replication.agent.impl.CompactSimpleReplicationAgentFactory-reverse.json sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.publish/org.apache.sling.replication.agent.impl.DefaultReplicationComponentFactory-trigger-content-changed.json Modified: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/ReplicationComponentProvider.java sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/CoordinatingReplicationAgentFactory.java sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/DefaultReplicationComponentFactory.java sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/DefaultReplicationComponentProvider.java sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/SimpleReplicationAgent.java sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/SimpleReplicationAgentFactory.java sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/packaging/ReplicationPackage.java sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/resources/impl/OsgiServicePropertiesResourceProvider.java sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/serialization/impl/AbstractReplicationPackageBuilder.java sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/servlet/ReplicationTriggerServlet.java sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/transport/authentication/impl/UserCredentialsTransportAuthenticationProviderFactory.java sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/transport/impl/RequestUtils.java sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/trigger/impl/ChainReplicateReplicationTrigger.java sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/trigger/impl/ResourceEventReplicationTrigger.java sling/trunk/contrib/extensions/replication/core/src/test/java/org/apache/sling/replication/agent/impl/SimpleReplicationAgentTest.java sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install.author/org.apache.sling.replication.agent.impl.CoordinatingReplicationAgentFactory-pubsync.json sling/trunk/contrib/extensions/replication/sample/src/main/resources/SLING-CONTENT/libs/sling/replication/install/resources/settings/org.apache.sling.replication.resources.impl.OsgiPropertiesResourceProviderFactory-simpleAgents.json Added: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/ReplicationComponent.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/ReplicationComponent.java?rev=1629162&view=auto ============================================================================== --- sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/ReplicationComponent.java (added) +++ sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/ReplicationComponent.java Fri Oct 3 09:33:20 2014 @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sling.replication.agent; + +/** + * Marker interface for replication components requiring explicit enabling and disabling + */ +public interface ReplicationComponent { + + /** + * Enables the component + */ + void enable(); + + /** + * Disables the component + */ + void disable(); +} Propchange: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/ReplicationComponent.java ------------------------------------------------------------------------------ svn:eol-style = native Added: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/ReplicationComponentFactory.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/ReplicationComponentFactory.java?rev=1629162&view=auto ============================================================================== --- sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/ReplicationComponentFactory.java (added) +++ sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/ReplicationComponentFactory.java Fri Oct 3 09:33:20 2014 @@ -0,0 +1,42 @@ +/* + * 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.sling.replication.agent; + +import java.util.Map; + +/** + * factory for {@link org.apache.sling.replication.agent.ReplicationComponent}s + */ +public interface ReplicationComponentFactory { + + /** + * create a {@link org.apache.sling.replication.agent.ReplicationComponent} + * + * @param type the <code>Class</code> of the component to be created + * @param properties the properties to be supplied for the initialization of the component + * @param componentProvider the {@link org.apache.sling.replication.agent.ReplicationComponentProvider} used to eventually + * wire additional required {@link org.apache.sling.replication.agent.ReplicationComponent}s + * @param <ComponentType> the actual type of the {@link org.apache.sling.replication.agent.ReplicationComponent} + * to be created + * @return + */ + <ComponentType> ComponentType createComponent(java.lang.Class<ComponentType> type, + Map<String, Object> properties, + ReplicationComponentProvider componentProvider); +} Propchange: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/ReplicationComponentFactory.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/ReplicationComponentProvider.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/ReplicationComponentProvider.java?rev=1629162&r1=1629161&r2=1629162&view=diff ============================================================================== --- sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/ReplicationComponentProvider.java (original) +++ sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/ReplicationComponentProvider.java Fri Oct 3 09:33:20 2014 @@ -18,28 +18,20 @@ */ package org.apache.sling.replication.agent; -import java.util.Map; - +/** + * provider for already existing {@link org.apache.sling.replication.agent.ReplicationComponent}s + */ public interface ReplicationComponentProvider { /** - * Retrieves an already existing component. - * @param type - * @param componentName - * @param <ComponentType> + * Retrieves an already existing component by name. + * If null is passed as componentName then a default component is returned. + * + * @param type the <code>Class</code> of the component to be retrieved + * @param componentName the component name as a <code>String</code> + * @param <ComponentType> the actual type of the {@link org.apache.sling.replication.agent.ReplicationComponent} + * to be retrieved * @return */ <ComponentType> ComponentType getComponent(java.lang.Class<ComponentType> type, String componentName); - - /** - * Creates a new component. - * @param type - * @param properties - * @param <ComponentType> - * @return - */ - <ComponentType> ComponentType createComponent(java.lang.Class<ComponentType> type, Map<String, Object> properties); - - - } Modified: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/CoordinatingReplicationAgentFactory.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/CoordinatingReplicationAgentFactory.java?rev=1629162&r1=1629161&r2=1629162&view=diff ============================================================================== --- sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/CoordinatingReplicationAgentFactory.java (original) +++ sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/CoordinatingReplicationAgentFactory.java Fri Oct 3 09:33:20 2014 @@ -18,20 +18,19 @@ */ package org.apache.sling.replication.agent.impl; -import java.util.Dictionary; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Map; - -import org.apache.felix.scr.annotations.Activate; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.ConfigurationPolicy; -import org.apache.felix.scr.annotations.Deactivate; -import org.apache.felix.scr.annotations.Property; -import org.apache.felix.scr.annotations.Reference; +import org.apache.felix.scr.annotations.*; import org.apache.sling.commons.osgi.PropertiesUtil; import org.apache.sling.replication.agent.ReplicationAgent; +import org.apache.sling.replication.agent.ReplicationComponent; +import org.apache.sling.replication.agent.ReplicationComponentFactory; import org.apache.sling.replication.agent.ReplicationComponentProvider; +import org.apache.sling.replication.event.ReplicationEventFactory; +import org.apache.sling.replication.queue.ReplicationQueueDistributionStrategy; +import org.apache.sling.replication.queue.ReplicationQueueProvider; +import org.apache.sling.replication.queue.impl.SingleQueueDistributionStrategy; +import org.apache.sling.replication.queue.impl.jobhandling.JobHandlingReplicationQueueProvider; +import org.apache.sling.replication.transport.authentication.TransportAuthenticationProvider; +import org.apache.sling.replication.trigger.ReplicationTrigger; import org.apache.sling.settings.SlingSettingsService; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; @@ -39,22 +38,29 @@ import org.osgi.framework.ServiceRegistr import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.*; +import java.util.Properties; + /** - * An OSGi service factory for {@link org.apache.sling.replication.agent.impl.CoordinatingReplicationAgent}s. + * An OSGi service factory for {@link org.apache.sling.replication.agent.ReplicationAgent}s which references already existing OSGi services. */ @Component(metatype = true, label = "Coordinating Replication Agents Factory", - description = "OSGi configuration based ReplicationAgent service factory", - name = CoordinatingReplicationAgentFactory.SERVICE_PID, + description = "OSGi configuration factory for coordinate agents", configurationFactory = true, specVersion = "1.1", policy = ConfigurationPolicy.REQUIRE ) -public class CoordinatingReplicationAgentFactory implements ReplicationComponentListener { +public class CoordinatingReplicationAgentFactory implements ReplicationComponentProvider { + public static final String QUEUEPROVIDER_TARGET = "queueProvider.target"; + + public static final String QUEUE_DISTRIBUTION_TARGET = "queueDistributionStrategy.target"; private final Logger log = LoggerFactory.getLogger(getClass()); - static final String SERVICE_PID = "org.apache.sling.replication.agent.impl.CoordinatingReplicationAgentFactory"; + private static final String DEFAULT_QUEUEPROVIDER = "(name=" + JobHandlingReplicationQueueProvider.NAME + ")"; + + private static final String DEFAULT_DISTRIBUTION = "(name=" + SingleQueueDistributionStrategy.NAME + ")"; @Property(boolValue = true, label = "Enabled") private static final String ENABLED = "enabled"; @@ -71,27 +77,36 @@ public class CoordinatingReplicationAgen @Property(label = "Package Importer", cardinality = 100) public static final String PACKAGE_IMPORTER = "packageImporter"; - @Property(label = "Queue Provider", cardinality = 100) - public static final String QUEUE_PROVIDER = "queueProvider"; + @Property(label = "Target ReplicationQueueProvider", name = QUEUEPROVIDER_TARGET, value = DEFAULT_QUEUEPROVIDER) + @Reference(name = "queueProvider", target = DEFAULT_QUEUEPROVIDER) + private volatile ReplicationQueueProvider queueProvider; + + @Property(label = "Target QueueDistributionStrategy", name = QUEUE_DISTRIBUTION_TARGET, value = DEFAULT_DISTRIBUTION) + @Reference(name = "queueDistributionStrategy", target = DEFAULT_DISTRIBUTION) + private volatile ReplicationQueueDistributionStrategy queueDistributionStrategy; + + @Property(label = "Target TransportAuthenticationProvider", name = "transportAuthenticationProvider.target") + @Reference(name = "transportAuthenticationProvider") + private volatile TransportAuthenticationProvider transportAuthenticationProvider; + - @Property(label = "Queue Distribution Strategy", cardinality = 100) - public static final String QUEUE_DISTRIBUTION_STRATEGY = "queueDistributionStrategy"; + @Reference + private ReplicationEventFactory replicationEventFactory; @Reference private SlingSettingsService settingsService; @Reference - private ReplicationComponentProvider componentProvider; + private ReplicationComponentFactory componentFactory; + - private ServiceRegistration agentReg; - private ServiceRegistration listenerReg; + private ServiceRegistration componentReg; private BundleContext savedContext; private Map<String, Object> savedConfig; @Activate - public void activate(BundleContext context, Map<String, Object> config) throws Exception { - log.debug("activating agent with config {}", config); + public void activate(BundleContext context, Map<String, Object> config) { savedContext = context; savedConfig = config; @@ -100,22 +115,50 @@ public class CoordinatingReplicationAgen Dictionary<String, Object> props = new Hashtable<String, Object>(); boolean enabled = PropertiesUtil.toBoolean(config.get(ENABLED), true); - String name = PropertiesUtil.toString(config.get(NAME), null); if (enabled) { props.put(ENABLED, true); + + String name = PropertiesUtil + .toString(config.get(NAME), String.valueOf(new Random().nextInt(1000))); props.put(NAME, name); - if (listenerReg == null) { - listenerReg = context.registerService(ReplicationComponentListener.class.getName(), this, props); - } - if (agentReg == null) { + String queue = PropertiesUtil.toString(config.get(QUEUEPROVIDER_TARGET), DEFAULT_QUEUEPROVIDER); + props.put(QUEUEPROVIDER_TARGET, queue); + + String distribution = PropertiesUtil.toString(config.get(QUEUE_DISTRIBUTION_TARGET), DEFAULT_DISTRIBUTION); + props.put(QUEUE_DISTRIBUTION_TARGET, distribution); + + if (componentReg == null) { Map<String, Object> properties = new HashMap<String, Object>(); properties.putAll(config); - properties.put("type", "coordinating"); - CoordinatingReplicationAgent agent = (CoordinatingReplicationAgent) componentProvider.createComponent(ReplicationAgent.class, properties); + properties.put("type", "simple"); + properties.put("isPassive", false); + + { + String[] packageImporterProperties = PropertiesUtil.toStringArray(properties.get(PACKAGE_IMPORTER)); + List<String> packageImporterPropertiesList = new ArrayList<String>(); + packageImporterPropertiesList.addAll(Arrays.asList(packageImporterProperties)); + packageImporterPropertiesList.add("type=remote"); + packageImporterProperties = packageImporterPropertiesList.toArray(new String[0]); + properties.put(PACKAGE_IMPORTER, packageImporterProperties); + } + + { + String[] packageExporterProperties = PropertiesUtil.toStringArray(properties.get(PACKAGE_EXPORTER)); + List<String> packageExporterPropertiesList = new ArrayList<String>(); + packageExporterPropertiesList.addAll(Arrays.asList(packageExporterProperties)); + packageExporterPropertiesList.add("type=remote"); + packageExporterProperties = packageExporterPropertiesList.toArray(new String[0]); + properties.put(PACKAGE_EXPORTER, packageExporterProperties); + } + + + properties.put("trigger0", new String[] { "type=scheduledEvent" }); + + ReplicationAgent agent = componentFactory.createComponent(ReplicationAgent.class, properties, this); log.debug("activated agent {}", agent != null ? agent.getName() : null); @@ -123,49 +166,45 @@ public class CoordinatingReplicationAgen props.put(NAME, agent.getName()); // register agent service - agentReg = context.registerService(ReplicationAgent.class.getName(), agent, props); - agent.enable(); + componentReg = context.registerService(ReplicationAgent.class.getName(), agent, props); + + + if (agent instanceof ReplicationComponent) { + ((ReplicationComponent) agent).enable(); + } } } + } } @Deactivate private void deactivate(BundleContext context) { - log.debug("deactivating agent"); - if (agentReg != null) { - ServiceReference reference = agentReg.getReference(); - CoordinatingReplicationAgent replicationAgent = (CoordinatingReplicationAgent) context.getService(reference); - replicationAgent.disable(); - agentReg.unregister(); - agentReg = null; - } - if (listenerReg != null) { - listenerReg.unregister(); - listenerReg = null; - } - } - - private void refresh(boolean isBinding) { - try { - if (savedContext != null && savedConfig != null) { - if (isBinding && agentReg == null) { - activate(savedContext, savedConfig); - } else if (!isBinding && agentReg != null) { - deactivate(savedContext); - } + if (componentReg != null) { + ServiceReference reference = componentReg.getReference(); + Object service = context.getService(reference); + if (service instanceof ReplicationComponent) { + ((ReplicationComponent) service).disable(); } - } catch (Exception e) { - log.error("Cannot refresh agent", e); + componentReg.unregister(); + componentReg = null; } - } - public <ComponentType> void componentBind(ComponentType component, String componentName) { - refresh(true); } - public <ComponentType> void componentUnbind(ComponentType component, String componentName) { - refresh(false); + + public <ComponentType> ComponentType getComponent(Class<ComponentType> type, String componentName) { + if (type.isAssignableFrom(ReplicationQueueProvider.class)) { + return (ComponentType) queueProvider; + + } + else if (type.isAssignableFrom(ReplicationQueueDistributionStrategy.class)) { + return (ComponentType) queueDistributionStrategy; + } + else if (type.isAssignableFrom(TransportAuthenticationProvider.class)) { + return (ComponentType) transportAuthenticationProvider; + } + return null; } } Modified: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/DefaultReplicationComponentFactory.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/DefaultReplicationComponentFactory.java?rev=1629162&r1=1629161&r2=1629162&view=diff ============================================================================== --- sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/DefaultReplicationComponentFactory.java (original) +++ sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/DefaultReplicationComponentFactory.java Fri Oct 3 09:33:20 2014 @@ -18,21 +18,35 @@ */ package org.apache.sling.replication.agent.impl; -import java.util.Dictionary; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Map; - -import org.apache.felix.scr.annotations.Activate; -import org.apache.felix.scr.annotations.Component; -import org.apache.felix.scr.annotations.ConfigurationPolicy; -import org.apache.felix.scr.annotations.Deactivate; -import org.apache.felix.scr.annotations.Property; -import org.apache.felix.scr.annotations.Reference; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.felix.scr.annotations.*; +import org.apache.jackrabbit.vault.packaging.Packaging; import org.apache.sling.commons.osgi.PropertiesUtil; +import org.apache.sling.commons.scheduler.Scheduler; +import org.apache.sling.jcr.api.SlingRepository; import org.apache.sling.replication.agent.ReplicationAgent; +import org.apache.sling.replication.agent.ReplicationComponentFactory; import org.apache.sling.replication.agent.ReplicationComponentProvider; +import org.apache.sling.replication.event.ReplicationEventFactory; +import org.apache.sling.replication.packaging.ReplicationPackageExporter; +import org.apache.sling.replication.packaging.ReplicationPackageImporter; +import org.apache.sling.replication.packaging.impl.exporter.LocalReplicationPackageExporterFactory; +import org.apache.sling.replication.packaging.impl.exporter.RemoteReplicationPackageExporterFactory; +import org.apache.sling.replication.packaging.impl.importer.LocalReplicationPackageImporterFactory; +import org.apache.sling.replication.packaging.impl.importer.RemoteReplicationPackageImporterFactory; +import org.apache.sling.replication.queue.ReplicationQueueDistributionStrategy; +import org.apache.sling.replication.queue.ReplicationQueueProvider; +import org.apache.sling.replication.serialization.ReplicationPackageBuilder; +import org.apache.sling.replication.serialization.impl.vlt.FileVaultReplicationPackageBuilderFactory; +import org.apache.sling.replication.transport.authentication.TransportAuthenticationProvider; +import org.apache.sling.replication.transport.authentication.impl.UserCredentialsTransportAuthenticationProvider; import org.apache.sling.replication.trigger.ReplicationTrigger; +import org.apache.sling.replication.trigger.impl.ChainReplicateReplicationTrigger; +import org.apache.sling.replication.trigger.impl.RemoteEventReplicationTrigger; +import org.apache.sling.replication.trigger.impl.ResourceEventReplicationTrigger; +import org.apache.sling.replication.trigger.impl.ScheduledReplicationTrigger; import org.apache.sling.settings.SlingSettingsService; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; @@ -49,137 +63,234 @@ import org.slf4j.LoggerFactory; @Component(metatype = true, label = "Generic Replication Components Factory", description = "OSGi configuration Replication Component factory", - configurationFactory = true, specVersion = "1.1", - policy = ConfigurationPolicy.REQUIRE -) -public class DefaultReplicationComponentFactory implements ReplicationComponentListener { + immediate = true - private final Logger log = LoggerFactory.getLogger(getClass()); - - @Property(boolValue = true, label = "Enabled") - private static final String ENABLED = "enabled"; +) +@Service(ReplicationComponentFactory.class) +public class DefaultReplicationComponentFactory implements ReplicationComponentFactory { - @Property(label = "Name") + public static final String COMPONENT_TYPE = "type"; public static final String NAME = "name"; - @Property(label = "Properties") - public static final String PROPERTIES = "properties"; - - @Property(label = "Kind") - public static final String KIND = "kind"; + private final Logger log = LoggerFactory.getLogger(getClass()); @Reference - private SlingSettingsService settingsService; + private ReplicationEventFactory replicationEventFactory; @Reference - private ReplicationComponentProvider componentProvider; + private SlingRepository repository; - private ServiceRegistration componentReg; - private ServiceRegistration listenerReg; + @Reference + private Packaging packaging; - private BundleContext savedContext; - private Map<String, Object> savedConfig; + @Reference + private Scheduler scheduler; - private String kind; + private BundleContext bundleContext; @Activate - public void activate(BundleContext context, Map<String, Object> config) throws Exception { - log.debug("activating agent with config {}", config); + private void activate(BundleContext bundleContext) { + this.bundleContext = bundleContext; + } - savedContext = context; - savedConfig = config; - // inject configuration - Dictionary<String, Object> props = new Hashtable<String, Object>(); + public <ComponentType> ComponentType createComponent(Class<ComponentType> type, Map<String, Object> properties, + ReplicationComponentProvider componentProvider) { + try { + if (type.isAssignableFrom(ReplicationAgent.class)) { + return (ComponentType) createAgent(properties, componentProvider); + } else if (type.isAssignableFrom(ReplicationTrigger.class)) { + return (ComponentType) createTrigger(properties, componentProvider); + } else if (type.isAssignableFrom(TransportAuthenticationProvider.class)) { + return (ComponentType) createTransportAuthenticationProvider(properties, componentProvider); + } - boolean enabled = PropertiesUtil.toBoolean(config.get(ENABLED), true); - String name = PropertiesUtil.toString(config.get(NAME), null); + } catch (Throwable t) { + log.error("Cannot create component", t); - kind = PropertiesUtil.toString(config.get(KIND), null); + } + return null; + } - if (enabled) { - props.put(ENABLED, true); - props.put(NAME, name); - if (listenerReg == null) { - listenerReg = context.registerService(ReplicationComponentListener.class.getName(), this, props); - } + public ReplicationAgent createAgent(Map<String, Object> properties, ReplicationComponentProvider componentProvider) { - if (componentReg == null) { - Map<String, Object> configProperties = SettingsUtils.extractMap(PROPERTIES, config); + String factory = PropertiesUtil.toString(properties.get(COMPONENT_TYPE), "simple"); + + if ("simple".equals(factory)) { + + Map<String, Object> importerProperties = extractMap("packageImporter", properties); + ReplicationPackageImporter packageImporter = createImporter(importerProperties, componentProvider); + + Map<String, Object> exporterProperties = extractMap("packageExporter", properties); + ReplicationPackageExporter packageExporter = createExporter(exporterProperties, componentProvider); + + Map<String, Object> queueDistributionStrategyProperties = extractMap("queueDistributionStrategy", properties); + ReplicationQueueDistributionStrategy queueDistributionStrategy = createDistributionStrategy(queueDistributionStrategyProperties, componentProvider); + + Map<String, Object> queueProviderProperties = extractMap("queueProvider", properties); + ReplicationQueueProvider queueProvider = createQueueProvider(queueProviderProperties, componentProvider); + + List<Map<String, Object>> triggersProperties = extractMapList("trigger", properties); + List<ReplicationTrigger> triggers = createTriggerList(triggersProperties, componentProvider); + + String name = PropertiesUtil.toString(properties.get(SimpleReplicationAgentFactory.NAME), String.valueOf(new Random().nextInt(1000))); + + boolean useAggregatePaths = PropertiesUtil.toBoolean(properties.get(SimpleReplicationAgentFactory.USE_AGGREGATE_PATHS), true); + + boolean isPassive = PropertiesUtil.toBoolean(properties.get(SimpleReplicationAgentFactory.IS_PASSIVE), false); + + + return new SimpleReplicationAgent(name, useAggregatePaths, isPassive, + packageImporter, packageExporter, queueProvider, queueDistributionStrategy, replicationEventFactory, triggers); - Map<String, Object> properties = new HashMap<String, Object>(); - properties.putAll(config); - properties.putAll(configProperties); - - String componentClass = null; - Object componentObject = null; - - if ("agent".equals(kind)) { - SimpleReplicationAgent agent = (SimpleReplicationAgent) componentProvider.createComponent(ReplicationAgent.class, properties); - componentClass = ReplicationAgent.class.getName(); - componentObject = agent; - agent.enable(); - - } else if ("trigger".equals(kind)) { - - ReplicationTrigger trigger = componentProvider.createComponent(ReplicationTrigger.class, properties); - - componentClass = ReplicationTrigger.class.getName(); - componentObject = trigger; - } - - if (componentObject != null && componentClass != null) { - componentReg = context.registerService(componentClass, componentObject, props); - log.debug("activated component kind {} name", kind, name); - } - } } + + return null; + } - @Deactivate - private void deactivate(BundleContext context) { - log.debug("deactivating component"); - if (componentReg != null) { - ServiceReference reference = componentReg.getReference(); - - if ("agent".equals(kind)) { - SimpleReplicationAgent replicationComponent = (SimpleReplicationAgent) context.getService(reference); - replicationComponent.disable(); - } else if ("trigger".equals(kind)) { + public ReplicationPackageExporter createExporter(Map<String, Object> properties, ReplicationComponentProvider componentProvider) { - } - componentReg.unregister(); - componentReg = null; + String factory = PropertiesUtil.toString(properties.get(COMPONENT_TYPE), "service"); + + if ("service".equals(factory)) { + String name = PropertiesUtil.toString(properties.get(NAME), null); + return componentProvider.getComponent(ReplicationPackageExporter.class, name); + + } else if ("local".equals(factory)) { + Map<String, Object> builderProperties = extractMap("packageBuilder", properties); + ReplicationPackageBuilder packageBuilder = createBuilder(builderProperties); + return LocalReplicationPackageExporterFactory.getInstance(packageBuilder); + } else if ("remote".equals(factory)) { + Map<String, Object> authenticationProviderProperties = extractMap("authenticationProvider", properties); + TransportAuthenticationProvider authenticationProvider = createTransportAuthenticationProvider(authenticationProviderProperties, componentProvider); + + Map<String, Object> builderProperties = extractMap("packageBuilder", properties); + ReplicationPackageBuilder packageBuilder = createBuilder(builderProperties); + + return RemoteReplicationPackageExporterFactory.getInstance(properties, packageBuilder, authenticationProvider); } - if (listenerReg != null) { - listenerReg.unregister(); - listenerReg = null; + + return null; + } + + public ReplicationPackageImporter createImporter(Map<String, Object> properties, ReplicationComponentProvider componentProvider) { + + String factory = PropertiesUtil.toString(properties.get(COMPONENT_TYPE), "service"); + + if ("service".equals(factory)) { + String name = PropertiesUtil.toString(properties.get(NAME), null); + return componentProvider.getComponent(ReplicationPackageImporter.class, name); + } else if ("local".equals(factory)) { + Map<String, Object> builderProperties = extractMap("packageBuilder", properties); + ReplicationPackageBuilder packageBuilder = createBuilder(builderProperties); + return LocalReplicationPackageImporterFactory.getInstance(properties, packageBuilder, replicationEventFactory); + } else if ("remote".equals(factory)) { + Map<String, Object> authenticationProviderProperties = extractMap("authenticationProvider", properties); + TransportAuthenticationProvider authenticationProvider = createTransportAuthenticationProvider(authenticationProviderProperties, componentProvider); + + return RemoteReplicationPackageImporterFactory.getInstance(properties, authenticationProvider); } + + return null; + } + + public ReplicationQueueProvider createQueueProvider(Map<String, Object> properties, ReplicationComponentProvider componentProvider) { + String factory = PropertiesUtil.toString(properties.get(COMPONENT_TYPE), "service"); + + if ("service".equals(factory)) { + String name = PropertiesUtil.toString(properties.get(NAME), null); + return componentProvider.getComponent(ReplicationQueueProvider.class, name); + } + + return null; + } + + public ReplicationQueueDistributionStrategy createDistributionStrategy(Map<String, Object> properties, ReplicationComponentProvider componentProvider) { + String factory = PropertiesUtil.toString(properties.get(COMPONENT_TYPE), "service"); + + if ("service".equals(factory)) { + String name = PropertiesUtil.toString(properties.get(NAME), null); + return componentProvider.getComponent(ReplicationQueueDistributionStrategy.class, name); + + } + + return null; + } + + public TransportAuthenticationProvider createTransportAuthenticationProvider(Map<String, Object> properties, ReplicationComponentProvider componentProvider) { + String factory = PropertiesUtil.toString(properties.get(COMPONENT_TYPE), "service"); + + if ("service".equals(factory)) { + String name = PropertiesUtil.toString(properties.get(NAME), null); + return componentProvider.getComponent(TransportAuthenticationProvider.class, name); + + } else if ("user".equals(factory)) { + return new UserCredentialsTransportAuthenticationProvider(properties); + } + + return null; + } + + public ReplicationPackageBuilder createBuilder(Map<String, Object> properties) { + String factory = PropertiesUtil.toString(properties.get(COMPONENT_TYPE), "service"); + + if ("vlt".equals(factory)) { + return FileVaultReplicationPackageBuilderFactory.getInstance(properties, repository, packaging, replicationEventFactory); + } + + return null; } - private void refresh(boolean isBinding) { - try { - if (savedContext != null && savedConfig != null) { - if (isBinding && componentReg == null) { - activate(savedContext, savedConfig); - } else if (!isBinding && componentReg != null) { - deactivate(savedContext); - } - } - } catch (Exception e) { - log.error("Cannot refresh agent", e); + private ReplicationTrigger createTrigger(Map<String, Object> properties, ReplicationComponentProvider componentProvider) { + String factory = PropertiesUtil.toString(properties.get(COMPONENT_TYPE), "service"); + + if ("service".equals(factory)) { + String name = PropertiesUtil.toString(properties.get(NAME), null); + return componentProvider.getComponent(ReplicationTrigger.class, name); + + } else if (RemoteEventReplicationTrigger.TYPE.equals(factory)) { + Map<String, Object> authenticationProviderProperties = extractMap("authenticationProvider", properties); + + TransportAuthenticationProvider authenticationProvider = createTransportAuthenticationProvider(authenticationProviderProperties, componentProvider); + return new RemoteEventReplicationTrigger(properties, authenticationProvider, scheduler); + } else if (ResourceEventReplicationTrigger.TYPE.equals(factory)) { + return new ResourceEventReplicationTrigger(properties, bundleContext); + } else if (ScheduledReplicationTrigger.TYPE.equals(factory)) { + return new ScheduledReplicationTrigger(properties, scheduler); + } else if (ChainReplicateReplicationTrigger.TYPE.equals(factory)) { + return new ChainReplicateReplicationTrigger(properties, bundleContext); } + + return null; } - public <ComponentType> void componentBind(ComponentType component, String componentName) { - refresh(true); + private List<ReplicationTrigger> createTriggerList(List<Map<String, Object>> triggersProperties, ReplicationComponentProvider componentProvider) { + List<ReplicationTrigger> triggers = new ArrayList<ReplicationTrigger>(); + for (Map<String, Object> properties : triggersProperties) { + triggers.add(createTrigger(properties, componentProvider)); + } + + return triggers; } - public <ComponentType> void componentUnbind(ComponentType component, String componentName) { - refresh(false); + Map<String, Object> extractMap(String key, Map<String, Object> objectMap) { + Map<String, Object> map = SettingsUtils.extractMap(key, objectMap); + return map == null ? new HashMap<String, Object>() : map; } + + List<Map<String, Object>> extractMapList(String key, Map<String, Object> objectMap) { + List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(); + for (String mapKey : objectMap.keySet()) { + if (mapKey.startsWith(key)) { + result.add(SettingsUtils.extractMap(mapKey, objectMap)); + } + } + return result; + } + } Modified: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/DefaultReplicationComponentProvider.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/DefaultReplicationComponentProvider.java?rev=1629162&r1=1629161&r2=1629162&view=diff ============================================================================== --- sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/DefaultReplicationComponentProvider.java (original) +++ sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/DefaultReplicationComponentProvider.java Fri Oct 3 09:33:20 2014 @@ -55,7 +55,6 @@ import org.slf4j.LoggerFactory; @Reference(name = "replicationQueueProvider", referenceInterface = ReplicationQueueProvider.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC), @Reference(name = "replicationQueueDistributionStrategy", referenceInterface = ReplicationQueueDistributionStrategy.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC), @Reference(name = "transportAuthenticationProvider", referenceInterface = TransportAuthenticationProvider.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC), - @Reference(name = "replicationComponentListener", referenceInterface = ReplicationComponentListener.class, cardinality = ReferenceCardinality.OPTIONAL_MULTIPLE, policy = ReferencePolicy.DYNAMIC) }) public class DefaultReplicationComponentProvider implements ReplicationComponentProvider { @@ -64,19 +63,7 @@ public class DefaultReplicationComponent private final Logger log = LoggerFactory.getLogger(getClass()); - @Reference - private ReplicationEventFactory replicationEventFactory; - @Reference - private SlingRepository repository; - - @Reference - private Packaging packaging; - - @Reference - private Scheduler scheduler; - - Map<String, ReplicationComponentListener> replicationComponentListenerMap = new ConcurrentHashMap<String, ReplicationComponentListener>(); Map<String, ReplicationQueueProvider> replicationQueueProviderMap = new ConcurrentHashMap<String, ReplicationQueueProvider>(); Map<String, ReplicationQueueDistributionStrategy> replicationQueueDistributionStrategyMap = new ConcurrentHashMap<String, ReplicationQueueDistributionStrategy>(); Map<String, TransportAuthenticationProvider> transportAuthenticationProviderMap = new ConcurrentHashMap<String, TransportAuthenticationProvider>(); @@ -84,10 +71,7 @@ public class DefaultReplicationComponent Map<String, ReplicationPackageExporter> replicationPackageExporterMap = new ConcurrentHashMap<String, ReplicationPackageExporter>(); private BundleContext bundleContext; - @Activate - private void activate(BundleContext bundleContext) { - this.bundleContext = bundleContext; - } + public <ComponentType> ComponentType getComponent(Class<ComponentType> type, String componentName) { if (type.isAssignableFrom(ReplicationPackageExporter.class)) { @@ -105,264 +89,11 @@ public class DefaultReplicationComponent return null; } - public <ComponentType> ComponentType createComponent(Class<ComponentType> type, Map<String, Object> properties) { - try { - if (type.isAssignableFrom(ReplicationAgent.class)) { - return (ComponentType) createAgent(properties, this); - } else if (type.isAssignableFrom(ReplicationTrigger.class)) { - return (ComponentType) createTrigger(properties, this); - } else if (type.isAssignableFrom(TransportAuthenticationProvider.class)) { - return (ComponentType) createTransportAuthenticationProvider(properties, this); - } - - } catch (Throwable t) { - log.error("Cannot create agent", t); - - } - return null; - } - - - public ReplicationAgent createAgent(Map<String, Object> properties, ReplicationComponentProvider componentProvider) { - - String factory = PropertiesUtil.toString(properties.get(COMPONENT_TYPE), "simple"); - - if ("simple".equals(factory)) { - if (log.isDebugEnabled()) { - log.debug("creating simple agent"); - for (Map.Entry<String, Object> e : properties.entrySet()) { - Object value = e.getValue(); - log.info(e.getKey() + " -> " + (value != null && value.getClass().isArray() ? Arrays.toString((Object[]) value) : value)); - } - } - Map<String, Object> importerProperties = extractMap("packageImporter", properties); - ReplicationPackageImporter packageImporter = createImporter(importerProperties, componentProvider); - - Map<String, Object> exporterProperties = extractMap("packageExporter", properties); - ReplicationPackageExporter packageExporter = createExporter(exporterProperties, componentProvider); - - Map<String, Object> queueDistributionStrategyProperties = extractMap("queueDistributionStrategy", properties); - ReplicationQueueDistributionStrategy queueDistributionStrategy = createDistributionStrategy(queueDistributionStrategyProperties, componentProvider); - - Map<String, Object> queueProviderProperties = extractMap("queueProvider", properties); - ReplicationQueueProvider queueProvider = createQueueProvider(queueProviderProperties, componentProvider); - - List<Map<String, Object>> triggersProperties = extractMapList("trigger", properties); - List<ReplicationTrigger> triggers = createTriggerList(triggersProperties, componentProvider); - - String name = PropertiesUtil.toString(properties.get(CompactSimpleReplicationAgentFactory.NAME), String.valueOf(new Random().nextInt(1000))); - - boolean useAggregatePaths = PropertiesUtil.toBoolean(properties.get(CompactSimpleReplicationAgentFactory.USE_AGGREGATE_PATHS), true); - - boolean isPassive = PropertiesUtil.toBoolean(properties.get(CompactSimpleReplicationAgentFactory.IS_PASSIVE), false); - - // check configuration is valid - if (name == null || packageExporter == null || packageImporter == null || queueProvider == null || queueDistributionStrategy == null) { - log.error("could not create the agent with following bindings {}", Arrays.toString(new Object[]{name, packageExporter, packageImporter, queueProvider, queueDistributionStrategy})); - return null; - } - - return new SimpleReplicationAgent(name, useAggregatePaths, isPassive, - packageImporter, packageExporter, queueProvider, queueDistributionStrategy, replicationEventFactory, triggers); - - } else if ("coordinating".equals(factory)) { - if (log.isDebugEnabled()) { - log.debug("creating coordinating agent"); - for (Map.Entry<String, Object> e : properties.entrySet()) { - Object value = e.getValue(); - log.info(e.getKey() + " -> " + (value != null && value.getClass().isArray() ? Arrays.toString((Object[]) value) : value)); - } - } - - // build exporter - Map<String, Object> exporterProperties = extractMap("packageExporter", properties); - exporterProperties.put(COMPONENT_TYPE, "remote"); - RemoteReplicationPackageExporter packageExporter = (RemoteReplicationPackageExporter) createExporter(exporterProperties, componentProvider); - - // build importer - Map<String, Object> importerProperties = extractMap("packageImporter", properties); - importerProperties.put(COMPONENT_TYPE, "remote"); - RemoteReplicationPackageImporter packageImporter = (RemoteReplicationPackageImporter) createImporter(importerProperties, componentProvider); - - // build triggers - List<ReplicationTrigger> triggers = new ArrayList<ReplicationTrigger>(1); - triggers.add(new ScheduledReplicationTrigger(Collections.<String, Object>emptyMap(), scheduler)); - - // TODO : eventually enable remote event triggers automatically -// String[] exporterEndpoints = (String[]) exporterProperties.get("endpoints"); -// for (String exporterEndpoint : exporterEndpoints) { -// } - - Map<String, Object> queueDistributionStrategyProperties = extractMap("queueDistributionStrategy", properties); - ReplicationQueueDistributionStrategy queueDistributionStrategy = createDistributionStrategy(queueDistributionStrategyProperties, componentProvider); - - Map<String, Object> queueProviderProperties = extractMap("queueProvider", properties); - ReplicationQueueProvider queueProvider = createQueueProvider(queueProviderProperties, componentProvider); - - String name = PropertiesUtil.toString(properties.get(CoordinatingReplicationAgentFactory.NAME), String.valueOf(new Random().nextInt(1000))); - - boolean useAggregatePaths = PropertiesUtil.toBoolean(properties.get(CompactSimpleReplicationAgentFactory.USE_AGGREGATE_PATHS), true); - - // check configuration is valid - if (name == null || packageExporter == null || packageImporter == null || queueProvider == null || queueDistributionStrategy == null) { - log.error("could not create the coordinate agent with following bindings {}", Arrays.toString(new Object[]{name, packageExporter, packageImporter, queueProvider, queueDistributionStrategy})); - } else { - return new CoordinatingReplicationAgent(name, useAggregatePaths, - packageImporter, packageExporter, queueProvider, queueDistributionStrategy, replicationEventFactory, triggers); - } - } - - return null; - - } - - - public ReplicationPackageExporter createExporter(Map<String, Object> properties, ReplicationComponentProvider componentProvider) { - - String factory = PropertiesUtil.toString(properties.get(COMPONENT_TYPE), "service"); - - if ("service".equals(factory)) { - String name = PropertiesUtil.toString(properties.get(NAME), null); - return componentProvider.getComponent(ReplicationPackageExporter.class, name); - - } else if ("local".equals(factory)) { - Map<String, Object> builderProperties = extractMap("packageBuilder", properties); - ReplicationPackageBuilder packageBuilder = createBuilder(builderProperties); - return LocalReplicationPackageExporterFactory.getInstance(packageBuilder); - } else if ("remote".equals(factory)) { - Map<String, Object> authenticationProviderProperties = extractMap("authenticationProvider", properties); - TransportAuthenticationProvider authenticationProvider = createTransportAuthenticationProvider(authenticationProviderProperties, componentProvider); - - Map<String, Object> builderProperties = extractMap("packageBuilder", properties); - ReplicationPackageBuilder packageBuilder = createBuilder(builderProperties); - - return RemoteReplicationPackageExporterFactory.getInstance(properties, packageBuilder, authenticationProvider); - } - - return null; - } - - public ReplicationPackageImporter createImporter(Map<String, Object> properties, ReplicationComponentProvider componentProvider) { - - String factory = PropertiesUtil.toString(properties.get(COMPONENT_TYPE), "service"); - - if ("service".equals(factory)) { - String name = PropertiesUtil.toString(properties.get(NAME), null); - return componentProvider.getComponent(ReplicationPackageImporter.class, name); - } else if ("local".equals(factory)) { - Map<String, Object> builderProperties = extractMap("packageBuilder", properties); - ReplicationPackageBuilder packageBuilder = createBuilder(builderProperties); - return LocalReplicationPackageImporterFactory.getInstance(properties, packageBuilder, replicationEventFactory); - } else if ("remote".equals(factory)) { - Map<String, Object> authenticationProviderProperties = extractMap("authenticationProvider", properties); - TransportAuthenticationProvider authenticationProvider = createTransportAuthenticationProvider(authenticationProviderProperties, componentProvider); - - return RemoteReplicationPackageImporterFactory.getInstance(properties, authenticationProvider); - } - - return null; - } - - public ReplicationQueueProvider createQueueProvider(Map<String, Object> properties, ReplicationComponentProvider componentProvider) { - String factory = PropertiesUtil.toString(properties.get(COMPONENT_TYPE), "service"); - - if ("service".equals(factory)) { - String name = PropertiesUtil.toString(properties.get(NAME), null); - return componentProvider.getComponent(ReplicationQueueProvider.class, name); - } - - return null; - } - - public ReplicationQueueDistributionStrategy createDistributionStrategy(Map<String, Object> properties, ReplicationComponentProvider componentProvider) { - String factory = PropertiesUtil.toString(properties.get(COMPONENT_TYPE), "service"); - - if ("service".equals(factory)) { - String name = PropertiesUtil.toString(properties.get(NAME), null); - return componentProvider.getComponent(ReplicationQueueDistributionStrategy.class, name); - - } - - return null; - } - - public TransportAuthenticationProvider createTransportAuthenticationProvider(Map<String, Object> properties, ReplicationComponentProvider componentProvider) { - String factory = PropertiesUtil.toString(properties.get(COMPONENT_TYPE), "service"); - - if ("service".equals(factory)) { - String name = PropertiesUtil.toString(properties.get(NAME), null); - return componentProvider.getComponent(TransportAuthenticationProvider.class, name); - - } else if ("user".equals(factory)) { - return new UserCredentialsTransportAuthenticationProvider(properties); - } - - return null; - } - - public ReplicationPackageBuilder createBuilder(Map<String, Object> properties) { - String factory = PropertiesUtil.toString(properties.get(COMPONENT_TYPE), "service"); - - if ("vlt".equals(factory)) { - return FileVaultReplicationPackageBuilderFactory.getInstance(properties, repository, packaging, replicationEventFactory); - } - - return null; - } - - - private ReplicationTrigger createTrigger(Map<String, Object> properties, ReplicationComponentProvider componentProvider) { - String factory = PropertiesUtil.toString(properties.get(COMPONENT_TYPE), "service"); - - if ("service".equals(factory)) { - String name = PropertiesUtil.toString(properties.get(NAME), null); - return componentProvider.getComponent(ReplicationTrigger.class, name); - - } else if (RemoteEventReplicationTrigger.TYPE.equals(factory)) { - Map<String, Object> authenticationProviderProperties = extractMap("authenticationProvider", properties); - - TransportAuthenticationProvider authenticationProvider = createTransportAuthenticationProvider(authenticationProviderProperties, componentProvider); - return new RemoteEventReplicationTrigger(properties, authenticationProvider, scheduler); - } else if (ResourceEventReplicationTrigger.TYPE.equals(factory)) { - return new ResourceEventReplicationTrigger(properties, bundleContext); - } else if (ScheduledReplicationTrigger.TYPE.equals(factory)) { - return new ScheduledReplicationTrigger(properties, scheduler); - } else if (ChainReplicateReplicationTrigger.TYPE.equals(factory)) { - return new ChainReplicateReplicationTrigger(properties, bundleContext); - } - - return null; - } - - private List<ReplicationTrigger> createTriggerList(List<Map<String, Object>> triggersProperties, ReplicationComponentProvider componentProvider) { - List<ReplicationTrigger> triggers = new ArrayList<ReplicationTrigger>(); - for (Map<String, Object> properties : triggersProperties) { - triggers.add(createTrigger(properties, componentProvider)); - } - - return triggers; - } - - Map<String, Object> extractMap(String key, Map<String, Object> objectMap) { - return SettingsUtils.extractMap(key, objectMap); - } - - List<Map<String, Object>> extractMapList(String key, Map<String, Object> objectMap) { - List<Map<String, Object>> result = new ArrayList<Map<String, Object>>(); - for (String mapKey : objectMap.keySet()) { - if (mapKey.startsWith(key)) { - result.add(SettingsUtils.extractMap(mapKey, objectMap)); - } - } - return result; - } - private void bindReplicationQueueProvider(ReplicationQueueProvider replicationQueueProvider, Map<String, Object> config) { String name = (String) config.get("name"); if (name != null) { replicationQueueProviderMap.put(name, replicationQueueProvider); - notifyListeners(replicationQueueProvider, name, true); } } @@ -371,7 +102,6 @@ public class DefaultReplicationComponent String name = (String) config.get("name"); if (name != null) { replicationQueueProviderMap.remove(name); - notifyListeners(replicationQueueProvider, name, false); } } @@ -380,8 +110,6 @@ public class DefaultReplicationComponent String name = (String) config.get("name"); if (name != null) { replicationQueueDistributionStrategyMap.put(name, replicationQueueDistributionStrategy); - notifyListeners(replicationQueueDistributionStrategy, name, true); - } } @@ -390,8 +118,6 @@ public class DefaultReplicationComponent String name = (String) config.get("name"); if (name != null) { replicationQueueDistributionStrategyMap.remove(name); - notifyListeners(replicationQueueDistributionStrategy, name, false); - } } @@ -400,7 +126,6 @@ public class DefaultReplicationComponent String name = (String) config.get("name"); if (name != null) { transportAuthenticationProviderMap.put(name, transportAuthenticationProvider); - notifyListeners(transportAuthenticationProvider, name, true); } @@ -411,7 +136,6 @@ public class DefaultReplicationComponent String name = (String) config.get("name"); if (name != null) { transportAuthenticationProviderMap.remove(name); - notifyListeners(transportAuthenticationProvider, name, false); } } @@ -421,7 +145,6 @@ public class DefaultReplicationComponent String name = (String) config.get("name"); if (name != null) { replicationPackageImporterMap.put(name, replicationPackageImporter); - notifyListeners(replicationPackageImporter, name, true); } } @@ -431,7 +154,6 @@ public class DefaultReplicationComponent String name = (String) config.get("name"); if (name != null) { replicationPackageImporterMap.remove(name); - notifyListeners(replicationPackageImporter, name, false); } } @@ -440,7 +162,6 @@ public class DefaultReplicationComponent String name = (String) config.get("name"); if (name != null) { replicationPackageExporterMap.put(name, replicationPackageExporter); - notifyListeners(replicationPackageExporter, name, true); } } @@ -449,39 +170,8 @@ public class DefaultReplicationComponent String name = (String) config.get("name"); if (name != null) { replicationPackageExporterMap.remove(name); - notifyListeners(replicationPackageExporter, name, false); - } - - } - - private void bindReplicationComponentListener(ReplicationComponentListener replicationComponentListener, Map<String, Object> config) { - - String name = (String) config.get("name"); - if (name != null) { - replicationComponentListenerMap.put(name, replicationComponentListener); - } - } - - private void unbindReplicationComponentListener(ReplicationComponentListener replicationComponentListener, Map<String, Object> config) { - String name = (String) config.get("name"); - if (name != null) { - replicationComponentListenerMap.remove(name); } - } - <ComponentType> void notifyListeners(ComponentType component, String componentName, boolean isBinding) { - for (ReplicationComponentListener listener : replicationComponentListenerMap.values()) { - try { - if (isBinding) { - listener.componentBind(component, componentName); - } else { - listener.componentUnbind(component, componentName); - } - } catch (Throwable t) { - log.error("Error while delivering event to ReplicationComponentListener", t); - } - } } - } Added: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/GenericReplicationComponentFactory.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/GenericReplicationComponentFactory.java?rev=1629162&view=auto ============================================================================== --- sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/GenericReplicationComponentFactory.java (added) +++ sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/GenericReplicationComponentFactory.java Fri Oct 3 09:33:20 2014 @@ -0,0 +1,163 @@ +package org.apache.sling.replication.agent.impl; + +import org.apache.felix.scr.annotations.*; +import org.apache.sling.commons.osgi.PropertiesUtil; +import org.apache.sling.replication.agent.ReplicationAgent; +import org.apache.sling.replication.agent.ReplicationComponent; +import org.apache.sling.replication.agent.ReplicationComponentFactory; +import org.apache.sling.replication.agent.ReplicationComponentProvider; +import org.apache.sling.replication.transport.authentication.TransportAuthenticationProvider; +import org.apache.sling.replication.trigger.ReplicationTrigger; +import org.apache.sling.settings.SlingSettingsService; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Dictionary; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +@Component(metatype = true, + label = "Generic Replication Components Factory", + description = "OSGi configuration factory for generic Replication Components", + configurationFactory = true, + specVersion = "1.1", + policy = ConfigurationPolicy.REQUIRE +) +public class GenericReplicationComponentFactory implements ReplicationComponentProvider { + + private final Logger log = LoggerFactory.getLogger(getClass()); + + @Property(boolValue = true, label = "Enabled") + private static final String ENABLED = "enabled"; + + @Property(label = "Name") + public static final String NAME = "name"; + + @Property(label = "Properties") + public static final String PROPERTIES = "properties"; + + @Property(label = "Component Type") + public static final String COMPONENT_TYPE = "componentType"; + + @Reference + private SlingSettingsService settingsService; + + @Reference + private ReplicationComponentFactory componentFactory; + + @Property(label = "Target TransportAuthenticationProvider", name = "transportAuthenticationProvider.target") + @Reference(name = "transportAuthenticationProvider", policy = ReferencePolicy.DYNAMIC, cardinality = ReferenceCardinality.OPTIONAL_UNARY) + private volatile TransportAuthenticationProvider transportAuthenticationProvider; + + private ServiceRegistration componentReg; + private String componentType; + + private BundleContext savedContext; + private Map<String, Object> savedConfig; + + @Activate + public void activate(BundleContext context, Map<String, Object> config) { + log.debug("activating component with config {}", config); + + savedContext = context; + savedConfig = config; + + // inject configuration + Dictionary<String, Object> props = new Hashtable<String, Object>(); + + boolean enabled = PropertiesUtil.toBoolean(config.get(ENABLED), true); + String name = PropertiesUtil.toString(config.get(NAME), null); + + componentType = PropertiesUtil.toString(config.get(COMPONENT_TYPE), null); + + if (enabled) { + props.put(ENABLED, true); + props.put(NAME, name); + + + if (componentReg == null) { + Map<String, Object> configProperties = SettingsUtils.extractMap(PROPERTIES, config); + + Map<String, Object> properties = new HashMap<String, Object>(); + properties.putAll(config); + properties.putAll(configProperties); + + String componentClass = null; + Object componentObject = null; + + if ("agent".equals(componentType)) { + ReplicationAgent agent = componentFactory.createComponent(ReplicationAgent.class, properties, this); + componentClass = ReplicationAgent.class.getName(); + componentObject = agent; + + } else if ("trigger".equals(componentType)) { + + ReplicationTrigger trigger = componentFactory.createComponent(ReplicationTrigger.class, properties, this); + + componentClass = ReplicationTrigger.class.getName(); + componentObject = trigger; + } + + if (componentObject != null && componentClass != null) { + if (componentObject instanceof ReplicationComponent) { + ((ReplicationComponent) componentObject).enable(); + } + + componentReg = context.registerService(componentClass, componentObject, props); + + + log.debug("activated component {} with name {}", componentType, name); + } + } + } + } + + @Deactivate + private void deactivate(BundleContext context) { + log.debug("deactivating component"); + if (componentReg != null) { + ServiceReference reference = componentReg.getReference(); + Object service = context.getService(reference); + if (service instanceof ReplicationComponent) { + ((ReplicationComponent) service).disable(); + } + + componentReg.unregister(); + componentReg = null; + } + + } + + private void refresh() { + if (savedContext != null && savedConfig != null) { + if (componentReg == null) { + activate(savedContext, savedConfig); + } + else if (componentReg != null) { + deactivate(savedContext); + activate(savedContext, savedConfig); + } + } + } + + private void bindTransportAuthenticationProvider(TransportAuthenticationProvider transportAuthenticationProvider) { + this.transportAuthenticationProvider = transportAuthenticationProvider; + refresh(); + } + + private void unbindTransportAuthenticationProvider(TransportAuthenticationProvider transportAuthenticationProvider) { + this.transportAuthenticationProvider = null; + refresh(); + } + + public <ComponentType> ComponentType getComponent(Class<ComponentType> type, String componentName) { + if (type.isAssignableFrom(TransportAuthenticationProvider.class)) { + return (ComponentType) transportAuthenticationProvider; + } + return null; + } +} Propchange: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/GenericReplicationComponentFactory.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/SimpleReplicationAgent.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/SimpleReplicationAgent.java?rev=1629162&r1=1629161&r2=1629162&view=diff ============================================================================== --- sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/SimpleReplicationAgent.java (original) +++ sling/trunk/contrib/extensions/replication/core/src/main/java/org/apache/sling/replication/agent/impl/SimpleReplicationAgent.java Fri Oct 3 09:33:20 2014 @@ -18,13 +18,11 @@ */ package org.apache.sling.replication.agent.impl; -import java.util.ArrayList; -import java.util.Dictionary; -import java.util.List; -import java.util.Properties; +import java.util.*; import org.apache.sling.replication.agent.AgentReplicationException; import org.apache.sling.replication.agent.ReplicationAgent; +import org.apache.sling.replication.agent.ReplicationComponent; import org.apache.sling.replication.communication.ReplicationRequest; import org.apache.sling.replication.communication.ReplicationResponse; import org.apache.sling.replication.event.ReplicationEventFactory; @@ -49,7 +47,7 @@ import org.slf4j.LoggerFactory; /** * Basic implementation of a {@link ReplicationAgent} */ -public class SimpleReplicationAgent implements ReplicationAgent { +public class SimpleReplicationAgent implements ReplicationAgent, ReplicationComponent { private final Logger log = LoggerFactory.getLogger(getClass()); @@ -75,15 +73,33 @@ public class SimpleReplicationAgent impl ReplicationPackageImporter replicationPackageImporter, ReplicationPackageExporter replicationPackageExporter, ReplicationQueueProvider queueProvider, - ReplicationQueueDistributionStrategy queueDistributionHandler, + ReplicationQueueDistributionStrategy queueDistributionStrategy, ReplicationEventFactory replicationEventFactory, List<ReplicationTrigger> triggers) { + + // check configuration is valid + if (name == null + || replicationPackageImporter == null + || replicationPackageExporter == null + || queueProvider == null + || queueDistributionStrategy == null + || replicationEventFactory == null) { + + String errorMessage = Arrays.toString(new Object[]{name, + replicationPackageImporter, + replicationPackageExporter, + queueProvider, + queueDistributionStrategy, + replicationEventFactory}); + throw new IllegalArgumentException("all arguments are required: " + errorMessage); + } + this.name = name; this.passive = passive; this.replicationPackageImporter = replicationPackageImporter; this.replicationPackageExporter = replicationPackageExporter; this.queueProvider = queueProvider; - this.queueDistributionStrategy = queueDistributionHandler; + this.queueDistributionStrategy = queueDistributionStrategy; this.useAggregatePaths = useAggregatePaths; this.replicationEventFactory = replicationEventFactory; this.triggers = triggers == null ? new ArrayList<ReplicationTrigger>() : triggers;