Skip to content

Commit

Permalink
Bug 565656 API revision | restriction execution
Browse files Browse the repository at this point in the history
The decision has been taken to exclude restriction execution from access
cycle and redesign it to a developer's set of facilities for
`Diagnostic` and `ExaminationCertificate` analysis as well as for
performing a set of predefining restrictive actions.

All access cycle related interfaces of this sort are removed from 1.0.0
API.

Signed-off-by: elena.parovyshnaya <elena.parovyshnaya@gmail.com>
  • Loading branch information
eparovyshnaya committed Aug 5, 2020
1 parent bd666ed commit dc88844
Show file tree
Hide file tree
Showing 28 changed files with 338 additions and 302 deletions.
1 change: 0 additions & 1 deletion bundles/org.eclipse.passage.lic.api/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,4 @@ Export-Package: org.eclipse.passage.lic.api,
org.eclipse.passage.lic.internal.api.registry;x-friends:="org.eclipse.passage.lic.base",
org.eclipse.passage.lic.internal.api.requirements;x-friends:="org.eclipse.passage.lic.base",
org.eclipse.passage.lic.internal.api.restrictions;x-friends:="org.eclipse.passage.lic.base",
org.eclipse.passage.lic.internal.api.restrictions.execution;x-internal:=true,
org.eclipse.passage.lic.internal.api.version;x-friends:="org.eclipse.passage.lic.base"
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
package org.eclipse.passage.lic.api.restrictions;

import org.eclipse.passage.lic.api.LicensingResult;
import org.eclipse.passage.lic.internal.api.restrictions.execution.RestrictionExecutingService;
import org.eclipse.passage.lic.internal.api.restrictions.ExaminationCertificate;

/**
*
Expand All @@ -22,7 +22,11 @@
*
* @since 0.4.0
* @see org.eclipse.passage.lic.api
* @deprecated use {@link RestrictionExecutingService}
* @deprecated Restriction execution is not part of access cycle anymore. It is
* now designed as a set of developer's facilities for
* {@linkplain Diagnostic} and {@linkplain ExaminationCertificate}
* analysis as well as for performing some predefined restrictive
* actions.
*/
@Deprecated
public interface RestrictionExecutor {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import org.eclipse.passage.lic.internal.api.io.StreamCodecRegistry;
import org.eclipse.passage.lic.internal.api.requirements.ResolvedRequirementsRegistry;
import org.eclipse.passage.lic.internal.api.restrictions.PermissionsExaminationServicesRegistry;
import org.eclipse.passage.lic.internal.api.restrictions.execution.RestrictionExecutingServicesRegistry;

/**
* Supplies all the service that runtime <i>access cycle</i> can count on.
Expand Down Expand Up @@ -52,5 +51,4 @@ public interface AccessCycleConfiguration {

PermissionsExaminationServicesRegistry examinators();

RestrictionExecutingServicesRegistry executors();
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
*******************************************************************************/
package org.eclipse.passage.lic.internal.api;

import org.eclipse.passage.lic.api.restrictions.RestrictionExecutor;
import org.eclipse.passage.lic.api.restrictions.RestrictionVerdict;
import org.eclipse.passage.lic.internal.api.requirements.Requirement;
import org.eclipse.passage.lic.internal.api.restrictions.ExaminationCertificate;
import org.eclipse.passage.lic.internal.api.restrictions.Restriction;
import org.eclipse.passage.lic.internal.api.restrictions.RestrictionLevel;

/**
* <p>
Expand All @@ -27,12 +28,9 @@
public interface Passage {

/**
* FIXME: add `see` to (1) dedicated parts of the new version of AccessManager
* (2) licensing dialog
*
* <p>
* Direct access to full access cycle up to all found restrictions execution.
* Can cause UI interference in the form of Licensing dialog.
* Full feathered access cycle invocation returns complete set of data and
* diagnostics to take an informed decision
* <p>
*
* <p>
Expand All @@ -43,31 +41,51 @@ public interface Passage {
* @param feature string identifier of the feature under licensing.
* @see org.eclipse.passage.lic.api
*/
void checkLicense(String feature);
ServiceInvocationResult<ExaminationCertificate> checkLicense(String feature);

/**
* FIXME: add `see` to dedicated parts of the new version of AccessManager
* <p>
* Headless way to check if the given {@code feature} is properly licensed. No
* actual {@linkplain RestrictionExecutor}s are going to be involved. FIXME:
* point to particular place in access cycle
* Ask Passage if a product user has enough license coverage to exploit the
* given {@code feature}. Access cycle invocation is simplified to be called in
* a headless environment.
* </p>
* <p>
* The full-feathered response is reduced to simple boolean value according to
* the following rules:
* </p>
* <ul>
* <li>If there is no {@linkplain Requirement} a product defined for the
* feature, then the answer is {@code true} - the feature can be used.</li>
* <li>IF not all the defined {@linkplain Requirement}s found for the feature
* are satisfied by user's license coverage, then we look at how severe are
* those which stay unsatisfied. If these are only of {@code info} or @{cod
* warning} restriction levels, then the feature can be used and the answer is
* again {@code true}</li>
* <li>Is it's not the case, or if the Passage Framework suspects sabotage or is
* poorly configured and cannot properly operate, then the answer is
* {@code false} and the feature cannot be used.</li>
* </ul>
* <p>
* Use it in the case you cannot afford full feather License Dialog appearance.
* Like to implement {@code action::isEnabled} of sorts or to guide simple
* control flow. FIXME: samples
* control flow.
* </p>
*
* @param feature string identifier of the feature under licensing.
* @return true if license check found all licensing requirements satisfied and
* found no restrictions. Any restrictions discovered starting from
* {@code warning} up to {@code fatal} causes {@code false} to be
* returned here. FIXME explain where to get these codes.
* @return {@code true} if the given {@code feature} can be used and
* {@code false} otherwise
*
* @see Requirement
* @see RestrictionVerdict
* @see Restriction
* @see RestrictionLevel
* @see org.eclipse.passage.lic.api
*/
boolean canUse(String feature);

/**
* Get the product identification found and used by Passage across all the
* access cycle phases
*/
ServiceInvocationResult<LicensedProduct> product();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*******************************************************************************
* Copyright (c) 2020 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.internal.api.restrictions;

import java.util.Comparator;

public final class RestrictionComparator implements Comparator<Restriction> {

@Override
public int compare(Restriction left, Restriction right) {
return new RestrictionLevelComparator().compare(level(left), level(right));
}

private RestrictionLevel level(Restriction restriction) {
return restriction.unsatisfiedRequirement().restrictionLevel();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,33 @@

import java.util.Objects;

import org.eclipse.passage.lic.internal.api.registry.ServiceId;

/**
* <p>
* Severity of a licensing requirement and, accordingly, restriction verdict.
* It's up to a product developer to define semantics of a restriction level. By
* default we supply
* </p>
* <ul>
* <li>{@code info} level. It a requirement of this level is not satisfied, then
* a product user should be somehow notified of this fact without pausing
* workflow.</li>
* <li>{@code warn} level: unsatisfied requirement of this type should cause a
* feature execution postponing</li>
* <li>{@code error} level: feature usage should be stopped
* <li>
* <li>{@code fatal} level: the whole product usage must be stopped
* <li>
* </ul>
* <p>
* These treatment can be redesigned according to a product development demands.
* </p>
* <p>
* Designed to be a <i>data-class</i>.
* </p>
*/
public abstract class RestrictionLevel {
public abstract class RestrictionLevel implements ServiceId {

private final String identifier;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*******************************************************************************
* Copyright (c) 2020 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.internal.api.restrictions;

import java.util.Comparator;

public final class RestrictionLevelComparator implements Comparator<RestrictionLevel> {

@Override
public int compare(RestrictionLevel left, RestrictionLevel right) {
return Integer.compare(weight(left), weight(right));
}

private int weight(RestrictionLevel level) {
if (new RestrictionLevel.Info().equals(level)) {
return 1;
}
if (new RestrictionLevel.Warning().equals(level)) {
return 2;
}
if (new RestrictionLevel.Error().equals(level)) {
return 3;
}
if (new RestrictionLevel.Fatal().equals(level)) {
return 4;
}
return 10;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@
* Contributors:
* ArSysOp - initial API and implementation
*******************************************************************************/
package org.eclipse.passage.lic.internal.api.restrictions.execution;
package org.eclipse.passage.lic.internal.base.diagnostic.code;

import java.util.function.Supplier;
import org.eclipse.passage.lic.internal.api.diagnostic.TroubleCode;
import org.eclipse.passage.lic.internal.base.i18n.DiagnosticCodeMessages;

import org.eclipse.passage.lic.internal.api.registry.Registry;
import org.eclipse.passage.lic.internal.api.registry.StringServiceId;
@SuppressWarnings("restriction")
public final class NoFramework extends TroubleCode {

public interface RestrictionExecutingServicesRegistry
extends Supplier<Registry<StringServiceId, RestrictionExecutingService>> {
public NoFramework() {
super(100, DiagnosticCodeMessages.getString("NoFramework.explanation")); //$NON-NLS-1$
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ LicenseNotStarted.license_not_started=License is not started
LicenseCheckFailed.error=License assessment failed with error
ServiceCannotOperate.explanation=Access cycle service cannot operate
NoServices.explanation=There is no services of type [{0}] available
NoFramework.explanation=Passage gains no Framework instance and is completely inoperable. It means either severe lack of configuration or sabotage.
ServiceFailedOnMorsel.explanation=Service failed to evaluate a morsel
ServiceFailedOnInfrastructureDenial.explanation=Service failed severely due to an invoked service denial.
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,22 @@
* Contributors:
* ArSysOp - initial API and implementation
*******************************************************************************/
package org.eclipse.passage.lic.api.tests.fakes.restrictions;
package org.eclipse.passage.lic.internal.base.restrictions;

import java.util.Collection;
import java.util.function.Predicate;

import org.eclipse.passage.lic.internal.api.registry.StringServiceId;
import org.eclipse.passage.lic.internal.api.restrictions.Restriction;
import org.eclipse.passage.lic.internal.api.restrictions.execution.RestrictionExecutingService;
import org.eclipse.passage.lic.internal.api.restrictions.RestrictionLevel;
import org.eclipse.passage.lic.internal.api.restrictions.RestrictionLevelComparator;

@SuppressWarnings("restriction")
public class FakeRestrictionExecutingService implements RestrictionExecutingService {
public final class RestrictionMustPauseExecution implements Predicate<Restriction> {

@Override
public StringServiceId id() {
throw new UnsupportedOperationException();
}

@Override
public void execute(Collection<Restriction> restrictions) {
throw new UnsupportedOperationException();
public boolean test(Restriction restriction) {
return new RestrictionLevelComparator().compare(//
new RestrictionLevel.Warning(), //
restriction.unsatisfiedRequirement().restrictionLevel())//
<= 0;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright (c) 2020 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.internal.base.restrictions;

import java.util.function.Predicate;

import org.eclipse.passage.lic.internal.api.restrictions.Restriction;
import org.eclipse.passage.lic.internal.api.restrictions.RestrictionLevel;
import org.eclipse.passage.lic.internal.api.restrictions.RestrictionLevelComparator;

public final class RestrictionMustStopExecution implements Predicate<Restriction> {

@Override
public boolean test(Restriction restriction) {
return new RestrictionLevelComparator().compare(//
new RestrictionLevel.Error(), //
restriction.unsatisfiedRequirement().restrictionLevel())//
<= 0;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright (c) 2020 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.internal.base.restrictions;

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

import org.eclipse.passage.lic.internal.api.restrictions.Restriction;
import org.eclipse.passage.lic.internal.api.restrictions.RestrictionComparator;

public final class WorstRestrictionsPerFeature implements Supplier<Collection<Restriction>> {

private final Collection<Restriction> restrictions;

public WorstRestrictionsPerFeature(Collection<Restriction> restrictions) {
this.restrictions = restrictions;
}

@Override
public Collection<Restriction> get() {
Map<String, List<Restriction>> featured = restrictions.stream()//
.collect(Collectors.groupingBy(r -> r.unsatisfiedRequirement().feature().identifier()));
return featured.values().stream()//
.map(this::worst) //
.collect(Collectors.toSet());
}

private Restriction worst(List<Restriction> source) {
return sorted(source).get(source.size() - 1);
}

private List<Restriction> sorted(Collection<Restriction> source) {
List<Restriction> sorted = new ArrayList<>(source);
Collections.sort(sorted, new RestrictionComparator());
return sorted;
}

}
Loading

0 comments on commit dc88844

Please sign in to comment.