| /* |
| * 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.agent.impl; |
| |
| import java.util.Dictionary; |
| import java.util.Hashtable; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.concurrent.CopyOnWriteArrayList; |
| |
| import javax.management.ObjectName; |
| |
| import org.apache.sling.commons.osgi.PropertiesUtil; |
| import org.apache.sling.distribution.agent.spi.DistributionAgent; |
| import org.apache.sling.distribution.component.impl.DistributionComponentConstants; |
| import org.apache.sling.distribution.component.impl.DistributionComponentKind; |
| import org.apache.sling.distribution.component.impl.SettingsUtils; |
| import org.apache.sling.distribution.log.impl.DefaultDistributionLog; |
| import org.apache.sling.distribution.resources.impl.OsgiUtils; |
| import org.apache.sling.distribution.trigger.DistributionTrigger; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.framework.ServiceReference; |
| import org.osgi.framework.ServiceRegistration; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| /** |
| * An abstract OSGi service factory for registering {@link org.apache.sling.distribution.agent.impl.SimpleDistributionAgent}s |
| */ |
| abstract class AbstractDistributionAgentFactory<DistributionAgentMBeanType> { |
| private final Logger log = LoggerFactory.getLogger(getClass()); |
| |
| private static final String NAME = DistributionComponentConstants.PN_NAME; |
| |
| private static final String ENABLED = "enabled"; |
| |
| static final String DEFAULT_TRIGGER_TARGET = "(name=)"; |
| |
| private static final String TRIGGERS_TARGET = "triggers.target"; |
| |
| static final String LOG_LEVEL = "log.level"; |
| |
| private final Class<DistributionAgentMBeanType> distributionAgentMBeanType; |
| |
| private ServiceRegistration componentReg; |
| private ServiceRegistration mbeanServiceRegistration; |
| private String agentName; |
| private final List<DistributionTrigger> triggers = new CopyOnWriteArrayList<DistributionTrigger>(); |
| private boolean triggersEnabled = false; |
| |
| private SimpleDistributionAgent agent; |
| |
| AbstractDistributionAgentFactory(Class<DistributionAgentMBeanType> distributionAgentMBeanType) { |
| this.distributionAgentMBeanType = distributionAgentMBeanType; |
| } |
| |
| void activate(BundleContext context, Map<String, Object> config) { |
| log.info("activating with config {}", OsgiUtils.osgiPropertyMapToString(config)); |
| |
| // inject configuration |
| Dictionary<String, Object> props = new Hashtable<String, Object>(); |
| |
| boolean enabled = PropertiesUtil.toBoolean(config.get(ENABLED), true); |
| String triggersTarget = SettingsUtils.removeEmptyEntry(PropertiesUtil.toString(config.get(TRIGGERS_TARGET), null)); |
| triggersEnabled = triggersTarget != null && triggersTarget.trim().length() > 0; |
| agentName = PropertiesUtil.toString(config.get(NAME), null); |
| |
| |
| if (enabled && agentName != null) { |
| |
| for (Map.Entry<String, Object> entry : config.entrySet()) { |
| // skip service and component related properties |
| if (entry.getKey().startsWith("service.") || entry.getKey().startsWith("component.")) { |
| continue; |
| } |
| |
| props.put(entry.getKey(), entry.getValue()); |
| |
| } |
| |
| if (componentReg == null) { |
| |
| DefaultDistributionLog distributionLog = null; |
| try { |
| |
| String logLevel = PropertiesUtil.toString(config.get(LOG_LEVEL), DefaultDistributionLog.LogLevel.INFO.name()); |
| DefaultDistributionLog.LogLevel level = DefaultDistributionLog.LogLevel.valueOf(logLevel.trim().toUpperCase()); |
| if (level == null) { |
| level = DefaultDistributionLog.LogLevel.INFO; |
| } |
| |
| |
| distributionLog = new DefaultDistributionLog(DistributionComponentKind.AGENT, agentName, SimpleDistributionAgent.class, level); |
| |
| agent = createAgent(agentName, context, config, distributionLog); |
| } catch (Throwable t) { |
| if (distributionLog != null) { |
| distributionLog.error("Cannot create agent", t); |
| } |
| log.error("Cannot create agent {}", OsgiUtils.osgiPropertyMapToString(config), t); |
| } |
| |
| |
| if (agent != null) { |
| |
| // register agent service |
| componentReg = context.registerService(DistributionAgent.class.getName(), agent, props); |
| agent.enable(); |
| |
| |
| if (triggersEnabled) { |
| for (DistributionTrigger trigger : triggers) { |
| agent.enableTrigger(trigger); |
| } |
| } |
| |
| Dictionary<String, String> mbeanProps = new Hashtable<String, String>(); |
| mbeanProps.put("jmx.objectname", "org.apache.sling.distribution:type=agent,id=" + ObjectName.quote(agentName)); |
| |
| DistributionAgentMBeanType mbean = createMBeanAgent(agent, config); |
| mbeanServiceRegistration = context.registerService(distributionAgentMBeanType.getName(), mbean, mbeanProps); |
| |
| } |
| |
| log.info("activated agent {}", agentName); |
| |
| } |
| } |
| } |
| |
| synchronized void bindDistributionTrigger(DistributionTrigger distributionTrigger, Map<String, Object> config) { |
| triggers.add(distributionTrigger); |
| if (agent != null && triggersEnabled) { |
| agent.enableTrigger(distributionTrigger); |
| } |
| |
| } |
| |
| synchronized void unbindDistributionTrigger(DistributionTrigger distributionTrigger, Map<String, Object> config) { |
| triggers.remove(distributionTrigger); |
| |
| if (agent != null) { |
| agent.disableTrigger(distributionTrigger); |
| } |
| } |
| |
| |
| void deactivate(BundleContext context) { |
| if (componentReg != null) { |
| ServiceReference reference = componentReg.getReference(); |
| Object service = context.getService(reference); |
| if (service instanceof SimpleDistributionAgent) { |
| SimpleDistributionAgent agent = (SimpleDistributionAgent) service; |
| for (DistributionTrigger trigger : triggers) { |
| agent.disableTrigger(trigger); |
| } |
| triggers.clear(); |
| triggersEnabled = false; |
| agent.disable(); |
| } |
| |
| if (safeUnregister(componentReg)) { |
| componentReg = null; |
| } |
| agent = null; |
| } |
| |
| if (safeUnregister(mbeanServiceRegistration)) { |
| mbeanServiceRegistration = null; |
| } |
| |
| log.info("deactivated agent {}", agentName); |
| } |
| |
| private static boolean safeUnregister(ServiceRegistration serviceRegistration) { |
| if (serviceRegistration != null) { |
| serviceRegistration.unregister(); |
| return true; |
| } |
| return false; |
| } |
| |
| protected abstract SimpleDistributionAgent createAgent(String agentName, BundleContext context, Map<String, Object> config, DefaultDistributionLog distributionLog); |
| |
| protected abstract DistributionAgentMBeanType createMBeanAgent(DistributionAgent agent, Map<String, Object> osgiConfiguration); |
| |
| } |