Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug 575182 protect condition mining with Agreements consistency check #889

Merged
merged 1 commit into from
Aug 25, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions bundles/org.eclipse.passage.lic.base/.settings/.api_filters
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@
</message_arguments>
</filter>
</resource>
<resource path="src/org/eclipse/passage/lic/base/access/Restrictions.java" type="org.eclipse.passage.lic.base.access.Restrictions">
<filter id="643850349">
<message_arguments>
<message_argument value="AgreementAcceptanceService"/>
<message_argument value="Restrictions"/>
<message_argument value="Restrictions(LicensedProduct, Registry&lt;StringServiceId,PermissionsExaminationService&gt;, AgreementAcceptanceService, Collection&lt;Requirement&gt;, PermissionsAppliedLicenses)"/>
</message_arguments>
</filter>
</resource>
<resource path="src/org/eclipse/passage/lic/base/restrictions/BasePermissionsExaminationService.java" type="org.eclipse.passage.lic.base.restrictions.BasePermissionsExaminationService">
<filter id="643850349">
<message_arguments>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
Expand All @@ -23,11 +22,11 @@
import org.eclipse.passage.lic.api.Framework;
import org.eclipse.passage.lic.api.ServiceInvocationResult;
import org.eclipse.passage.lic.api.conditions.ConditionPack;
import org.eclipse.passage.lic.api.conditions.evaluation.Permission;
import org.eclipse.passage.lic.api.diagnostic.Diagnostic;
import org.eclipse.passage.lic.api.requirements.Requirement;
import org.eclipse.passage.lic.api.restrictions.ExaminationCertificate;
import org.eclipse.passage.lic.base.BaseServiceInvocationResult;
import org.eclipse.passage.lic.base.access.Permissions.AppliedLicenses;
import org.eclipse.passage.lic.base.diagnostic.BaseDiagnostic;
import org.eclipse.passage.lic.base.diagnostic.SumOfDiagnostics;

Expand Down Expand Up @@ -64,7 +63,7 @@ protected Optional<String> feature() {
}

private T examine(Supplier<ServiceInvocationResult<Collection<Requirement>>> requirements, //
Supplier<ServiceInvocationResult<Collection<Permission>>> permissions) {
Supplier<ServiceInvocationResult<AppliedLicenses>> permissions) {
ServiceInvocationResult<Collection<Requirement>> reqs = requirements.get();
if (failed(reqs)) {
return stop();
Expand All @@ -74,7 +73,7 @@ private T examine(Supplier<ServiceInvocationResult<Collection<Requirement>>> req
// we just want to avoid heavy operations below
return freeWayOut();
}
ServiceInvocationResult<Collection<Permission>> perms = permissions.get();
ServiceInvocationResult<AppliedLicenses> perms = permissions.get();
if (failed(perms)) {
return stop();
}
Expand Down Expand Up @@ -141,11 +140,10 @@ private ServiceInvocationResult<Collection<ConditionPack>> conditions() {
filter.conditional()).get());
}

private ServiceInvocationResult<Collection<Permission>> permissions() {
private ServiceInvocationResult<Permissions.AppliedLicenses> permissions() {
ServiceInvocationResult<Collection<ConditionPack>> conditions = conditions();
if (failed(conditions) || empty(conditions)) {
return new BaseServiceInvocationResult<Collection<Permission>>(conditions.diagnostic(),
Collections.emptyList());
return new BaseServiceInvocationResult<AppliedLicenses>(conditions.diagnostic(), new AppliedLicenses());
}
return scan(new Permissions(//
framework.accessCycleConfiguration().permissionEmitters().get(), //
Expand All @@ -154,9 +152,11 @@ private ServiceInvocationResult<Collection<Permission>> permissions() {
}

private ServiceInvocationResult<ExaminationCertificate> restrictions(Collection<Requirement> requirements,
Collection<Permission> permissions) {
AppliedLicenses permissions) {
return scan(new Restrictions(//
framework.product(), //
framework.accessCycleConfiguration().examinators().get(), //
framework.accessCycleConfiguration().acceptance(), //
requirements, //
permissions).get());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import org.eclipse.passage.lic.api.LicensedProduct;
import org.eclipse.passage.lic.api.ServiceInvocationResult;
import org.eclipse.passage.lic.api.agreements.GlobalAgreement;
import org.eclipse.passage.lic.api.conditions.ConditionPack;
import org.eclipse.passage.lic.api.conditions.evaluation.Emission;
import org.eclipse.passage.lic.api.conditions.evaluation.Permission;
Expand All @@ -29,13 +31,14 @@
import org.eclipse.passage.lic.api.registry.StringServiceId;
import org.eclipse.passage.lic.base.BaseServiceInvocationResult;
import org.eclipse.passage.lic.base.SumOfCollections;
import org.eclipse.passage.lic.base.access.Permissions.AppliedLicenses;

/**
* FIXME: Has public visibility only for testing.
*
* @since 2.1
*/
public final class Permissions implements Supplier<ServiceInvocationResult<Collection<Permission>>> {
public final class Permissions implements Supplier<ServiceInvocationResult<AppliedLicenses>> {

private final Registry<StringServiceId, PermissionEmittingService> registry;
private final Collection<ConditionPack> conditions;
Expand All @@ -49,7 +52,17 @@ public Permissions(Registry<StringServiceId, PermissionEmittingService> registry
}

@Override
public ServiceInvocationResult<Collection<Permission>> get() {
public ServiceInvocationResult<AppliedLicenses> get() {
BaseServiceInvocationResult<Collection<Permission>> permissions = permissions();
return new BaseServiceInvocationResult<>(//
permissions.diagnostic(), //
new AppliedLicenses(//
permissions.data().get(), //
agreements())//
);
}

private BaseServiceInvocationResult<Collection<Permission>> permissions() {
return registry.services().stream() //
.map(service -> service.emit(conditions, product))//
.reduce(new BaseServiceInvocationResult.Sum<>(new SumOfCollections<Emission>()))//
Expand All @@ -70,6 +83,13 @@ private Collection<Permission> allPermissions(Optional<Collection<Emission>> emi
new SumOfCollections<Permission>());
}

private Collection<GlobalAgreement> agreements() {
return conditions.stream()//
.map(ConditionPack::agreements)//
.flatMap(Collection::stream)//
.collect(Collectors.toList());
}

/**
* Here we do not need `ConditionPack` granularity, thus unfold each one to
* amass all the permissions we have.
Expand All @@ -85,4 +105,27 @@ public Collection<Permission> apply(Collection<Permission> sum, Emission emissio

}

public static final class AppliedLicenses {

private final Collection<Permission> permissions;
private final Collection<GlobalAgreement> agreements;

AppliedLicenses() {
this(Collections.emptyList(), Collections.emptyList());
}

AppliedLicenses(Collection<Permission> permissions, Collection<GlobalAgreement> agreements) {
this.permissions = permissions;
this.agreements = agreements;
}

Collection<Permission> permissions() {
return permissions;
}

Collection<GlobalAgreement> agreements() {
return agreements;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,33 @@
package org.eclipse.passage.lic.base.access;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import org.eclipse.passage.lic.api.LicensedProduct;
import org.eclipse.passage.lic.api.ServiceInvocationResult;
import org.eclipse.passage.lic.api.conditions.evaluation.Permission;
import org.eclipse.passage.lic.api.agreements.AgreementAcceptanceService;
import org.eclipse.passage.lic.api.agreements.AgreementState;
import org.eclipse.passage.lic.api.agreements.AgreementToAccept;
import org.eclipse.passage.lic.api.agreements.GlobalAgreement;
import org.eclipse.passage.lic.api.agreements.ResolvedAgreement;
import org.eclipse.passage.lic.api.diagnostic.Trouble;
import org.eclipse.passage.lic.api.registry.Registry;
import org.eclipse.passage.lic.api.registry.StringServiceId;
import org.eclipse.passage.lic.api.requirements.Requirement;
import org.eclipse.passage.lic.api.restrictions.ExaminationCertificate;
import org.eclipse.passage.lic.api.restrictions.PermissionsExaminationService;
import org.eclipse.passage.lic.api.restrictions.Restriction;
import org.eclipse.passage.lic.base.BaseServiceInvocationResult;
import org.eclipse.passage.lic.base.access.Permissions.AppliedLicenses;
import org.eclipse.passage.lic.base.agreements.AgreementAcceptanceDemand;
import org.eclipse.passage.lic.base.agreements.BaseAgreementToAccept;
import org.eclipse.passage.lic.base.agreements.MinedAgreement;
import org.eclipse.passage.lic.base.agreements.UnacceptedAgreementRestriction;
import org.eclipse.passage.lic.base.diagnostic.code.NoServicesOfType;
import org.eclipse.passage.lic.base.restrictions.BaseExaminationCertificate;
import org.eclipse.passage.lic.internal.base.i18n.AccessCycleMessages;

/**
Expand All @@ -33,12 +48,16 @@
public final class Restrictions implements Supplier<ServiceInvocationResult<ExaminationCertificate>> {

private final Registry<StringServiceId, PermissionsExaminationService> registry;
private final AgreementAcceptanceService acceptance;
private final Collection<Requirement> requirements;
private final Collection<Permission> permissions;
private final AppliedLicenses permissions;
private final LicensedProduct product;

public Restrictions(Registry<StringServiceId, PermissionsExaminationService> registry,
Collection<Requirement> requirements, Collection<Permission> permissions) {
public Restrictions(LicensedProduct product, Registry<StringServiceId, PermissionsExaminationService> registry,
AgreementAcceptanceService acceptance, Collection<Requirement> requirements, AppliedLicenses permissions) {
this.product = product;
this.registry = registry;
this.acceptance = acceptance;
this.requirements = requirements;
this.permissions = permissions;
}
Expand All @@ -52,11 +71,43 @@ public ServiceInvocationResult<ExaminationCertificate> get() {
AccessCycleMessages.getString("Restrictions.no_services"))); //$NON-NLS-1$
}
return new BaseServiceInvocationResult<ExaminationCertificate>(//
registry.services().stream()//
.map(service -> service.examine(requirements, permissions)) //
.reduce(new SumOfCertificates())//
.get() // guaranteed to exist as there is at least one service
new SumOfCertificates().apply(//
permissionBasedCertificate(), //
agreementsBasedCertificate())//
);
}

private ExaminationCertificate permissionBasedCertificate() {
return registry.services().stream()//
.map(service -> service.examine(requirements, permissions.permissions())) //
.reduce(new SumOfCertificates())//
.get(); // guaranteed to exist as there is at least one service
}

private ExaminationCertificate agreementsBasedCertificate() {
List<AgreementToAccept> agreements = permissions.agreements().stream()//
.map(this::agreementToAccept)//
.collect(Collectors.toList());
return new BaseExaminationCertificate(Collections.emptyMap(), restrictions(agreements), agreements);
}

private AgreementToAccept agreementToAccept(GlobalAgreement agreement) {
ResolvedAgreement definition = new MinedAgreement(agreement);
return new BaseAgreementToAccept(//
new AgreementAcceptanceDemand(definition), //
definition, //
acceptanceState(agreement));
}

private AgreementState acceptanceState(GlobalAgreement agreement) {
return acceptance.accepted(agreement.content(), agreement.name());
}

private Collection<Restriction> restrictions(List<AgreementToAccept> agreements) {
return agreements.stream()//
.filter(agreement -> !agreement.acceptance().accepted())//
.map(agreement -> new UnacceptedAgreementRestriction(product, agreement).get())//
.collect(Collectors.toList());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright (c) 2021 ArSysOp
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0/.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* ArSysOp - initial API and implementation
*******************************************************************************/
package org.eclipse.passage.lic.base.agreements;

import java.util.Collections;
import java.util.List;

import org.eclipse.passage.lic.api.agreements.ResolvedAgreement;
import org.eclipse.passage.lic.api.requirements.Feature;
import org.eclipse.passage.lic.api.requirements.Requirement;
import org.eclipse.passage.lic.api.restrictions.RestrictionLevel;

public final class AgreementAcceptanceDemand implements Requirement {

private final Feature feature;
private final List<ResolvedAgreement> agreement;

public AgreementAcceptanceDemand(ResolvedAgreement agreement) {
this.feature = new GlobalAgreementSupportFeature().get();
this.agreement = Collections.singletonList(agreement);
}

@Override
public Feature feature() {
return feature;
}

@Override
public RestrictionLevel restrictionLevel() {
return new RestrictionLevel.Fatal();
}

@Override
public List<ResolvedAgreement> agreements() {
return agreement;
}

@Override
public Object source() {
return "a license"; //$NON-NLS-1$
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*******************************************************************************
* Copyright (c) 2021 ArSysOp
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0/.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* ArSysOp - initial API and implementation
*******************************************************************************/
package org.eclipse.passage.lic.base.agreements;

import java.util.function.Supplier;

import org.eclipse.passage.lic.api.requirements.Feature;
import org.eclipse.passage.lic.base.requirements.BaseFeature;

public final class GlobalAgreementSupportFeature implements Supplier<Feature> {

@Override
public Feature get() {
return new BaseFeature(//
"passage.global-agreement-support.feature", //$NON-NLS-1$
"0.0.0", //$NON-NLS-1$
"Global Agreements Support", //$NON-NLS-1$
"Eclipse Passage Runtime" //$NON-NLS-1$
);
}

}
Loading