-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #690 from eclipse-passage/566482
Bug 566482 implement license grants uploading interface
- Loading branch information
Showing
22 changed files
with
463 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
...ssage.lbc.base/src/org/eclipse/passage/lbc/internal/base/interaction/IncomingLicense.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/******************************************************************************* | ||
* 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.lbc.internal.base.interaction; | ||
|
||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.Paths; | ||
import java.util.Collection; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.Objects; | ||
|
||
import org.eclipse.passage.lic.internal.api.ServiceInvocationResult; | ||
import org.eclipse.passage.lic.internal.api.diagnostic.Trouble; | ||
import org.eclipse.passage.lic.internal.base.BaseServiceInvocationResult; | ||
import org.eclipse.passage.lic.internal.base.diagnostic.BaseDiagnostic; | ||
import org.eclipse.passage.lic.internal.base.diagnostic.SumOfLists; | ||
import org.eclipse.passage.lic.internal.base.diagnostic.code.ServiceFailedOnMorsel; | ||
import org.eclipse.passage.lic.internal.base.io.ExternalLicense; | ||
|
||
public final class IncomingLicense { | ||
|
||
private final Path residence; | ||
|
||
public IncomingLicense(String residence) { | ||
Objects.requireNonNull(residence, "IncomingLicense:residence");//$NON-NLS-1$ | ||
this.residence = Paths.get(residence); | ||
validateResidence(); | ||
} | ||
|
||
public ServiceInvocationResult<List<Path>> upload() { | ||
ServiceInvocationResult<Collection<Pack>> packs = new PacksFound(residence).get(); | ||
if (!packs.data().isPresent() || packs.data().get().isEmpty()) { | ||
return new BaseServiceInvocationResult<>(packs.diagnostic()); | ||
} | ||
return packs.data().get().stream()// | ||
.map(this::uploadPack)// | ||
.reduce(new BaseServiceInvocationResult<>(Collections.emptyList()), | ||
new BaseServiceInvocationResult.Sum<>(new SumOfLists<>())); | ||
} | ||
|
||
private ServiceInvocationResult<List<Path>> uploadPack(Pack pack) { | ||
try { | ||
Pack.Resolved resolved = pack.resolve(); | ||
Path destination = new ExternalLicense(resolved.product()).install(pack.content()); | ||
return new BaseServiceInvocationResult<>(Collections.singletonList(destination)); | ||
} catch (Exception e) { | ||
return failedToUploadPack(pack, e); | ||
} | ||
} | ||
|
||
private BaseServiceInvocationResult<List<Path>> failedToUploadPack(Pack pack, Exception e) { | ||
return new BaseServiceInvocationResult<>(new BaseDiagnostic(Collections.singletonList(// | ||
new Trouble(// | ||
new ServiceFailedOnMorsel(), // | ||
String.format("Failed to upload %s", pack), //$NON-NLS-1$ | ||
e)))); | ||
} | ||
|
||
private final void validateResidence() { | ||
String info = residence.toAbsolutePath().toString(); | ||
if (!Files.exists(residence)) { | ||
throw new IllegalArgumentException(String.format("%s does not exist", info)); //$NON-NLS-1$ | ||
} | ||
if (!Files.isDirectory(residence)) { | ||
throw new IllegalArgumentException(String.format("%s is not a directory", info)); //$NON-NLS-1$ | ||
} | ||
if (!Files.isExecutable(residence)) { | ||
throw new IllegalArgumentException(String.format("%s cannot be read", info)); //$NON-NLS-1$ | ||
} | ||
} | ||
|
||
} |
46 changes: 46 additions & 0 deletions
46
...assage.lbc.base/src/org/eclipse/passage/lbc/internal/base/interaction/OnlyFileOfType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/******************************************************************************* | ||
* 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.lbc.internal.base.interaction; | ||
|
||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.attribute.BasicFileAttributes; | ||
import java.util.List; | ||
import java.util.stream.Collectors; | ||
|
||
import org.eclipse.passage.lic.internal.api.LicensingException; | ||
|
||
final class OnlyFileOfType { | ||
|
||
private final Path folder; | ||
private final String extension; | ||
|
||
public OnlyFileOfType(Path folder, String extension) { | ||
this.folder = folder; | ||
this.extension = extension; | ||
} | ||
|
||
Path get() throws Exception { | ||
List<Path> keys = Files.find(folder, 1, this::ofType).collect(Collectors.toList()); | ||
if (keys.size() != 1) { | ||
throw new LicensingException(String.format("%s is expected to contain exactly one file of type %s", //$NON-NLS-1$ | ||
folder.toString(), extension)); | ||
} | ||
return keys.get(0); | ||
} | ||
|
||
private boolean ofType(Path file, @SuppressWarnings("unused") BasicFileAttributes any) { | ||
return file.getFileName().toString().endsWith(extension); | ||
} | ||
|
||
} |
84 changes: 84 additions & 0 deletions
84
....eclipse.passage.lbc.base/src/org/eclipse/passage/lbc/internal/base/interaction/Pack.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/******************************************************************************* | ||
* 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.lbc.internal.base.interaction; | ||
|
||
import java.nio.file.Path; | ||
import java.util.Collections; | ||
|
||
import org.eclipse.passage.lic.floating.model.api.FloatingLicensePack; | ||
import org.eclipse.passage.lic.floating.model.api.ProductRef; | ||
import org.eclipse.passage.lic.floating.model.meta.FloatingPackage; | ||
import org.eclipse.passage.lic.internal.api.LicensedProduct; | ||
import org.eclipse.passage.lic.internal.api.LicensingException; | ||
import org.eclipse.passage.lic.internal.base.BaseLicensedProduct; | ||
import org.eclipse.passage.lic.internal.base.InvalidLicensedProduct; | ||
import org.eclipse.passage.lic.internal.base.conditions.mining.DecodedContent; | ||
import org.eclipse.passage.lic.internal.base.io.FileKeyKeeper; | ||
import org.eclipse.passage.lic.internal.bc.BcStreamCodec; | ||
import org.eclipse.passage.lic.internal.emf.EObjectFromBytes; | ||
|
||
final class Pack { | ||
|
||
private final Path license; | ||
private final Path key; | ||
|
||
Pack(Path license, Path key) { | ||
this.license = license; | ||
this.key = key; | ||
} | ||
|
||
Resolved resolve() throws LicensingException { | ||
return new Resolved(); | ||
} | ||
|
||
Path[] content() { | ||
return new Path[] { license, key }; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return String.format("pack license=[%s], key=[%s]", license.toAbsolutePath(), key.toAbsolutePath()); //$NON-NLS-1$ | ||
} | ||
|
||
final class Resolved { | ||
|
||
private final FloatingLicensePack content; | ||
|
||
Resolved() throws LicensingException { | ||
this.content = read(decoded()); | ||
} | ||
|
||
private FloatingLicensePack read(byte[] bytes) throws LicensingException { | ||
return new EObjectFromBytes<>(// | ||
bytes, // | ||
FloatingLicensePack.class// | ||
).get(Collections.singletonMap(FloatingPackage.eNAME, FloatingPackage.eINSTANCE)); | ||
} | ||
|
||
private byte[] decoded() throws LicensingException { | ||
return new DecodedContent(// | ||
license, // | ||
new FileKeyKeeper(key), // | ||
new BcStreamCodec(InvalidLicensedProduct::new) // not demanded for decoding, only for error handling | ||
).get(); | ||
} | ||
|
||
LicensedProduct product() { | ||
ProductRef ref = content.getLicense().getProduct(); | ||
return new BaseLicensedProduct(ref.getProduct(), ref.getVersion()); | ||
} | ||
|
||
} | ||
|
||
} |
93 changes: 93 additions & 0 deletions
93
...se.passage.lbc.base/src/org/eclipse/passage/lbc/internal/base/interaction/PacksFound.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/******************************************************************************* | ||
* 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.lbc.internal.base.interaction; | ||
|
||
import java.io.File; | ||
import java.nio.file.Path; | ||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.function.Supplier; | ||
|
||
import org.eclipse.passage.lic.floating.FloatingFileExtensions; | ||
import org.eclipse.passage.lic.internal.api.ServiceInvocationResult; | ||
import org.eclipse.passage.lic.internal.api.diagnostic.Trouble; | ||
import org.eclipse.passage.lic.internal.base.BaseServiceInvocationResult; | ||
import org.eclipse.passage.lic.internal.base.SumOfCollections; | ||
import org.eclipse.passage.lic.internal.base.diagnostic.BaseDiagnostic; | ||
import org.eclipse.passage.lic.internal.base.diagnostic.code.NoDataOfType; | ||
import org.eclipse.passage.lic.internal.base.diagnostic.code.ServiceFailedOnMorsel; | ||
import org.eclipse.passage.lic.internal.base.io.PassageFileExtension; | ||
|
||
final class PacksFound implements Supplier<ServiceInvocationResult<Collection<Pack>>> { | ||
|
||
private final Path source; | ||
private final String flicen = new FloatingFileExtensions.FloatingLicenseEncrypted().get(); | ||
private final String pub = new PassageFileExtension.PublicKey().get(); | ||
|
||
public PacksFound(Path source) { | ||
this.source = source; | ||
} | ||
|
||
@Override | ||
public ServiceInvocationResult<Collection<Pack>> get() { | ||
List<ServiceInvocationResult<Collection<Pack>>> packs = new ArrayList<>(); | ||
searchThroughDirectory(source.toFile(), packs); | ||
if (packs.isEmpty()) { | ||
return new BaseServiceInvocationResult<Collection<Pack>>( | ||
new Trouble(new NoDataOfType(), "floating license")); //$NON-NLS-1$ | ||
} | ||
return packs.stream().reduce(// | ||
new BaseServiceInvocationResult<>(Collections.emptyList()), // | ||
new BaseServiceInvocationResult.Sum<>(new SumOfCollections<>())); | ||
} | ||
|
||
private void searchThroughDirectory(File parent, List<ServiceInvocationResult<Collection<Pack>>> packs) { | ||
for (File file : parent.listFiles()) { | ||
if (file.isDirectory()) { | ||
searchThroughDirectory(file, packs); | ||
} else { | ||
maybePack(file).ifPresent(packs::add); | ||
} | ||
} | ||
} | ||
|
||
private Optional<ServiceInvocationResult<Collection<Pack>>> maybePack(File license) { | ||
if (!license.getName().endsWith(flicen)) { | ||
return Optional.empty(); | ||
} | ||
Path key; | ||
try { | ||
key = new OnlyFileOfType(license.getParentFile().toPath(), pub).get(); | ||
} catch (Exception e) { | ||
return Optional.of(failToFindKey(license, e)); | ||
} | ||
return Optional.of(packIndeed(license, key)); | ||
|
||
} | ||
|
||
private ServiceInvocationResult<Collection<Pack>> packIndeed(File license, Path key) { | ||
return new BaseServiceInvocationResult<>(Collections.singletonList(new Pack(license.toPath(), key))); | ||
} | ||
|
||
private ServiceInvocationResult<Collection<Pack>> failToFindKey(File license, Exception e) { | ||
Trouble error = new Trouble(// | ||
new ServiceFailedOnMorsel(), // | ||
String.format("Failed to find public key for license file %s", //$NON-NLS-1$ | ||
license.getAbsolutePath()), | ||
e); | ||
return new BaseServiceInvocationResult<>(new BaseDiagnostic(Collections.singletonList(error))); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.