import javax.management.InstanceNotFoundException;
import javax.management.MBeanServer;
import javax.management.ObjectName;
-import java.util.ArrayList;
-import java.util.Collection;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.concurrent.atomic.AtomicBoolean;
import static java.lang.String.format;
private final DependencyResolverManager dependencyResolverManager;
private final TransactionStatus transactionStatus;
private final MBeanServer transactionsMBeanServer;
- private final List<ModuleFactory> currentlyRegisteredFactories;
+ private final Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories;
/**
* Disables ability of {@link DynamicWritableWrapper} to change attributes
configBeanModificationDisabled);
private final MBeanServer configMBeanServer;
- private final BundleContext bundleContext;
+ private final boolean blankTransaction;
public ConfigTransactionControllerImpl(String transactionName,
TransactionJMXRegistrator transactionRegistrator,
long parentVersion, long currentVersion,
- List<ModuleFactory> currentlyRegisteredFactories,
- MBeanServer transactionsMBeanServer, MBeanServer configMBeanServer, BundleContext bundleContext) {
+ Map<String, Map.Entry<ModuleFactory, BundleContext>> currentlyRegisteredFactories,
+ MBeanServer transactionsMBeanServer, MBeanServer configMBeanServer,
+ boolean blankTransaction) {
this.transactionIdentifier = new TransactionIdentifier(transactionName);
this.controllerON = ObjectNameUtil
this.dependencyResolverManager = new DependencyResolverManager(transactionName, transactionStatus);
this.transactionsMBeanServer = transactionsMBeanServer;
this.configMBeanServer = configMBeanServer;
- this.bundleContext = bundleContext;
+ this.blankTransaction = blankTransaction;
}
@Override
transactionStatus.checkNotAborted();
Set<ModuleFactory> oldSet = new HashSet<>(lastListOfFactories);
- Set<ModuleFactory> newSet = new HashSet<>(currentlyRegisteredFactories);
+ Set<ModuleFactory> newSet = new HashSet<>(factoriesHolder.getModuleFactories());
List<ModuleFactory> toBeAdded = new ArrayList<>();
List<ModuleFactory> toBeRemoved = new ArrayList<>();
- for(ModuleFactory moduleFactory: currentlyRegisteredFactories) {
+ for(ModuleFactory moduleFactory: factoriesHolder.getModuleFactories()) {
if (oldSet.contains(moduleFactory) == false){
toBeAdded.add(moduleFactory);
}
}
// add default modules
for (ModuleFactory moduleFactory : toBeAdded) {
- Set<? extends Module> defaultModules = moduleFactory.getDefaultModules(dependencyResolverManager, bundleContext);
+ Set<? extends Module> defaultModules = moduleFactory.getDefaultModules(dependencyResolverManager,
+ getModuleFactoryBundleContext(moduleFactory.getImplementationName()));
for (Module module : defaultModules) {
// ensure default module to be registered to jmx even if its module factory does not use dependencyResolverFactory
DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(module.getIdentifier());
try {
- putConfigBeanToJMXAndInternalMaps(module.getIdentifier(), module, moduleFactory, null, dependencyResolver);
+ boolean defaultBean = true;
+ putConfigBeanToJMXAndInternalMaps(module.getIdentifier(), module, moduleFactory, null, dependencyResolver, defaultBean);
} catch (InstanceAlreadyExistsException e) {
throw new IllegalStateException(e);
}
DependencyResolver dependencyResolver = dependencyResolverManager
.getOrCreate(moduleIdentifier);
try {
+ BundleContext bc = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
module = moduleFactory.createModule(
moduleIdentifier.getInstanceName(), dependencyResolver,
- oldConfigBeanInfo.getReadableModule(), bundleContext);
+ oldConfigBeanInfo.getReadableModule(), bc);
} catch (Exception e) {
throw new IllegalStateException(format(
"Error while copying old configuration from %s to %s",
oldConfigBeanInfo, moduleFactory), e);
}
- putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module, moduleFactory, oldConfigBeanInfo, dependencyResolver);
+ putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module, moduleFactory, oldConfigBeanInfo, dependencyResolver,
+ oldConfigBeanInfo.isDefaultBean());
}
@Override
// find factory
ModuleFactory moduleFactory = factoriesHolder.findByModuleName(factoryName);
DependencyResolver dependencyResolver = dependencyResolverManager.getOrCreate(moduleIdentifier);
- Module module = moduleFactory.createModule(instanceName, dependencyResolver, bundleContext);
+ Module module = moduleFactory.createModule(instanceName, dependencyResolver,
+ getModuleFactoryBundleContext(moduleFactory.getImplementationName()));
+ boolean defaultBean = false;
return putConfigBeanToJMXAndInternalMaps(moduleIdentifier, module,
- moduleFactory, null, dependencyResolver);
+ moduleFactory, null, dependencyResolver, defaultBean);
}
private synchronized ObjectName putConfigBeanToJMXAndInternalMaps(
ModuleIdentifier moduleIdentifier, Module module,
ModuleFactory moduleFactory,
- @Nullable ModuleInternalInfo maybeOldConfigBeanInfo, DependencyResolver dependencyResolver)
+ @Nullable ModuleInternalInfo maybeOldConfigBeanInfo, DependencyResolver dependencyResolver, boolean isDefaultBean)
throws InstanceAlreadyExistsException {
logger.debug("Adding module {} to transaction {}", moduleIdentifier, this);
.registerMBean(writableDynamicWrapper, writableON);
ModuleInternalTransactionalInfo moduleInternalTransactionalInfo = new ModuleInternalTransactionalInfo(
moduleIdentifier, module, moduleFactory,
- maybeOldConfigBeanInfo, transactionModuleJMXRegistration);
+ maybeOldConfigBeanInfo, transactionModuleJMXRegistration, isDefaultBean);
dependencyResolverManager.put(moduleInternalTransactionalInfo);
return writableON;
}
@Override
- public void destroyModule(ObjectName objectName)
+ public synchronized void destroyModule(ObjectName objectName)
throws InstanceNotFoundException {
String foundTransactionName = ObjectNameUtil
.getTransactionName(objectName);
destroyModule(moduleIdentifier);
}
- private void destroyModule(ModuleIdentifier moduleIdentifier) {
+ private synchronized void destroyModule(ModuleIdentifier moduleIdentifier) {
logger.debug("Destroying module {} in transaction {}", moduleIdentifier, this);
transactionStatus.checkNotAborted();
+
+ if (blankTransaction == false) {
+ ModuleInternalTransactionalInfo found =
+ dependencyResolverManager.findModuleInternalTransactionalInfo(moduleIdentifier);
+ if (found.isDefaultBean()) {
+ logger.warn("Warning: removing default bean. This will be forbidden in next version of config-subsystem");
+ }
+ }
ModuleInternalTransactionalInfo removedTInfo = dependencyResolverManager.destroyModule(moduleIdentifier);
// remove from jmx
removedTInfo.getTransactionModuleJMXRegistration().close();
@Override
public List<ModuleFactory> getCurrentlyRegisteredFactories() {
- return currentlyRegisteredFactories;
+ return new ArrayList<>(factoriesHolder.getModuleFactories());
}
@Override
public TransactionIdentifier getIdentifier() {
return transactionIdentifier;
}
+
+ @Override
+ public BundleContext getModuleFactoryBundleContext(String factoryName) {
+ Map.Entry<ModuleFactory, BundleContext> factoryBundleContextEntry = this.currentlyRegisteredFactories.get(factoryName);
+ if (factoryBundleContextEntry == null || factoryBundleContextEntry.getValue() == null) {
+ throw new NullPointerException("Bundle context of " + factoryName + " ModuleFactory not found.");
+ }
+ return factoryBundleContextEntry.getValue();
+ }
}