use of org.opendaylight.controller.config.spi.ModuleFactory in project controller by opendaylight.
the class ConfigManagerActivator method start.
@Override
public void start(final BundleContext context) {
LOG.info("Config manager starting...");
try {
// the inner strategy is backed by thread context cl?
final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();
final BindingContextProvider bindingContextProvider = new BindingContextProvider();
final RefreshingSCPModuleInfoRegistry moduleInfoRegistryWrapper = new RefreshingSCPModuleInfoRegistry(moduleInfoBackedContext, moduleInfoBackedContext, moduleInfoBackedContext, moduleInfoBackedContext, bindingContextProvider, context);
final ModuleInfoBundleTracker moduleInfoBundleTracker = new ModuleInfoBundleTracker(moduleInfoRegistryWrapper);
// start config registry
final BundleContextBackedModuleFactoriesResolver bundleContextBackedModuleFactoriesResolver = new BundleContextBackedModuleFactoriesResolver(context);
this.configRegistry = new ConfigRegistryImpl(bundleContextBackedModuleFactoriesResolver, this.configMBeanServer, bindingContextProvider);
// track bundles containing factories
final BlankTransactionServiceTracker blankTransactionServiceTracker = new BlankTransactionServiceTracker(this.configRegistry);
final ModuleFactoryBundleTracker moduleFactoryTracker = new ModuleFactoryBundleTracker(blankTransactionServiceTracker);
BundleTracker<Collection<ObjectRegistration<YangModuleInfo>>> moduleInfoResolvedBundleTracker = new BundleTracker<>(context, Bundle.RESOLVED | Bundle.STARTING | Bundle.STOPPING | Bundle.ACTIVE, moduleInfoBundleTracker);
ExtensibleBundleTracker<?> moduleFactoryBundleTracker = new ExtensibleBundleTracker<>(context, moduleFactoryTracker);
moduleInfoBundleTracker.open(moduleInfoResolvedBundleTracker);
// start extensible tracker
moduleFactoryBundleTracker.open();
// Wrap config registry with JMX notification publishing adapter
final JMXNotifierConfigRegistry notifyingConfigRegistry = new JMXNotifierConfigRegistry(this.configRegistry, this.configMBeanServer);
// register config registry to OSGi
final AutoCloseable clsReg = OsgiRegistrationUtil.registerService(context, moduleInfoBackedContext, ClassLoadingStrategy.class);
final AutoCloseable configRegReg = OsgiRegistrationUtil.registerService(context, notifyingConfigRegistry, ConfigRegistry.class);
// register config registry to jmx
final ConfigRegistryJMXRegistrator configRegistryJMXRegistrator = new ConfigRegistryJMXRegistrator(this.configMBeanServer);
try {
configRegistryJMXRegistrator.registerToJMXNoNotifications(this.configRegistry);
} catch (final InstanceAlreadyExistsException e) {
configRegistryJMXRegistrator.close();
throw new IllegalStateException("Config Registry was already registered to JMX", e);
}
// register config registry to jmx
final ConfigRegistryJMXRegistrator configRegistryJMXRegistratorWithNotifications = new ConfigRegistryJMXRegistrator(this.configMBeanServer);
try {
configRegistryJMXRegistrator.registerToJMX(notifyingConfigRegistry);
} catch (final InstanceAlreadyExistsException e) {
configRegistryJMXRegistrator.close();
configRegistryJMXRegistratorWithNotifications.close();
throw new IllegalStateException("Config Registry was already registered to JMX", e);
}
// TODO wire directly via moduleInfoBundleTracker
final ServiceTracker<ModuleFactory, Object> serviceTracker = new ServiceTracker<>(context, ModuleFactory.class, blankTransactionServiceTracker);
serviceTracker.open();
final AutoCloseable configMgrReg = OsgiRegistrationUtil.registerService(context, this, ConfigSystemService.class);
final List<AutoCloseable> list = Arrays.asList(bindingContextProvider, clsReg, OsgiRegistrationUtil.wrap(moduleFactoryBundleTracker), moduleInfoBundleTracker, configRegReg, configRegistryJMXRegistrator, configRegistryJMXRegistratorWithNotifications, OsgiRegistrationUtil.wrap(serviceTracker), moduleInfoRegistryWrapper, notifyingConfigRegistry, configMgrReg);
this.autoCloseable = OsgiRegistrationUtil.aggregate(list);
context.addBundleListener(this);
} catch (final IllegalStateException e) {
LOG.error("Error starting config manager", e);
}
LOG.info("Config manager start complete");
}
use of org.opendaylight.controller.config.spi.ModuleFactory in project controller by opendaylight.
the class JMXGenerator method generateSources.
@Override
public Collection<File> generateSources(final SchemaContext context, final File outputBaseDir, final Set<Module> currentModules, final Function<Module, Optional<String>> moduleResourcePathResolver) {
Preconditions.checkArgument(context != null, "Null context received");
Preconditions.checkArgument(outputBaseDir != null, "Null outputBaseDir received");
Preconditions.checkArgument(this.namespaceToPackageMapping != null && !this.namespaceToPackageMapping.isEmpty(), "No namespace to package mapping provided in additionalConfiguration");
final PackageTranslator packageTranslator = new PackageTranslator(this.namespaceToPackageMapping);
if (!outputBaseDir.exists()) {
outputBaseDir.mkdirs();
}
final GeneratedFilesTracker generatedFiles = new GeneratedFilesTracker();
// create SIE structure qNamesToSIEs
final Map<QName, ServiceInterfaceEntry> qNamesToSIEs = new HashMap<>();
final Map<IdentitySchemaNode, ServiceInterfaceEntry> knownSEITracker = new HashMap<>();
for (final Module module : context.getModules()) {
final String packageName = packageTranslator.getPackageName(module);
final Map<QName, ServiceInterfaceEntry> namesToSIEntries = ServiceInterfaceEntry.create(module, packageName, knownSEITracker);
for (final Entry<QName, ServiceInterfaceEntry> sieEntry : namesToSIEntries.entrySet()) {
// merge value into qNamesToSIEs
if (qNamesToSIEs.put(sieEntry.getKey(), sieEntry.getValue()) != null) {
throw new IllegalStateException("Cannot add two SIE with same qname " + sieEntry.getValue());
}
}
if (currentModules.contains(module)) {
// write this sie to disk
for (final ServiceInterfaceEntry sie : namesToSIEntries.values()) {
try {
generatedFiles.addFile(this.codeWriter.writeSie(sie, outputBaseDir));
} catch (final Exception e) {
throw new RuntimeException("Error occurred during SIE source generate phase", e);
}
}
}
}
final File mainBaseDir = concatFolders(this.projectBaseDir, "src", "main", "java");
Preconditions.checkNotNull(this.resourceBaseDir, "resource base dir attribute was null");
final StringBuilder fullyQualifiedNamesOfFactories = new StringBuilder();
// create MBEs
for (final Module module : currentModules) {
final String packageName = packageTranslator.getPackageName(module);
final Map<String, ModuleMXBeanEntry> /* MB identity local name */
namesToMBEs = ModuleMXBeanEntry.create(module, qNamesToSIEs, context, new TypeProviderWrapper(new TypeProviderImpl(context)), packageName);
for (final Entry<String, ModuleMXBeanEntry> mbeEntry : namesToMBEs.entrySet()) {
final ModuleMXBeanEntry mbe = mbeEntry.getValue();
try {
final List<File> files1 = this.codeWriter.writeMbe(mbe, outputBaseDir, mainBaseDir);
generatedFiles.addFile(files1);
} catch (final Exception e) {
throw new RuntimeException("Error occurred during MBE source generate phase", e);
}
fullyQualifiedNamesOfFactories.append(mbe.getFullyQualifiedName(mbe.getStubFactoryName()));
fullyQualifiedNamesOfFactories.append("\n");
}
}
// create ModuleFactory file if needed
if (fullyQualifiedNamesOfFactories.length() > 0 && this.generateModuleFactoryFile) {
final File serviceLoaderFile = JMXGenerator.concatFolders(this.resourceBaseDir, "META-INF", "services", ModuleFactory.class.getName());
// if this file does not exist, create empty file
serviceLoaderFile.getParentFile().mkdirs();
try {
serviceLoaderFile.createNewFile();
Files.asCharSink(serviceLoaderFile, StandardCharsets.UTF_8).write(fullyQualifiedNamesOfFactories.toString());
} catch (final IOException e) {
final String message = "Cannot write to " + serviceLoaderFile;
LOG.error(message, e);
throw new RuntimeException(message, e);
}
}
return generatedFiles.getFiles();
}
use of org.opendaylight.controller.config.spi.ModuleFactory in project controller by opendaylight.
the class ConfigTransactionControllerImpl method processDefaultBeans.
private synchronized void processDefaultBeans(final List<ModuleFactory> lastListOfFactories) {
transactionStatus.checkNotCommitStarted();
transactionStatus.checkNotAborted();
Set<ModuleFactory> oldSet = new HashSet<>(lastListOfFactories);
Set<ModuleFactory> newSet = new HashSet<>(factoriesHolder.getModuleFactories());
List<ModuleFactory> toBeAdded = new ArrayList<>();
List<ModuleFactory> toBeRemoved = new ArrayList<>();
for (ModuleFactory moduleFactory : factoriesHolder.getModuleFactories()) {
if (!oldSet.contains(moduleFactory)) {
toBeAdded.add(moduleFactory);
}
}
for (ModuleFactory moduleFactory : lastListOfFactories) {
if (!newSet.contains(moduleFactory)) {
toBeRemoved.add(moduleFactory);
}
}
// add default modules
for (ModuleFactory moduleFactory : toBeAdded) {
BundleContext bundleContext = getModuleFactoryBundleContext(moduleFactory.getImplementationName());
Set<? extends Module> defaultModules = moduleFactory.getDefaultModules(dependencyResolverManager, bundleContext);
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());
final ObjectName objectName;
try {
boolean defaultBean = true;
objectName = putConfigBeanToJMXAndInternalMaps(module.getIdentifier(), module, moduleFactory, null, dependencyResolver, defaultBean, bundleContext);
} catch (final InstanceAlreadyExistsException e) {
throw new IllegalStateException(e);
}
// register default module as every possible service
final Set<ServiceInterfaceAnnotation> serviceInterfaceAnnotations = InterfacesHelper.getServiceInterfaceAnnotations(moduleFactory);
for (String qname : InterfacesHelper.getQNames(serviceInterfaceAnnotations)) {
try {
saveServiceReference(qname, module.getIdentifier().getInstanceName(), objectName);
} catch (final InstanceNotFoundException e) {
throw new IllegalStateException("Unable to register default module instance " + module + " as a service of " + qname, e);
}
}
}
}
// remove modules belonging to removed factories
for (ModuleFactory removedFactory : toBeRemoved) {
List<ModuleIdentifier> modulesOfRemovedFactory = dependencyResolverManager.findAllByFactory(removedFactory);
for (ModuleIdentifier name : modulesOfRemovedFactory) {
// remove service refs
final ModuleFactory moduleFactory = dependencyResolverManager.findModuleInternalTransactionalInfo(name).getModuleFactory();
final Set<ServiceInterfaceAnnotation> serviceInterfaceAnnotations = InterfacesHelper.getServiceInterfaceAnnotations(moduleFactory);
for (String qname : InterfacesHelper.getQNames(serviceInterfaceAnnotations)) {
try {
removeServiceReference(qname, name.getInstanceName());
} catch (final InstanceNotFoundException e) {
throw new IllegalStateException("Unable to UNregister default module instance " + name + " as a service of " + qname, e);
}
}
// close module
destroyModule(name);
}
}
}
use of org.opendaylight.controller.config.spi.ModuleFactory in project controller by opendaylight.
the class DependencyResolverImpl method validateDependency.
/**
* {@inheritDoc}
*/
// TODO: check for cycles
@Override
public void validateDependency(final Class<? extends AbstractServiceInterface> expectedServiceInterface, final ObjectName dependentReadOnlyON, final JmxAttribute jmxAttribute) {
this.transactionStatus.checkNotCommitted();
if (expectedServiceInterface == null) {
throw new NullPointerException("Parameter 'expectedServiceInterface' is null");
}
if (jmxAttribute == null) {
throw new NullPointerException("Parameter 'jmxAttribute' is null");
}
JmxAttributeValidationException.checkNotNull(dependentReadOnlyON, "is null, expected dependency implementing " + expectedServiceInterface, jmxAttribute);
// check that objectName belongs to this transaction - this should be
// stripped
// in DynamicWritableWrapper
final boolean hasTransaction = ObjectNameUtil.getTransactionName(dependentReadOnlyON) != null;
JmxAttributeValidationException.checkCondition(!hasTransaction, String.format("ObjectName should not contain " + "transaction name. %s set to %s. ", jmxAttribute, dependentReadOnlyON), jmxAttribute);
final ObjectName newDependentReadOnlyON = translateServiceRefIfPossible(dependentReadOnlyON);
final ModuleIdentifier moduleIdentifier = ObjectNameUtil.fromON(newDependentReadOnlyON, ObjectNameUtil.TYPE_MODULE);
final ModuleFactory foundFactory = this.modulesHolder.findModuleFactory(moduleIdentifier, jmxAttribute);
final boolean implementsSI = foundFactory.isModuleImplementingServiceInterface(expectedServiceInterface);
if (!implementsSI) {
final String message = String.format("Found module factory does not expose expected service interface. " + "Module name is %s : %s, expected service interface %s, dependent module ON %s , " + "attribute %s", foundFactory.getImplementationName(), foundFactory, expectedServiceInterface, newDependentReadOnlyON, jmxAttribute);
throw new JmxAttributeValidationException(message, jmxAttribute);
}
synchronized (this) {
this.dependencies.add(moduleIdentifier);
}
}
use of org.opendaylight.controller.config.spi.ModuleFactory in project controller by opendaylight.
the class BundleContextBackedModuleFactoriesResolver method getAllFactories.
@Override
public Map<String, Map.Entry<ModuleFactory, BundleContext>> getAllFactories() {
Collection<ServiceReference<ModuleFactory>> serviceReferences;
try {
serviceReferences = bundleContext.getServiceReferences(ModuleFactory.class, null);
} catch (final InvalidSyntaxException e) {
throw new IllegalStateException(e);
}
Map<String, Map.Entry<ModuleFactory, BundleContext>> result = new HashMap<>(serviceReferences.size());
for (ServiceReference<ModuleFactory> serviceReference : serviceReferences) {
ModuleFactory factory = bundleContext.getService(serviceReference);
// ServiceFactory threw an exception.
if (factory == null) {
throw new NullPointerException("ServiceReference of class" + serviceReference.getClass() + "not found.");
}
String moduleName = factory.getImplementationName();
if (moduleName == null || moduleName.isEmpty()) {
throw new IllegalStateException("Invalid implementation name for " + factory);
}
if (serviceReference.getBundle() == null || serviceReference.getBundle().getBundleContext() == null) {
throw new NullPointerException("Bundle context of " + factory + " ModuleFactory not found.");
}
LOG.debug("Reading factory {} {}", moduleName, factory);
Map.Entry<ModuleFactory, BundleContext> conflicting = result.get(moduleName);
if (conflicting != null) {
String error = String.format("Module name is not unique. Found two conflicting factories with same name '%s': '%s' '%s'", moduleName, conflicting.getKey(), factory);
LOG.error(error);
throw new IllegalArgumentException(error);
}
result.put(moduleName, new AbstractMap.SimpleImmutableEntry<>(factory, serviceReference.getBundle().getBundleContext()));
}
return result;
}
Aggregations