private void processCapabilityProviders(List<ManifestElement> manifestElementList) { manifestElementList .stream() .filter( manifestElement -> CapabilityProvider.class.getName().equals(getObjectClassName(manifestElement))) .map( manifestElement -> { // Processing CapabilityProvider OSGi service String providedCapabilityName = getManifestElementAttribute(CAPABILITY_NAME, manifestElement, false); if (logger.isDebugEnabled()) { logger.debug( "Creating a CapabilityProviderCapability from manifest element in " + "bundle({}:{}), with CapabilityName - {}. ", manifestElement.getBundle().getSymbolicName(), manifestElement.getBundle().getVersion(), providedCapabilityName); } return new CapabilityProviderCapability( getObjectClassName(manifestElement), Capability.CapabilityType.OSGi_SERVICE, providedCapabilityName, manifestElement.getBundle()); }) .forEach(capability -> startupComponentManager.addExpectedCapabilityProvider(capability)); }
/** * Process Provide-Capability headers and populate a counter which keep all the expected service * counts. Register timers to track the service availability as well as pending service * registrations. * * <p>If there are no RequireCapabilityListener instances then this method returns. * * @param bundleContext OSGi bundle context of the Carbon.core bundle * @throws Exception if the service component activation fails */ @Activate public void start(BundleContext bundleContext) throws Exception { try { logger.debug("Initialize - Startup Order Resolver."); // 1) Process OSGi manifest headers to calculate the expected list required capabilities. processManifestHeaders(Arrays.asList(bundleContext.getBundles()), supportedManifestHeaders); // 2) Check for any startup components with pending required capabilities. if (startupComponentManager.getPendingComponents().size() == 0) { // There are no registered RequiredCapabilityListener // Clear all the populated maps. startupComponentManager = null; osgiServiceTracker = null; return; } // 3) Register capability trackers to get notified when required capabilities are available. startCapabilityTrackers(); // 4) Schedule a time task to check for startup components with zero pending required // capabilities. scheduleCapabilityListenerTimer(); // 5) Start a timer to track pending capabilities, pending CapabilityProvider services, // pending RequiredCapabilityLister services. schedulePendingCapabilityTimerTask(); } catch (Throwable e) { logger.error("Error occurred in Startup Order Resolver.", e); } }
/** * Process all the Startup-Component manifest header elements. Creates {@code StartupComponent} * instances for each and every ManifestElement. * * @param manifestElementList a list of {@code ManifestElement} whose header name is * Startup-Component. */ private void processStartupComponents(List<ManifestElement> manifestElementList) { // Create StartupComponents from the manifest elements. List<StartupComponent> startupComponentList = manifestElementList .stream() .map(StartupOrderResolverUtils::getStartupComponentBean) .collect(Collectors.toList()); startupComponentManager.addComponents(startupComponentList); }
private void notifySatisfiableComponents() { startupComponentManager .getSatisfiableComponents() .forEach( startupComponent -> { String componentName = startupComponent.getName(); synchronized (componentName.intern()) { startupComponentManager.removeSatisfiedComponent(startupComponent); RequiredCapabilityListener capabilityListener = startupComponent.getListener(); if (logger.isDebugEnabled()) { logger.debug( "Notifying RequiredCapabilityListener of component {} from bundle({}:{}) " + "since all the required capabilities are available", componentName, startupComponent.getBundle().getSymbolicName(), startupComponent.getBundle().getVersion()); } capabilityListener.onAllRequiredCapabilitiesAvailable(); } }); }
/** * Process all the Provide-Capability Manifest header elements to get a list of required * Capabilities. * * <p>At the moment this methods process manifest elements with the namespace osgi.service. * * @param manifestElementList partitioned manifest elements by the header name. */ private void processOSGiServiceCapabilities(List<ManifestElement> manifestElementList) { // Handle CapabilityProvider OSGi services processCapabilityProviders(manifestElementList); // Handle other OSGi service capabilities manifestElementList .stream() .filter( manifestElement -> !CapabilityProvider.class.getName().equals(getObjectClassName(manifestElement)) && !RequiredCapabilityListener.class .getName() .equals(getObjectClassName(manifestElement))) // Creating a Capability from the manifestElement .flatMap( manifestElement -> { String capabilityName = getObjectClassName(manifestElement); String serviceCountStr = getManifestElementAttribute(SERVICE_COUNT, manifestElement, false); int serviceCount = 1; if (serviceCountStr != null) { try { serviceCount = Integer.parseInt(serviceCountStr.trim()); } catch (NumberFormatException e) { throw new StartOrderResolverException( "Invalid value for serviceCount manifest attribute " + "in bundle(" + manifestElement.getBundle().getSymbolicName() + ":" + manifestElement.getBundle().getVersion() + ")", e); } } // Create specifed number of OSGi service components and adding them to a list. List<OSGiServiceCapability> osgiServiceCapabilityList = new ArrayList<>(serviceCount); IntStream.range(0, serviceCount) .forEach( count -> { OSGiServiceCapability osgiServiceCapability = new OSGiServiceCapability( capabilityName, Capability.CapabilityType.OSGi_SERVICE, manifestElement.getBundle()); // Check whether a dependent-component-key or dependent-component-name // property is specified. String dependentComponentName = getManifestElementAttribute( DEPENDENT_COMPONENT_NAME, manifestElement, false); if (dependentComponentName != null && !dependentComponentName.equals("")) { osgiServiceCapability.setDependentComponentName( dependentComponentName.trim()); } osgiServiceCapabilityList.add(osgiServiceCapability); }); return osgiServiceCapabilityList.stream(); }) .forEach( capability -> { if (capability.getDependentComponentName() != null) { startupComponentManager.addRequiredOSGiServiceCapabilityToComponent( capability.getDependentComponentName(), capability.getName()); } startupComponentManager.addExpectedRequiredCapability(capability); }); }