You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by to...@apache.org on 2014/10/03 11:33:22 UTC

svn commit: r1629162 [1/2] - in /sling/trunk/contrib/extensions/replication: core/src/main/java/org/apache/sling/replication/agent/ core/src/main/java/org/apache/sling/replication/agent/impl/ core/src/main/java/org/apache/sling/replication/packaging/ c...

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;