import com.google.common.base.Strings;
import java.util.ArrayList;
import java.util.Dictionary;
-import java.util.Hashtable;
import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.aries.blueprint.ComponentDefinitionRegistry;
import org.apache.aries.blueprint.ComponentDefinitionRegistryProcessor;
import org.apache.aries.blueprint.ext.AbstractPropertyPlaceholder;
import org.opendaylight.controller.blueprint.BlueprintContainerRestartService;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.blueprint.reflect.BeanProperty;
-import org.osgi.service.blueprint.reflect.ComponentMetadata;
import org.osgi.service.blueprint.reflect.ValueMetadata;
import org.osgi.service.cm.ManagedService;
import org.slf4j.Logger;
* @author Thomas Pantelis
*/
public class ComponentProcessor implements ComponentDefinitionRegistryProcessor {
+ static final String DEFAULT_TYPE_FILTER = "(|(type=default)(!(type=*)))";
+
private static final Logger LOG = LoggerFactory.getLogger(ComponentProcessor.class);
private static final String CM_PERSISTENT_ID_PROPERTY = "persistentId";
private final List<ServiceRegistration<?>> managedServiceRegs = new ArrayList<>();
- private Bundle bundle;
- private BlueprintContainerRestartService blueprintContainerRestartService;
+ private Bundle bundle = null;
+ private BlueprintContainerRestartService blueprintContainerRestartService = null;
private boolean restartDependentsOnUpdates;
private boolean useDefaultForReferenceTypes;
- public void setBundle(Bundle bundle) {
+ public void setBundle(final Bundle bundle) {
this.bundle = bundle;
}
- public void setBlueprintContainerRestartService(BlueprintContainerRestartService restartService) {
- this.blueprintContainerRestartService = restartService;
+ public void setBlueprintContainerRestartService(final BlueprintContainerRestartService restartService) {
+ blueprintContainerRestartService = restartService;
}
- public void setRestartDependentsOnUpdates(boolean restartDependentsOnUpdates) {
+ public void setRestartDependentsOnUpdates(final boolean restartDependentsOnUpdates) {
this.restartDependentsOnUpdates = restartDependentsOnUpdates;
}
- public void setUseDefaultForReferenceTypes(boolean useDefaultForReferenceTypes) {
+ public void setUseDefaultForReferenceTypes(final boolean useDefaultForReferenceTypes) {
this.useDefaultForReferenceTypes = useDefaultForReferenceTypes;
}
public void destroy() {
- for(ServiceRegistration<?> reg: managedServiceRegs) {
- AriesFrameworkUtil.safeUnregisterService(reg);
- }
+ managedServiceRegs.forEach(AriesFrameworkUtil::safeUnregisterService);
}
@Override
- public void process(ComponentDefinitionRegistry registry) {
+ public void process(final ComponentDefinitionRegistry registry) {
LOG.debug("{}: In process", logName());
- for(String name : registry.getComponentDefinitionNames()) {
- ComponentMetadata component = registry.getComponentDefinition(name);
- if(component instanceof MutableBeanMetadata) {
- processMutableBeanMetadata((MutableBeanMetadata)component);
- } else if(component instanceof MutableServiceReferenceMetadata) {
- processServiceReferenceMetadata((MutableServiceReferenceMetadata)component);
+ for (var name : registry.getComponentDefinitionNames()) {
+ final var component = registry.getComponentDefinition(name);
+ if (component instanceof MutableBeanMetadata bean) {
+ processMutableBeanMetadata(bean);
+ } else if (component instanceof MutableServiceReferenceMetadata serviceRef) {
+ processServiceReferenceMetadata(serviceRef);
}
}
}
- private void processServiceReferenceMetadata(MutableServiceReferenceMetadata serviceRef) {
- if(!useDefaultForReferenceTypes) {
+ private void processServiceReferenceMetadata(final MutableServiceReferenceMetadata serviceRef) {
+ if (!useDefaultForReferenceTypes) {
return;
}
LOG.debug("{}: processServiceReferenceMetadata for {}, filter: {}, ext filter: {}", logName(),
serviceRef.getId(), filter, extFilter);
- if(Strings.isNullOrEmpty(filter) && Strings.isNullOrEmpty(extFilter)) {
- serviceRef.setFilter("(|(type=default)(!(type=*)))");
+ if (Strings.isNullOrEmpty(filter) && Strings.isNullOrEmpty(extFilter)) {
+ serviceRef.setFilter(DEFAULT_TYPE_FILTER);
LOG.debug("{}: processServiceReferenceMetadata for {} set filter to {}", logName(),
serviceRef.getId(), serviceRef.getFilter());
}
}
- private void processMutableBeanMetadata(MutableBeanMetadata bean) {
- if(restartDependentsOnUpdates && bean.getRuntimeClass() != null &&
- AbstractPropertyPlaceholder.class.isAssignableFrom(bean.getRuntimeClass())) {
+ private void processMutableBeanMetadata(final MutableBeanMetadata bean) {
+ if (restartDependentsOnUpdates && bean.getRuntimeClass() != null
+ && AbstractPropertyPlaceholder.class.isAssignableFrom(bean.getRuntimeClass())) {
LOG.debug("{}: Found PropertyPlaceholder bean: {}, runtime {}", logName(), bean.getId(),
bean.getRuntimeClass());
- for(BeanProperty prop: bean.getProperties()) {
- if(CM_PERSISTENT_ID_PROPERTY.equals(prop.getName())) {
- if(prop.getValue() instanceof ValueMetadata) {
- ValueMetadata persistentId = (ValueMetadata)prop.getValue();
-
- LOG.debug("{}: Found {} property, value : {}", logName(),
- CM_PERSISTENT_ID_PROPERTY, persistentId.getStringValue());
-
+ for (var prop : bean.getProperties()) {
+ if (CM_PERSISTENT_ID_PROPERTY.equals(prop.getName())) {
+ if (prop.getValue() instanceof ValueMetadata persistentId) {
+ LOG.debug("{}: Found {} property, value : {}", logName(), CM_PERSISTENT_ID_PROPERTY,
+ persistentId.getStringValue());
registerManagedService(persistentId.getStringValue());
} else {
- LOG.debug("{}: {} property metadata {} is not instanceof ValueMetadata",
- logName(), CM_PERSISTENT_ID_PROPERTY, prop.getValue());
+ LOG.debug("{}: {} property metadata {} is not instanceof ValueMetadata", logName(),
+ CM_PERSISTENT_ID_PROPERTY, prop.getValue());
}
break;
private void registerManagedService(final String persistentId) {
// Register a ManagedService so we get updates from the ConfigAdmin when the cfg file corresponding
// to the persistentId changes.
- ManagedService managedService = new ManagedService() {
- private volatile boolean initialUpdate = true;
+ final var managedService = new ManagedService() {
+ private final AtomicBoolean initialUpdate = new AtomicBoolean(true);
+ private volatile Dictionary<String, ?> previousProperties;
@Override
- public void updated(Dictionary<String, ?> properties) {
+ public void updated(final Dictionary<String, ?> properties) {
LOG.debug("{}: ManagedService updated for persistentId {}, properties: {}, initialUpdate: {}",
logName(), persistentId, properties, initialUpdate);
// The first update occurs when the service is registered so ignore it as we want subsequent
// updates when it changes. The ConfigAdmin will send an update even if the cfg file doesn't
// yet exist.
- if(initialUpdate) {
- initialUpdate = false;
- } else {
+ if (!initialUpdate.compareAndSet(true, false) && !Objects.equals(previousProperties, properties)) {
blueprintContainerRestartService.restartContainerAndDependents(bundle);
}
+
+ previousProperties = properties;
}
};
- Dictionary<String, Object> props = new Hashtable<>();
- props.put(Constants.SERVICE_PID, persistentId);
- props.put(Constants.BUNDLE_SYMBOLICNAME, bundle.getSymbolicName());
- props.put(Constants.BUNDLE_VERSION, bundle.getHeaders().get(Constants.BUNDLE_VERSION));
- managedServiceRegs.add(bundle.getBundleContext().registerService(ManagedService.class.getName(),
- managedService, props));
+ managedServiceRegs.add(bundle.getBundleContext().registerService(ManagedService.class, managedService,
+ FrameworkUtil.asDictionary(Map.of(
+ Constants.SERVICE_PID, persistentId,
+ Constants.BUNDLE_SYMBOLICNAME, bundle.getSymbolicName(),
+ Constants.BUNDLE_VERSION, bundle.getHeaders().get(Constants.BUNDLE_VERSION)))));
}
private String logName() {