Return-Path: X-Original-To: apmail-sling-commits-archive@www.apache.org Delivered-To: apmail-sling-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 4A3E017BE2 for ; Tue, 11 Nov 2014 14:17:56 +0000 (UTC) Received: (qmail 75546 invoked by uid 500); 11 Nov 2014 14:17:56 -0000 Delivered-To: apmail-sling-commits-archive@sling.apache.org Received: (qmail 75490 invoked by uid 500); 11 Nov 2014 14:17:56 -0000 Mailing-List: contact commits-help@sling.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@sling.apache.org Delivered-To: mailing list commits@sling.apache.org Received: (qmail 75481 invoked by uid 99); 11 Nov 2014 14:17:56 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 11 Nov 2014 14:17:56 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 11 Nov 2014 14:17:53 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 810C923888D7; Tue, 11 Nov 2014 14:16:03 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1638116 - in /sling/trunk/contrib/extensions/distribution: api/src/main/java/org/apache/sling/distribution/component/ core/src/main/java/org/apache/sling/distribution/component/impl/ sample/src/main/resources/SLING-CONTENT/libs/sling/distr... Date: Tue, 11 Nov 2014 14:16:03 -0000 To: commits@sling.apache.org From: mpetria@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20141111141603.810C923888D7@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: mpetria Date: Tue Nov 11 14:16:02 2014 New Revision: 1638116 URL: http://svn.apache.org/r1638116 Log: SLING-4149: renaming factory to resource based & adding defaults Added: sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/component/impl/ResourceBasedDistributionComponentFactory.java sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/install.author/org.apache.sling.distribution.component.impl.ResourceBasedDistributionComponentFactory-agents.json sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/jcrsettings/defaults/ sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/jcrsettings/defaults/agents/ sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/jcrsettings/defaults/agents/global.json Removed: sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/component/impl/ContentBasedDistributionComponentFactory.java sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/install.author/org.apache.sling.distribution.component.impl.ContentBasedDistributionComponentFactory-agents.json Modified: sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/component/DistributionComponentFactory.java sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/component/impl/DefaultDistributionComponentFactory.java sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/jcrsettings/agents/jpublish.json Modified: sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/component/DistributionComponentFactory.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/component/DistributionComponentFactory.java?rev=1638116&r1=1638115&r2=1638116&view=diff ============================================================================== --- sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/component/DistributionComponentFactory.java (original) +++ sling/trunk/contrib/extensions/distribution/api/src/main/java/org/apache/sling/distribution/component/DistributionComponentFactory.java Tue Nov 11 14:16:02 2014 @@ -293,6 +293,12 @@ public interface DistributionComponentFa String QUEUE_PROVIDER_JOB = "job"; /** + * property for default topics + */ + String QUEUE_PROVIDER_PROPERTY_QUEUE_PREFIX = "queue.prefix"; + + + /** * queue provider simple type */ String QUEUE_PROVIDER_SIMPLE = "simple"; Modified: sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/component/impl/DefaultDistributionComponentFactory.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/component/impl/DefaultDistributionComponentFactory.java?rev=1638116&r1=1638115&r2=1638116&view=diff ============================================================================== --- sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/component/impl/DefaultDistributionComponentFactory.java (original) +++ sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/component/impl/DefaultDistributionComponentFactory.java Tue Nov 11 14:16:02 2014 @@ -146,6 +146,8 @@ public class DefaultDistributionComponen String factory = PropertiesUtil.toString(properties.get(COMPONENT_TYPE), DistributionComponentFactory.AGENT_SIMPLE); if (DistributionComponentFactory.AGENT_SIMPLE.equals(factory)) { + String agentName = PropertiesUtil.toString(properties.get(COMPONENT_NAME), null); + Map exporterProperties = extractMap(COMPONENT_PACKAGE_EXPORTER, properties); DistributionPackageExporter packageExporter = createExporter(exporterProperties, componentProvider); @@ -160,18 +162,18 @@ public class DefaultDistributionComponen DistributionQueueDistributionStrategy queueDistributionStrategy = createDistributionStrategy(queueDistributionStrategyProperties, componentProvider); Map queueProviderProperties = extractMap(COMPONENT_QUEUE_PROVIDER, properties); + queueProviderProperties.put(QUEUE_PROVIDER_PROPERTY_QUEUE_PREFIX, agentName); DistributionQueueProvider queueProvider = createQueueProvider(queueProviderProperties, componentProvider); List> triggersProperties = extractMapList(COMPONENT_TRIGGER, properties); List triggers = createTriggerList(triggersProperties, componentProvider); - String name = PropertiesUtil.toString(properties.get(COMPONENT_NAME), String.valueOf(new Random().nextInt(1000))); String serviceName = PropertiesUtil.toString(properties.get(DistributionComponentFactory.AGENT_SIMPLE_PROPERTY_SERVICE_NAME), null); boolean isPassive = PropertiesUtil.toBoolean(properties.get(DistributionComponentFactory.AGENT_SIMPLE_PROPERTY_IS_PASSIVE), false); - return new SimpleDistributionAgent(name, isPassive, serviceName, + return new SimpleDistributionAgent(agentName, isPassive, serviceName, packageImporter, packageExporter, packageExporterStrategy, queueProvider, queueDistributionStrategy, distributionEventFactory, resourceResolverFactory, triggers); @@ -267,13 +269,13 @@ public class DefaultDistributionComponen return componentProvider.getComponent(DistributionQueueProvider.class, name); } else if (QUEUE_PROVIDER_JOB.equals(factory)) { - String name = PropertiesUtil.toString(properties.get(COMPONENT_NAME), null); - return new JobHandlingDistributionQueueProvider(name, jobManager, bundleContext); + String prefix = PropertiesUtil.toString(properties.get(QUEUE_PROVIDER_PROPERTY_QUEUE_PREFIX), null); + return new JobHandlingDistributionQueueProvider(prefix, jobManager, bundleContext); } else if (QUEUE_PROVIDER_SIMPLE.equals(factory)) { - String name = PropertiesUtil.toString(properties.get(COMPONENT_NAME), null); + String prefix = PropertiesUtil.toString(properties.get(QUEUE_PROVIDER_PROPERTY_QUEUE_PREFIX), null); - return new SimpleDistributionQueueProvider(scheduler, name); + return new SimpleDistributionQueueProvider(scheduler, prefix); } return null; Added: sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/component/impl/ResourceBasedDistributionComponentFactory.java URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/component/impl/ResourceBasedDistributionComponentFactory.java?rev=1638116&view=auto ============================================================================== --- sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/component/impl/ResourceBasedDistributionComponentFactory.java (added) +++ sling/trunk/contrib/extensions/distribution/core/src/main/java/org/apache/sling/distribution/component/impl/ResourceBasedDistributionComponentFactory.java Tue Nov 11 14:16:02 2014 @@ -0,0 +1,300 @@ +/* + * 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.distribution.component.impl; + +import org.apache.felix.scr.annotations.*; +import org.apache.sling.api.SlingConstants; +import org.apache.sling.api.resource.*; +import org.apache.sling.commons.osgi.PropertiesUtil; +import org.apache.sling.distribution.agent.DistributionAgent; +import org.apache.sling.distribution.component.DistributionComponentFactory; +import org.apache.sling.distribution.component.ManagedDistributionComponent; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; +import org.osgi.service.event.Event; +import org.osgi.service.event.EventConstants; +import org.osgi.service.event.EventHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Dictionary; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * An resource based service factory for {@link org.apache.sling.distribution.component.DistributionComponent}s using a compact configuration, already existing OSGi services + * for the components to be wired can be used as well as directly instantiated components (called by type name). + */ +@Component(metatype = true, + label = "Sling Distribution - Resource Based Component Factory", + description = "Resource configuration for Distribution Components Factory", + configurationFactory = true, + specVersion = "1.1", + policy = ConfigurationPolicy.REQUIRE +) +public class ResourceBasedDistributionComponentFactory { + + private static final int MAX_LEVEL = 2; + + private final Logger log = LoggerFactory.getLogger(getClass()); + + @Property(label = "Name") + public static final String NAME = "name"; + + @Property(label = "Kind") + public static final String KIND = "kind"; + + @Property(label = "Path") + public static final String PATH = "path"; + + @Property(label = "Defaults Path") + public static final String DEFAULTS_PATH = "defaults.path"; + + + @Reference + DistributionComponentFactory componentFactory; + + @Reference + ResourceResolverFactory resourceResolverFactory; + + + private Map componentRegistrations = new ConcurrentHashMap(); + private ServiceRegistration resourceListenerRegistration; + + private BundleContext savedContext; + private Map savedConfig; + + private String name; + private String kind; + private String path; + private String defaultsPath; + + @Activate + public void activate(BundleContext context, Map config) throws Exception { + log.debug("activating agent with config {}", config); + + savedContext = context; + savedConfig = config; + + // inject configuration + Dictionary componentListenerProperties = new Hashtable(); + + name = PropertiesUtil.toString(config.get(NAME), null); + kind = PropertiesUtil.toString(config.get(KIND), null); + path = PropertiesUtil.toString(config.get(PATH), null); + defaultsPath = PropertiesUtil.toString(config.get(DEFAULTS_PATH), null); + + componentListenerProperties.put(NAME, name); + + + Dictionary eventProperties = new Hashtable(); + eventProperties.put(EventConstants.EVENT_TOPIC, new String[]{ + SlingConstants.TOPIC_RESOURCE_ADDED, + SlingConstants.TOPIC_RESOURCE_CHANGED, + SlingConstants.TOPIC_RESOURCE_REMOVED + }); + + eventProperties.put(EventConstants.EVENT_FILTER, "(path=" + path + "/*)"); + resourceListenerRegistration = context.registerService(EventHandler.class.getName(), + new ResourceChangeEventHandler() , eventProperties); + + registerAll(); + } + + @Deactivate + private void deactivate(BundleContext context) { + + + if (resourceListenerRegistration != null) { + resourceListenerRegistration.unregister(); + resourceListenerRegistration = null; + } + + unregisterAll(); + } + + private void refresh(String name) { + unregister(name); + register(name); + } + + + private void unregisterAll() { + for(String name : componentRegistrations.keySet()) { + unregister(name); + } + } + + private void registerAll() { + ResourceResolver resourceResolver = null; + try { + resourceResolver = getResolver(); + Resource resourceRoot = resourceResolver.getResource(path); + + if (resourceRoot != null && !ResourceUtil.isNonExistingResource(resourceRoot)) { + for (Resource resource : resourceResolver.getChildren(resourceRoot)) { + String name = resource.getName(); + register(name); + } + } + } catch (LoginException e) { + if (resourceResolver != null) { + resourceResolver.close(); + + } + } + } + + ResourceResolver getResolver() throws LoginException { + ResourceResolver resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(null); + + return resourceResolver; + } + + private void register(String name) { + ResourceResolver resourceResolver = null; + try { + resourceResolver = getResolver(); + Resource resource = resourceResolver.getResource(path + "/" + name); + Map config = new HashMap(); + + if (defaultsPath != null) { + Resource defaultsResource = resourceResolver.getResource(defaultsPath); + if (defaultsResource != null) { + config = extractMap(0, defaultsResource); + } + } + Map componentConfig = extractMap(0, resource); + + putMap(0, componentConfig, config); + config.put(DistributionComponentFactory.COMPONENT_NAME, name); + + register(name, config); + } catch (LoginException e) { + if (resourceResolver != null) { + resourceResolver.close(); + + } + } + + } + + private void unregister(String name) { + + ServiceRegistration componentReg = componentRegistrations.get(name); + + if (componentReg != null) { + ServiceReference reference = componentReg.getReference(); + + if ("agent".equals(kind)) { + Object replicationComponent = savedContext.getService(reference); + if (replicationComponent instanceof ManagedDistributionComponent) { + ((ManagedDistributionComponent) replicationComponent).disable(); + } + } + + componentReg.unregister(); + + } + } + + private Map extractMap(int level, Resource resource) { + if (level > MAX_LEVEL) + return null; + + Map result = new HashMap(); + ValueMap resourceProperties = ResourceUtil.getValueMap(resource); + result.putAll(resourceProperties); + + for (Resource childResource : resource.getChildren()) { + Map childMap = extractMap(level+1, childResource); + if (childMap != null) { + result.put(childResource.getName(), childMap); + } + } + + return result; + } + + private void putMap(int level, Map source, Map target) { + if (level > MAX_LEVEL) + return; + + for (Map.Entry entry : source.entrySet()) { + + if (target.containsKey(entry.getKey()) + && entry.getValue() instanceof Map + && target.get(entry.getKey()) instanceof Map) { + putMap(level, (Map) entry.getValue(), (Map) target.get(entry.getKey())); + + } + else { + target.put(entry.getKey(), entry.getValue()); + } + } + + + + + } + + private void register(String componentName, Map config) { + String componentClass = null; + Object componentObject = null; + + if ("agent".equals(kind)) { + componentClass = DistributionAgent.class.getName(); + componentObject = componentFactory.createComponent(DistributionAgent.class, config, null); + } + + + if (componentObject != null && componentClass != null) { + if (componentObject instanceof ManagedDistributionComponent) { + ((ManagedDistributionComponent) componentObject).enable(); + } + + Dictionary props = new Hashtable(); + props.put(NAME, componentName); + ServiceRegistration componentReg = savedContext.registerService(componentClass, componentObject, props); + componentRegistrations.put(componentName, componentReg); + log.debug("activated component kind {} name", kind, componentName); + } + } + + private class ResourceChangeEventHandler implements EventHandler { + + public void handleEvent(Event event) { + String eventPath = (String) event.getProperty("path"); + String prefix = path + "/"; + if (eventPath != null && eventPath.startsWith(prefix)) { + String name = eventPath.substring(prefix.length()); + int slashIndex = name.indexOf('/'); + if (slashIndex >= 0) { + name = name.substring(0, slashIndex); + } + refresh(name); + } + } + } + + +} Added: sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/install.author/org.apache.sling.distribution.component.impl.ResourceBasedDistributionComponentFactory-agents.json URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/install.author/org.apache.sling.distribution.component.impl.ResourceBasedDistributionComponentFactory-agents.json?rev=1638116&view=auto ============================================================================== --- sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/install.author/org.apache.sling.distribution.component.impl.ResourceBasedDistributionComponentFactory-agents.json (added) +++ sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/install.author/org.apache.sling.distribution.component.impl.ResourceBasedDistributionComponentFactory-agents.json Tue Nov 11 14:16:02 2014 @@ -0,0 +1,8 @@ +{ + "jcr:primaryType": "sling:OsgiConfig", + "name": "agents", + + "kind": "agent", + "path": "/libs/sling/distribution/jcrsettings/agents", + "defaults.path" : "/libs/sling/distribution/jcrsettings/defaults/agents/global" +} \ No newline at end of file Modified: sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/jcrsettings/agents/jpublish.json URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/jcrsettings/agents/jpublish.json?rev=1638116&r1=1638115&r2=1638116&view=diff ============================================================================== --- sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/jcrsettings/agents/jpublish.json (original) +++ sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/jcrsettings/agents/jpublish.json Tue Nov 11 14:16:02 2014 @@ -1,18 +1,8 @@ { - "name": "jpublish", - "jcr:primaryType" : "nt:unstructured", - "serviceName" : "distributionService", - "requestAuthorizationStrategy" : { - "type" : "privilege", - "jcrPrivilege" : "jcr:read" - }, - "packageExporter": { - "type": "local", - "packageBuilder" : { "type" : "vlt" } - + "type": "local" }, "packageImporter": { @@ -26,13 +16,6 @@ "endpoints" : [ "http://localhost:4503/libs/sling/distribution/services/importers/default" - ], - - "packageBuilder" : { "type" : "vlt" } - - }, - - "queueDistributionStrategy" : { "type" : "single" }, - - "queueProvider" : { "type" : "job", "name" : "jpublish" } + ] + } } \ No newline at end of file Added: sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/jcrsettings/defaults/agents/global.json URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/jcrsettings/defaults/agents/global.json?rev=1638116&view=auto ============================================================================== --- sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/jcrsettings/defaults/agents/global.json (added) +++ sling/trunk/contrib/extensions/distribution/sample/src/main/resources/SLING-CONTENT/libs/sling/distribution/jcrsettings/defaults/agents/global.json Tue Nov 11 14:16:02 2014 @@ -0,0 +1,22 @@ +{ + "jcr:primaryType" : "nt:unstructured", + + "requestAuthorizationStrategy" : { + "type" : "privilege", + "jcrPrivilege" : "jcr:read" + }, + + "packageExporter": { + "packageBuilder" : { "type" : "vlt" } + + }, + + "packageImporter": { + "packageBuilder" : { "type" : "vlt" } + + }, + + "queueDistributionStrategy" : { "type" : "single" }, + + "queueProvider" : { "type" : "job" } +} \ No newline at end of file