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

564419 API revision | conditions | Path condition miner #286

Merged
merged 2 commits into from
Jul 6, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,17 @@

import java.util.Collection;

import org.eclipse.passage.lic.internal.api.LicensedProduct;
import org.eclipse.passage.lic.internal.api.conditions.Condition;
import org.eclipse.passage.lic.internal.api.registry.Service;
import org.eclipse.passage.lic.internal.api.registry.StringServiceId;

/**
* <p>
* Condition mining is driven by a {@linkplain LicensedProduct} configuration:
* having coordinates for a product under licensing, miner tries to get all
* {@linkplain Condition}s, under which the product can be used.
* </p>
* <p>
* The miner to extract {@link Condition}s from different sources like
* </p>
Expand All @@ -36,12 +42,12 @@ public interface MinedConditions extends Service<StringServiceId> {
/**
*
* @return all the conditions gained during the mining (caching possible, but
* not mandatory)
* not mandatory) for the given {@code product}
* @throws ConditionMiningException in case of any undeniable misbehavior of a
* mining infrastructure: is it floating
* license server protocol discrepancy or file
* system failure
*/
Collection<Condition> all() throws ConditionMiningException;
Collection<Condition> all(LicensedProduct product) throws ConditionMiningException;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*******************************************************************************
* 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.conditions.mining;

import java.nio.file.Path;
import java.util.Collection;

import org.eclipse.passage.lic.internal.api.LicensedProduct;
import org.eclipse.passage.lic.internal.api.LicensingException;
import org.eclipse.passage.lic.internal.api.conditions.Condition;
import org.eclipse.passage.lic.internal.api.conditions.mining.ConditionMiningException;
import org.eclipse.passage.lic.internal.api.conditions.mining.MinedConditions;
import org.eclipse.passage.lic.internal.api.io.KeyKeeperRegistry;
import org.eclipse.passage.lic.internal.api.io.StreamCodecRegistry;
import org.eclipse.passage.lic.internal.api.registry.StringServiceId;
import org.eclipse.passage.lic.internal.base.i18n.BaseMessages;
import org.eclipse.passage.lic.internal.base.io.FileCollection;
import org.eclipse.passage.lic.internal.base.io.PassageFileExtension;
import org.eclipse.passage.lic.internal.base.io.PathFromLicensedProduct;

@SuppressWarnings("restriction")
public abstract class LocalConditions implements MinedConditions {

protected final StringServiceId id;
private final KeyKeeperRegistry keys;
private final StreamCodecRegistry codecs;

protected LocalConditions(StringServiceId id, KeyKeeperRegistry keys, StreamCodecRegistry codecs) {
this.id = id;
this.keys = keys;
this.codecs = codecs;
}

@Override
public final StringServiceId id() {
return id;
}

@Override
public final Collection<Condition> all(LicensedProduct product) throws ConditionMiningException {
return conditions(licenses(product));
}

private Collection<Path> licenses(LicensedProduct product) throws ConditionMiningException {
try {
return new FileCollection(new PathFromLicensedProduct(this::base, product),
new PassageFileExtension.LicenseEncrypted()).get();
} catch (LicensingException e) {
throw new ConditionMiningException(//
String.format(BaseMessages.getString("PathConditionMiner.failure"), id, product), e); //$NON-NLS-1$
}
}

private Collection<Condition> conditions(Collection<Path> sources) throws ConditionMiningException {
return null;
eparovyshnaya marked this conversation as resolved.
Show resolved Hide resolved

}

protected abstract Path base();

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ ConditionMiners_collect_packs_error=Failed to collect packs at %s
ConditionMiners_mine_error_extracting_conditions=Invalid data %s for configuration %s (%s)
ConditionMiners_mine_task_name=Found licensing conditions for configuration: %s (%s)
ConditionMiners.e_mining_failed=Error for configuration: %s (%s)
FileCollection.failure=Files collecting failed
JointRegistry.retrieve_absent=No service for id %s can be found among %d following registries: \n\t%s
LicensingConditions_validation_invalid_from=Valid from starts in the future for condition %s
LicensingConditions_validation_invalid_until=Valid until ends in the past for condition %s
Expand All @@ -42,6 +43,7 @@ LicensingConditions_validation_no_until=Valid until not specified for condition
PathConditionMiner.e_no_key_keeper_registry=KeyKeeperRegistry is not available
PathConditionMiner.e_no_stream_codec_registry=StreamCodecRegistry is not available
PathConditionMiner.e_not_a_directory=%s is not a directory
PathConditionMiner.failure=Miner %s failed for [%s]
RuntimeRegistry.register_override=Service with id %s is going to be overridden: \n\t from %s \n\t to %s
Registry.retrieve_absent_exception=Service required for id %s is absent in the registry.
Requirements.mandatory_requirements_resolvers_demand_author=Passage Core
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*******************************************************************************
* 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.io;

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.function.Supplier;

import org.eclipse.passage.lic.internal.api.LicensingException;
import org.eclipse.passage.lic.internal.base.i18n.BaseMessages;

public final class FileCollection {

private final Supplier<Path> base;
private final PassageFileExtension extensions;

public FileCollection(Supplier<Path> base, PassageFileExtension extension) {
Objects.requireNonNull(base, "FileCollection::base path"); //$NON-NLS-1$
Objects.requireNonNull(extension, "FileCollection::extension"); //$NON-NLS-1$
this.base = base;
this.extensions = extension;
}

public Collection<Path> get() throws LicensingException {
HunterFiles hunter = new HunterFiles(extensions);
try {
Files.walkFileTree(base.get(), hunter);
} catch (IOException e) {
new LicensingException(BaseMessages.getString("FileCollection.failure"), e); //$NON-NLS-1$
}
return hunter.findings();
}

private static final class HunterFiles extends SimpleFileVisitor<Path> {
private final List<Path> findings = new ArrayList<>();
private final PassageFileExtension extension;

HunterFiles(PassageFileExtension extension) {
this.extension = extension;
}

@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
if (file.getFileName().toString().endsWith(extension.get())) {
findings.add(file);
}
return FileVisitResult.CONTINUE;
}

Collection<Path> findings() {
return findings;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,22 +65,22 @@ public Settings(Supplier<Path> base) {
}

public Map<String, Object> get() throws LicensingException {
Map<String, Object> properties = new HashMap<>();
HunterForSettingsFiles hunter = new HunterForSettingsFiles();
try {
Files.walkFileTree(base.get(), new HunterForSettingsFiles(properties));
Files.walkFileTree(base.get(), hunter);
} catch (IOException e) {
throw new LicensingException(BaseMessages.getString("Settings.error_on_reading_settings"), e); //$NON-NLS-1$
}
return properties;
return hunter.findings();
}

private final class HunterForSettingsFiles extends SimpleFileVisitor<Path> {

private final Map<String, Object> properties;
private final PassageFileExtension extension = new PassageFileExtension.Settings();

public HunterForSettingsFiles(Map<String, Object> properties) {
this.properties = properties;
public HunterForSettingsFiles() {
this.properties = new HashMap<String, Object>();
}

@Override
Expand All @@ -103,6 +103,10 @@ private Set<Entry<Object, Object>> load(Path file) throws IOException {
return heap.entrySet();
}

Map<String, Object> findings() {
return properties;
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
package org.eclipse.passage.lic.internal.hc.remote.impl;

import java.util.Collection;
import java.util.function.Supplier;

import org.eclipse.passage.lic.internal.api.LicensedProduct;
import org.eclipse.passage.lic.internal.api.conditions.Condition;
Expand All @@ -26,11 +25,9 @@
public final class RemoteConditions implements MinedConditions {

private final StringServiceId id = new StringServiceId("remote"); //$NON-NLS-1$
private final Supplier<LicensedProduct> product;
private final ConditionTransportRegistry transports;

public RemoteConditions(Supplier<LicensedProduct> product, ConditionTransportRegistry transports) {
this.product = product;
public RemoteConditions(ConditionTransportRegistry transports) {
this.transports = transports;
}

Expand All @@ -41,9 +38,9 @@ public StringServiceId id() {

// FIXME: consider caching (ttl-ed)
@Override
public Collection<Condition> all() throws ConditionMiningException {
public Collection<Condition> all(LicensedProduct product) throws ConditionMiningException {
return new HttpClient().remoteConditions(//
new RemoteConditionsRequest(product.get()), //
new RemoteConditionsRequest(product), //
new DecryptedConditions(transports));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ final class SealedAccessCycleConfiguration implements AccessCycleConfiguration {
new ComponentRequirements() //
));
conditions = new ReadOnlyRegistry<>(Arrays.asList(//
new RemoteConditions(product, conditionTransports())//
new RemoteConditions(conditionTransports())//
));
transports = new ReadOnlyRegistry<>(Arrays.asList(//
new JsonConditionTransport()//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.Collection;
import java.util.Collections;

import org.eclipse.passage.lic.internal.api.LicensedProduct;
import org.eclipse.passage.lic.internal.api.conditions.Condition;
import org.eclipse.passage.lic.internal.api.conditions.mining.ConditionMiningException;
import org.eclipse.passage.lic.internal.api.conditions.mining.MinedConditions;
Expand All @@ -29,7 +30,7 @@ public StringServiceId id() {
}

@Override
public Collection<Condition> all() throws ConditionMiningException {
public Collection<Condition> all(LicensedProduct product) throws ConditionMiningException {
return Collections.emptySet();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*******************************************************************************
* 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.tests.io;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeNoException;

import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collection;

import org.eclipse.passage.lic.internal.api.LicensingException;
import org.eclipse.passage.lic.internal.base.io.FileCollection;
import org.eclipse.passage.lic.internal.base.io.PassageFileExtension;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

@SuppressWarnings("restriction")
public final class FileCollectionTest {
@Rule
public TemporaryFolder folder = new TemporaryFolder();

@Test
public void findsMatchingFiles() throws LicensingException {
Collection<Path> findings = //
new FileCollection(this::emulated, new PassageFileExtension.LicenseEncrypted()).get();
assertEquals(2, findings.size());
assertTrue(findings.stream()//
.map(Path::getFileName)//
.map(Object::toString)//
.allMatch(name -> name.contains("hunted"))); //$NON-NLS-1$
}

@Test(expected = NullPointerException.class)
public void pathSupplierIsMandatory() {
new FileCollection(null, new PassageFileExtension.PublicKey());
}

@Test(expected = NullPointerException.class)
public void extensionIsMandatory() {
new FileCollection(folder.getRoot()::toPath, null);
}

@Test(expected = NullPointerException.class)
public void pushIsMandatoryOnAction() throws LicensingException {
new FileCollection(() -> null, new PassageFileExtension.PublicKey()).get();

}

private Path emulated() {
PassageFileExtension hunted = new PassageFileExtension.LicenseEncrypted();
String foreign = ".txt"; //$NON-NLS-1$
try {
folder.newFolder("inner"); //$NON-NLS-1$
folder.newFile(//
Paths.get("inner") //$NON-NLS-1$
.resolve("hunted_inner" + hunted.get()) //$NON-NLS-1$
.toString());
folder.newFile(//
Paths.get("inner") //$NON-NLS-1$
.resolve("foreign_inner" + foreign) //$NON-NLS-1$
.toString());
folder.newFile("hunted" + hunted.get()); //$NON-NLS-1$
folder.newFile("foreign" + foreign); //$NON-NLS-1$
} catch (IOException e) {
assumeNoException(e);
}

return folder.getRoot().toPath();
}
}