Skip to content

Commit

Permalink
Merge pull request #174 from eclipse-passage/561436
Browse files Browse the repository at this point in the history
561436 - API revision: requirements resolution: equinox services
  • Loading branch information
eparovyshnaya authored Mar 26, 2020
2 parents b603b76 + 26cd4f3 commit 7ff2d4b
Show file tree
Hide file tree
Showing 10 changed files with 195 additions and 119 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,60 +17,74 @@
/**
* Severity of a licensing requirement and, accordingly, restriction verdict.
*/
public interface RestrictionLevel {
public abstract class RestrictionLevel {

String META = "licensing.restriction.level"; //$NON-NLS-1$
// FIXME: to be used further
// private final String meta = "licensing.restriction.level"; //$NON-NLS-1$
private final String identifier;

String identifier();
protected RestrictionLevel(String identifier) {
Objects.requireNonNull(identifier, "Identifier is mandatory for restriction level"); //$NON-NLS-1$
this.identifier = identifier.trim().toLowerCase();
}

final class Info implements RestrictionLevel {
public final String identifier() {
return identifier;
}

@Override
public String identifier() {
return "info"; //$NON-NLS-1$
@Override
public final int hashCode() {
return Objects.hash(identifier());
}

@Override
public final boolean equals(Object object) {
if (!RestrictionLevel.class.isInstance(object)) {
return false;
}
return identifier.equals(((RestrictionLevel) object).identifier);
}

@Override
public final String toString() {
return identifier;
}

final class Warning implements RestrictionLevel {
public static final class Info extends RestrictionLevel {

@Override
public String identifier() {
return "warn"; //$NON-NLS-1$
public Info() {
super("info"); //$NON-NLS-1$
}

}

final class Error implements RestrictionLevel {
public static final class Warning extends RestrictionLevel {

@Override
public String identifier() {
return "error"; //$NON-NLS-1$
public Warning() {
super("warn"); //$NON-NLS-1$
}

}

final class Fatal implements RestrictionLevel {
public final static class Error extends RestrictionLevel {

@Override
public String identifier() {
return "fatal"; //$NON-NLS-1$
public Error() {
super("error"); //$NON-NLS-1$
}

}

final class Of implements RestrictionLevel {

private final String name;
public static final class Fatal extends RestrictionLevel {

public Of(String name) {
Objects.requireNonNull(name, "Name is mandatory for restriction level"); //$NON-NLS-1$
this.name = name.trim().toLowerCase();
public Fatal() {
super("fatal"); //$NON-NLS-1$
}

@Override
public String identifier() {
return name;
}

public static final class Of extends RestrictionLevel {

public Of(String identifier) {
super(identifier);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ public UnsatisfiableRequirement(String description, Object source) {
public Requirement get() {
Feature feature = new BaseFeature( //
Long.toHexString(System.currentTimeMillis()), //
"0.0.0", //$NON-NLS-1$
"0.0.0", //$NON-NLS-1$ // FIXME: rework on LicensingVersions elimination
description, //
"Passage License Management"); //$NON-NLS-1$
"Passage License Management"); //$NON-NLS-1$ // FIXME: i18n
return new BaseRequirement(feature, new RestrictionLevel.Error(), source);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public static Iterable<BundleRequirement> extractLicensingManagementRequirements
}

/**
* @deprecated Use {@linkplain LicensingFeaturesFromBundle}
* @deprecated Use {@linkplain LicensingFeatureCapabilitiesFromBundle}
*/
@Deprecated
public static Iterable<BundleCapability> extractLicensingFeatures(Bundle bundle) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ public class EquinoxMessages extends NLS {

public static String ComponentConfigurationResolver_error_invalid_bundle_context;
public static String ComponentConfigurationResolver_error_invalid_component_rt;
public static String BundleCapabilityResolver_error;
public static String BundleCapabilityResolver_error_bundle_context;
public static String BundleRequirements_error_bundle_context;

public static String BundleRequirements_no_context;
public static String EquinoxRestrictionExecutorRegistry_error_name;
public static String EquinoxRestrictionExecutorRegistry_error_title;
public static String EquinoxRestrictionExecutorRegistry_fatal_name;
Expand All @@ -38,6 +39,10 @@ public class EquinoxMessages extends NLS {
public static String EquinoxRestrictionExecutorRegistry_info_title;
public static String EquinoxRestrictionExecutorRegistry_warning_name;
public static String EquinoxRestrictionExecutorRegistry_warning_title;

public static String RequirementsFromCapability_no_attributes;

public static String RequirementsFromCapability_no_feature_id;
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, EquinoxMessages.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ EquinoxRestrictions_title=Issues with licensing

ComponentConfigurationResolver_error_invalid_bundle_context=Unable to extract configuration requirements: invalid BundleContext
ComponentConfigurationResolver_error_invalid_component_rt=Unable to extract configuration requirements: invalid ServiceComponentRuntime
BundleCapabilityResolver_error=Unable to extract configuration requirements: %s
BundleCapabilityResolver_error_bundle_context=Unable to extract configuration requirements: invalid BundleContext
BundleRequirements_no_context=Bundle context for {1} OSGi-component
BundleRequirements_error_bundle_context=Unable to extract configuration requirements: invalid BundleContext
EquinoxRestrictionExecutorRegistry_error_name=Error
EquinoxRestrictionExecutorRegistry_error_title=Interrupt the execution for the restricted functionality with error, but allow to use other scenarios
EquinoxRestrictionExecutorRegistry_fatal_name=Fatal
Expand All @@ -30,3 +30,5 @@ EquinoxRestrictionExecutorRegistry_info_name=Info
EquinoxRestrictionExecutorRegistry_info_title=Inform about functionality restriction without pausing the execution flow
EquinoxRestrictionExecutorRegistry_warning_name=Warning
EquinoxRestrictionExecutorRegistry_warning_title=Pause the execution flow with warning, but allow to proceed without functionality blocking
RequirementsFromCapability_no_attributes=Attributes for capability {1} in bundle {2} is required
RequirementsFromCapability_no_feature_id=Configuration of a feature identifier in capability {1} of bundle {2} is required
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public Iterable<LicensingRequirement> resolveLicensingRequirements(LicensingConf
String nameLicensing = LICENSING_FEATURE_NAME_DEFAULT;
String providerLicensing = LICENSING_FEATURE_PROVIDER_DEFAULT;
if (bundleContext == null) {
logger.severe(EquinoxMessages.BundleCapabilityResolver_error_bundle_context);
logger.severe(EquinoxMessages.BundleRequirements_error_bundle_context);
return LicensingRequirements.createErrorIterable(LicensingNamespaces.CAPABILITY_LICENSING_MANAGEMENT,
LicensingVersions.VERSION_DEFAULT, nameLicensing, providerLicensing, configuration);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Optional;
import java.util.stream.Collectors;

import org.eclipse.osgi.util.NLS;
import org.eclipse.passage.lic.api.LicensingConfiguration;
import org.eclipse.passage.lic.internal.api.registry.StringServiceId;
import org.eclipse.passage.lic.internal.api.requirements.Requirement;
Expand All @@ -32,21 +33,28 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* <p>
* {@linkplain ResolvedRequirements} service implementation which search for
* {@linkplain Requirement} declarations in an OSGi-bundles meta information:
* among <i>Provide-Capability</i> declarations.
* </p>
*/
@SuppressWarnings("restriction")
@Component
public class BundleRequirements implements ResolvedRequirements {
public final class BundleRequirements implements ResolvedRequirements {

private final Logger logger = LoggerFactory.getLogger(BundleRequirements.class);
private BundleContext context;
private Optional<BundleContext> context;

@Activate
public void activate(BundleContext bundle) {
this.context = bundle;
this.context = Optional.ofNullable(bundle);
}

@Deactivate
public void deactivate() {
this.context = null;
this.context = Optional.empty();
}

@Override
Expand All @@ -63,24 +71,22 @@ public Collection<Requirement> all(LicensingConfiguration configuration) {
}

private boolean sabotage() {
return context == null;
return !context.isPresent();
}

private Collection<Requirement> unsafisifiable() {
logger.error(EquinoxMessages.BundleCapabilityResolver_error_bundle_context);
logger.error(EquinoxMessages.BundleRequirements_error_bundle_context);
return Collections.singleton(//
new UnsatisfiableRequirement(//
"Bundle context for " + getClass().getName() + " OSGi-component", //$NON-NLS-1$ //$NON-NLS-2$
NLS.bind(EquinoxMessages.BundleRequirements_no_context, getClass().getName()), //
getClass()//
).get());
}

private Collection<Requirement> resolve() {
return Arrays.stream(context.getBundles())//
return Arrays.stream(context.get().getBundles())//
.map(RequirementsFromBundle::new)//
.map(RequirementsFromBundle::get) //
.filter(Optional::isPresent) //
.map(Optional<List<Requirement>>::get) //
.flatMap(List::stream) //
.collect(Collectors.toList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,22 @@
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleWiring;

/**
* <p>
* Covers special <i>licensing</i> {@code capability} reading from the given
* {@code Bundle}'s manifest, where the bundle developers place inion for the
* feature under licensing.
* </p>
* <p>
* Never supplies empty {@code Optional}: it always contain either actual list
* of {@code capabilities} or empty list, if there is none declared in the given
* {@code bundle}.
* </p>
*/
@SuppressWarnings("restriction")
final class LicensingFeaturesFromBundle extends BaseNamedData<List<BundleCapability>> {
final class LicensingFeatureCapabilitiesFromBundle extends BaseNamedData<List<BundleCapability>> {

protected LicensingFeaturesFromBundle(Bundle bundle) {
protected LicensingFeatureCapabilitiesFromBundle(Bundle bundle) {
super(key -> //
Optional.ofNullable(bundle.adapt(BundleWiring.class))//
.map(wiring -> wiring.getCapabilities(key))//
Expand All @@ -36,9 +48,4 @@ public String key() {
return "licensing.feature"; //$NON-NLS-1$
}

@Override
public String printed(List<BundleCapability> value) {
throw new UnsupportedOperationException();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,85 +12,28 @@
*******************************************************************************/
package org.eclipse.passage.lic.internal.equinox.requirements;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import org.eclipse.passage.lic.base.LicensingVersions;
import org.eclipse.passage.lic.internal.api.requirements.Requirement;
import org.eclipse.passage.lic.internal.api.restrictions.RestrictionLevel;
import org.eclipse.passage.lic.internal.base.requirements.BaseFeature;
import org.eclipse.passage.lic.internal.base.requirements.BaseRequirement;
import org.eclipse.passage.lic.internal.base.requirements.UnsatisfiableRequirement;
import org.eclipse.passage.lic.internal.base.restrictions.DefaultRestrictionLevel;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
import org.osgi.framework.wiring.BundleCapability;

@SuppressWarnings("restriction")
final class RequirementsFromBundle implements Supplier<Optional<List<Requirement>>> {
final class RequirementsFromBundle implements Supplier<List<Requirement>> {

private final Bundle bundle;

public RequirementsFromBundle(Bundle bundle) {
this.bundle = bundle;
}

@Override
public Optional<List<Requirement>> get() {
LicensingFeaturesFromBundle licensingFeaturesFromBundle = new LicensingFeaturesFromBundle(bundle);
Optional<List<BundleCapability>> capabilities = licensingFeaturesFromBundle.get();
if (capabilities.isPresent()) {
return Optional.empty();
}
String name = bundleName();
String vendor = bundleVendor();
List<Requirement> results = new ArrayList<>();
for (BundleCapability capability : capabilities.get()) {
Map<String, Object> attributes = capability.getAttributes();
if (attributes == null) {
results.add(new UnsatisfiableRequirement(//
"Attributes for " + licensingFeaturesFromBundle.key() + //$NON-NLS-1$
" capability of " + name //$NON-NLS-1$
+ " bundle", //$NON-NLS-1$
bundle).get());
continue;
}
CapabilityLicFeatureId capabilityLicFeatureId = new CapabilityLicFeatureId(attributes);
Optional<String> feature = capabilityLicFeatureId.get();
if (!feature.isPresent()) {
results.add(new UnsatisfiableRequirement(//
licensingFeaturesFromBundle.key() + " capability attribute " + capabilityLicFeatureId.key() //$NON-NLS-1$
+ " for " + name //$NON-NLS-1$
+ " bundle", //$NON-NLS-1$
bundle).get());
continue;
}
String version = new CapabilityLicFeatureVersion(attributes).get()//
.map(LicensingVersions::toVersionValue)//
.orElse(LicensingVersions.VERSION_DEFAULT);

String featureName = new CapabilityLicFeatureName(attributes).get().orElse(feature.get());
String provider = new CapabilityLicFeatureProvider(attributes).get().orElse(vendor);
RestrictionLevel level = new CapabilityLicFeatureLevel(attributes).get()//
.<RestrictionLevel>map(RestrictionLevel.Of::new) //
.orElseGet(new DefaultRestrictionLevel());

results.add(new BaseRequirement(//
new BaseFeature(feature.get(), version, featureName, provider), //
level, //
capability.getResource()));
}
return Optional.of(results);
}

private String bundleName() {
return bundle.getHeaders().get(Constants.BUNDLE_NAME);
}

private String bundleVendor() {
return bundle.getHeaders().get(Constants.BUNDLE_VENDOR);
public List<Requirement> get() {
return new LicensingFeatureCapabilitiesFromBundle(bundle).get().get().stream()//
.map(capability -> new RequirementsFromCapability(bundle, capability))//
.map(RequirementsFromCapability::get) //
.collect(Collectors.toList());
}

}
Loading

0 comments on commit 7ff2d4b

Please sign in to comment.