diff --git a/.gitignore b/.gitignore
index a4c3195..c9cdabe 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
.idea/
.vscode/
alvarium-sdk-java.iml
+sbom-tool
# Compiled class file
*.class
diff --git a/pom.xml b/pom.xml
index 6c7b1a1..2607370 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,14 +10,39 @@
alvarium-sdk
https://alvarium.org/
-
+
11
11
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 3.6.0
+
+
+ jar-with-dependencies
+
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
-
+
org.apache.httpcomponents
httpclient
@@ -30,7 +55,7 @@
4.11
test
-
+
com.google.crypto.tink
tink
@@ -38,47 +63,47 @@
- com.google.code.gson
- gson
- 2.8.8
+ com.google.code.gson
+ gson
+ 2.8.8
+
+
+
+ de.huxhorn.sulky
+ de.huxhorn.sulky.ulid
+ 8.2.0
- de.huxhorn.sulky
- de.huxhorn.sulky.ulid
- 8.2.0
+ org.eclipse.paho
+ org.eclipse.paho.client.mqttv3
+ 1.2.5
- org.eclipse.paho
- org.eclipse.paho.client.mqttv3
- 1.2.5
+ io.pravega
+ pravega-client
+ 0.10.0
+
+
+
+ org.apache.logging.log4j
+ log4j-api
+ 2.21.0
+
+
+
+ org.apache.logging.log4j
+ log4j-core
+ 2.21.0
+ test
- io.pravega
- pravega-client
- 0.10.0
+ org.spdx
+ spdx-jackson-store
+ 1.1.9.1
-
- org.apache.logging.log4j
- log4j-api
- 2.21.0
-
-
-
- org.apache.logging.log4j
- log4j-core
- 2.21.0
- test
-
-
-
- org.spdx
- spdx-jackson-store
- 1.1.9.1
-
-
-
+
\ No newline at end of file
diff --git a/src/main/java/com/alvarium/DefaultSdk.java b/src/main/java/com/alvarium/DefaultSdk.java
index 44dba56..709c93f 100644
--- a/src/main/java/com/alvarium/DefaultSdk.java
+++ b/src/main/java/com/alvarium/DefaultSdk.java
@@ -14,10 +14,6 @@
*******************************************************************************/
package com.alvarium;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
import com.alvarium.annotators.Annotator;
import com.alvarium.annotators.AnnotatorConfig;
import com.alvarium.annotators.AnnotatorException;
@@ -25,14 +21,20 @@
import com.alvarium.contracts.Annotation;
import com.alvarium.contracts.AnnotationList;
import com.alvarium.contracts.AnnotationType;
+import com.alvarium.hash.HashProviderFactory;
+import com.alvarium.hash.HashTypeException;
import com.alvarium.streams.StreamException;
import com.alvarium.streams.StreamProvider;
import com.alvarium.streams.StreamProviderFactory;
import com.alvarium.utils.ImmutablePropertyBag;
import com.alvarium.utils.PropertyBag;
-
import org.apache.logging.log4j.Logger;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+
public class DefaultSdk implements Sdk {
private final Annotator[] annotators;
private final SdkInfo config;
@@ -51,20 +53,20 @@ public DefaultSdk(Annotator[] annotators, SdkInfo config, Logger logger) throws
this.logger.debug("stream provider connected successfully.");
}
- public void create(PropertyBag properties, byte[] data) throws AnnotatorException,
- StreamException {
+ public void create(PropertyBag properties, byte[] data) throws AnnotatorException,
+ StreamException, HashTypeException {
final List annotations = this.createAnnotations(properties, data);
this.publishAnnotations(SdkAction.CREATE, annotations);
this.logger.debug("data annotated and published successfully.");
}
-
- public void create(byte[] data) throws AnnotatorException, StreamException {
- final PropertyBag properties = new ImmutablePropertyBag(new HashMap());
+
+ public void create(byte[] data) throws AnnotatorException, StreamException, HashTypeException {
+ final PropertyBag properties = new ImmutablePropertyBag(new HashMap<>());
this.create(properties, data);
}
- public void mutate(PropertyBag properties, byte[] oldData, byte[] newData) throws
- AnnotatorException, StreamException {
+ public void mutate(PropertyBag properties, byte[] oldData, byte[] newData) throws
+ AnnotatorException, StreamException, HashTypeException {
final List annotations = new ArrayList();
// source annotate the old data
@@ -74,14 +76,19 @@ public void mutate(PropertyBag properties, byte[] oldData, byte[] newData) throw
this.config,
this.logger
);
- final Annotation sourceAnnotation = sourceAnnotator.execute(properties, oldData);
+
+ String key;
+ var hasher = new HashProviderFactory().getProvider(config.getHash().getType());
+ key = hasher.derive(oldData);
+
+ final Annotation sourceAnnotation = sourceAnnotator.execute(properties, oldData, key);
annotations.add(sourceAnnotation);
// Add annotations for new data
- for (Annotation annotation: this.createAnnotations(properties, newData)) {
+ for (Annotation annotation : this.createAnnotations(properties, newData)) {
// TLS is ignored in mutate to prevent needless penalization
// See https://github.com/project-alvarium/alvarium-sdk-go/issues/19
- if(annotation.getKind() != AnnotationType.TLS) {
+ if (annotation.getKind() != AnnotationType.TLS) {
annotations.add(annotation);
}
}
@@ -91,32 +98,32 @@ public void mutate(PropertyBag properties, byte[] oldData, byte[] newData) throw
this.logger.debug("data annotated and published successfully.");
}
- public void mutate(byte[] oldData, byte[] newData) throws AnnotatorException, StreamException {
- final PropertyBag properties = new ImmutablePropertyBag(new HashMap());
+ public void mutate(byte[] oldData, byte[] newData) throws AnnotatorException, StreamException, HashTypeException {
+ final PropertyBag properties = new ImmutablePropertyBag(new HashMap<>());
this.mutate(properties, oldData, newData);
}
public void transit(PropertyBag properties, byte[] data) throws AnnotatorException,
- StreamException {
+ StreamException, HashTypeException {
final List annotations = this.createAnnotations(properties, data);
this.publishAnnotations(SdkAction.TRANSIT, annotations);
this.logger.debug("data annotated and published successfully.");
}
- public void transit(byte[] data) throws AnnotatorException, StreamException {
+ public void transit(byte[] data) throws AnnotatorException, StreamException, HashTypeException {
final PropertyBag properties = new ImmutablePropertyBag(new HashMap());
this.transit(properties, data);
}
public void publish(PropertyBag properties, byte[] data) throws AnnotatorException,
- StreamException {
+ StreamException, HashTypeException {
final List annotations = this.createAnnotations(properties, data);
this.publishAnnotations(SdkAction.PUBLISH, annotations);
this.logger.debug("data annotated and published successfully.");
}
-
- public void publish(byte[] data) throws AnnotatorException, StreamException {
- final PropertyBag properties = new ImmutablePropertyBag(new HashMap());
+
+ public void publish(byte[] data) throws AnnotatorException, StreamException, HashTypeException {
+ final PropertyBag properties = new ImmutablePropertyBag(new HashMap<>());
this.publish(properties, data);
}
@@ -127,18 +134,23 @@ public void close() throws StreamException {
/**
* Executes all the specified annotators and returns a list of all the created annotations
+ *
* @param properties
* @param data
* @return
* @throws AnnotatorException
*/
- private List createAnnotations(PropertyBag properties, byte[] data)
- throws AnnotatorException {
- final List annotations = new ArrayList();
+ private List createAnnotations(PropertyBag properties, byte[] data)
+ throws AnnotatorException, HashTypeException {
+ final List annotations = new ArrayList<>();
+
+ String key;
+ var hasher = new HashProviderFactory().getProvider(config.getHash().getType());
+ key = hasher.derive(data);
// Annotate incoming data
- for (Annotator annotator: this.annotators) {
- final Annotation annotation = annotator.execute(properties, data);
+ for (Annotator annotator : this.annotators) {
+ final Annotation annotation = annotator.execute(properties, data, key);
annotations.add(annotation);
}
@@ -146,20 +158,21 @@ private List createAnnotations(PropertyBag properties, byte[] data)
}
/**
- * Wraps the annotation list with a publish wrapper that specifies the SDK action and the
+ * Wraps the annotation list with a publish wrapper that specifies the SDK action and the
* content type
+ *
* @param action
* @param annotations
* @throws StreamException
*/
- private void publishAnnotations(SdkAction action, List annotations)
+ private void publishAnnotations(SdkAction action, List annotations)
throws StreamException {
final AnnotationList annotationList = new AnnotationList(annotations);
-
+
// publish list of annotations to the StreamProvider
final PublishWrapper wrapper = new PublishWrapper(
- action,
- annotationList.getClass().getName(),
+ action,
+ annotationList.getClass().getName(),
annotationList
);
this.stream.publish(wrapper);
diff --git a/src/main/java/com/alvarium/PublishWrapper.java b/src/main/java/com/alvarium/PublishWrapper.java
index 9051883..b19d154 100644
--- a/src/main/java/com/alvarium/PublishWrapper.java
+++ b/src/main/java/com/alvarium/PublishWrapper.java
@@ -14,14 +14,9 @@
*******************************************************************************/
package com.alvarium;
-import java.io.Serializable;
-import java.util.Base64;
+import com.alvarium.serializers.Serialization;
-import com.alvarium.contracts.Annotation;
-import com.alvarium.serializers.AnnotationConverter;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonElement;
+import java.io.Serializable;
/**
* A java bean that encapsulates the content sent through the stream providers
@@ -32,6 +27,7 @@ public class PublishWrapper implements Serializable {
private final String messageType;
private final Object content;
+
public PublishWrapper(SdkAction action, String messageType, Object content) {
this.action = action;
this.messageType = messageType;
@@ -50,33 +46,12 @@ public Object getContent() {
return content;
}
+
/**
- * The content field in the returned JSON will be Base64 string encoded
+ * The content field in the returned JSON will be Base64 string encoded
* @return String representation of the PublishWrapper JSON
*/
public String toJson() {
- Gson gson = new GsonBuilder()
- .registerTypeAdapter(Annotation.class, new AnnotationConverter())
- .disableHtmlEscaping()
- .create();
-
- // Change the content field to a base64 encoded string before serializing to json
- final JsonElement decodedContent = gson.toJsonTree(this.content);
- final String encodedContent;
-
- // `toString()` will work if the content is a primitive type, but will add additional
- // quotes (e.g. "foo" will be "\"foo\"") but `getAsString()` will produce correct behavior but
- // using `getAsString()` on a non-primitive type will throw an exception.
- // This condition ensures that the correct method is called on the correct type
- if (decodedContent.isJsonPrimitive()) {
- encodedContent = Base64.getEncoder().encodeToString(decodedContent.getAsString().getBytes());
- } else {
- encodedContent = Base64.getEncoder().encodeToString(decodedContent.toString().getBytes());
- }
-
- // new publish wrapper returned as JSON string with encoded content
- // to prevent setting the object content value
- final PublishWrapper wrapper = new PublishWrapper(action, messageType, encodedContent);
- return gson.toJson(wrapper);
+ return Serialization.toJson(this);
}
}
diff --git a/src/main/java/com/alvarium/Sdk.java b/src/main/java/com/alvarium/Sdk.java
index 0346920..e3c5803 100644
--- a/src/main/java/com/alvarium/Sdk.java
+++ b/src/main/java/com/alvarium/Sdk.java
@@ -15,6 +15,7 @@
package com.alvarium;
import com.alvarium.annotators.AnnotatorException;
+import com.alvarium.hash.HashTypeException;
import com.alvarium.streams.StreamException;
import com.alvarium.utils.PropertyBag;
@@ -33,8 +34,8 @@ public interface Sdk {
* @throws AnnotatorException
* @throws StreamException
*/
- public void create(PropertyBag properties, byte[] data)
- throws AnnotatorException, StreamException;
+ public void create(PropertyBag properties, byte[] data)
+ throws AnnotatorException, StreamException, HashTypeException;
/**
* Annotates incoming data based on the list of annotators that was provided to the sdk and
@@ -43,7 +44,7 @@ public void create(PropertyBag properties, byte[] data)
* @throws AnnotatorException
* @throws StreamException
*/
- public void create(byte[] data) throws AnnotatorException, StreamException;
+ public void create(byte[] data) throws AnnotatorException, StreamException, HashTypeException;
/**
* Used when the recieved piece of data is originated by a separate application.
@@ -57,8 +58,8 @@ public void create(PropertyBag properties, byte[] data)
* @throws AnnotatorException
* @throws StreamException
*/
- public void transit(PropertyBag properties, byte[] data)
- throws AnnotatorException, StreamException;
+ public void transit(PropertyBag properties, byte[] data)
+ throws AnnotatorException, StreamException, HashTypeException;
/**
* Used when the recieved piece of data is originated by a separate application.
@@ -67,7 +68,7 @@ public void transit(PropertyBag properties, byte[] data)
* @throws AnnotatorException
* @throws StreamException
*/
- public void transit(byte[] data) throws AnnotatorException, StreamException;
+ public void transit(byte[] data) throws AnnotatorException, StreamException, HashTypeException;
/**
* Handles annotations related to any type of data modification.
* @param properties : A property bag that may be used by specific (or custom) annotators to pass
@@ -80,14 +81,14 @@ public void transit(PropertyBag properties, byte[] data)
* @throws AnnotatorException
* @throws StreamException
*/
- public void mutate(PropertyBag properties, byte[] oldData, byte[] newData) throws
- AnnotatorException, StreamException;
+ public void mutate(PropertyBag properties, byte[] oldData, byte[] newData) throws
+ AnnotatorException, StreamException, HashTypeException;
/**
* Handles annotations related to any type of data modification.
* @throws StreamException
*/
- public void mutate(byte[] oldData, byte[] newData) throws AnnotatorException, StreamException;
+ public void mutate(byte[] oldData, byte[] newData) throws AnnotatorException, StreamException, HashTypeException;
/**
* Publish is proposed to provide extensibility for annotators that may need
@@ -104,8 +105,8 @@ public void mutate(PropertyBag properties, byte[] oldData, byte[] newData) throw
* @throws AnnotatorException
* @throws StreamException
*/
- public void publish(PropertyBag properties, byte[] data)
- throws AnnotatorException, StreamException;
+ public void publish(PropertyBag properties, byte[] data)
+ throws AnnotatorException, StreamException, HashTypeException;
/**
* Publish is proposed to provide extensibility for annotators that may need
@@ -116,7 +117,7 @@ public void publish(PropertyBag properties, byte[] data)
* @throws AnnotatorException
* @throws StreamException
*/
- public void publish(byte[] data) throws AnnotatorException, StreamException;
+ public void publish(byte[] data) throws AnnotatorException, StreamException, HashTypeException;
/**
* Closes any open connections
diff --git a/src/main/java/com/alvarium/annotators/Annotator.java b/src/main/java/com/alvarium/annotators/Annotator.java
index 1678039..f12dc4a 100644
--- a/src/main/java/com/alvarium/annotators/Annotator.java
+++ b/src/main/java/com/alvarium/annotators/Annotator.java
@@ -27,5 +27,5 @@ public interface Annotator {
* @return Annotation object
* @throws AnnotatorException
*/
- public Annotation execute(PropertyBag ctx, byte[] data) throws AnnotatorException;
+ public Annotation execute(PropertyBag ctx, byte[] data, String key) throws AnnotatorException;
}
diff --git a/src/main/java/com/alvarium/annotators/ChecksumAnnotator.java b/src/main/java/com/alvarium/annotators/ChecksumAnnotator.java
index bbea2f6..6c41a3c 100644
--- a/src/main/java/com/alvarium/annotators/ChecksumAnnotator.java
+++ b/src/main/java/com/alvarium/annotators/ChecksumAnnotator.java
@@ -20,9 +20,8 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
-import java.time.Instant;
+import java.time.ZonedDateTime;
-import org.apache.logging.log4j.Logger;
import com.alvarium.contracts.Annotation;
import com.alvarium.contracts.AnnotationType;
@@ -33,135 +32,138 @@
import com.alvarium.hash.HashTypeException;
import com.alvarium.sign.SignatureInfo;
import com.alvarium.utils.PropertyBag;
+import org.apache.logging.log4j.Logger;
-public class ChecksumAnnotator extends AbstractAnnotator implements Annotator {
-
- final private HashType hash;
- final private SignatureInfo signature;
- private final AnnotationType kind;
- private final LayerType layer;
- private HashProvider hashProvider;
+public class ChecksumAnnotator extends AbstractAnnotator implements Annotator {
- protected ChecksumAnnotator(HashType hash, SignatureInfo signature, Logger logger, LayerType layer) {
- super(logger);
- this.hash = hash;
- this.signature = signature;
- this.kind = AnnotationType.CHECKSUM;
- this.layer = layer;
+ final private HashType hash;
+ final private SignatureInfo signature;
+ private final AnnotationType kind;
+ private final LayerType layer;
+
+ private HashProvider hashProvider;
+
+ protected ChecksumAnnotator(HashType hash, SignatureInfo signature, Logger logger, LayerType layer) {
+ super(logger);
+ this.hash = hash;
+ this.signature = signature;
+ this.kind = AnnotationType.CHECKSUM;
+ this.layer = layer;
+ }
+
+ @Override
+ public Annotation execute(PropertyBag ctx, byte[] data, String key) throws AnnotatorException {
+
+ this.initHashProvider(this.hash);
+ final ChecksumAnnotatorProps props = ctx.getProperty(
+ AnnotationType.CHECKSUM.name(),
+ ChecksumAnnotatorProps.class
+ );
+
+ String host = "";
+ boolean isSatisfied;
+ try {
+ host = InetAddress.getLocalHost().getHostName();
+ // Get artifact checksum
+ final String checksum = this.readFile(props.getChecksumPath());
+
+ // Validate artifact checksum
+ final String artifactHash = this.hashFile(props.getArtifactPath());
+
+ isSatisfied = checksum.equals(artifactHash);
+ } catch (UnknownHostException | AnnotatorException e) {
+ isSatisfied = false;
+ //log the error using the logger
+ this.logger.error("Error during ChecksumAnnotator execution: ", e);
}
-
- @Override
- public Annotation execute(PropertyBag ctx, byte[] data) throws AnnotatorException {
-
- this.initHashProvider(this.hash);
- final String key = this.hashProvider.derive(data);
-
- final ChecksumAnnotatorProps props = ctx.getProperty(
- AnnotationType.CHECKSUM.name(),
- ChecksumAnnotatorProps.class
- );
-
- String host = "";
- boolean isSatisfied;
- try{
- host = InetAddress.getLocalHost().getHostName();
- // Get artifact checksum
- final String checksum = this.readFile(props.getChecksumPath());
-
- // Validate artifact checksum
- final String artifactHash = this.hashFile(props.getArtifactPath());
-
- isSatisfied = checksum.equals(artifactHash);
- } catch (UnknownHostException | AnnotatorException e) {
- isSatisfied = false;
- //log the error using the logger
- this.logger.error("Error during ChecksumAnnotator execution: ",e);
- }
- final Annotation annotation = new Annotation(
- key,
- this.hash,
- host,
- layer,
- this.kind,
- null,
- isSatisfied,
- Instant.now()
- );
-
- final String annotationSignature = super.signAnnotation(
- this.signature.getPrivateKey(),
- annotation
- );
- annotation.setSignature(annotationSignature);
- return annotation;
+ final Annotation annotation = new Annotation(
+ key,
+ this.hash,
+ host,
+ layer,
+ this.kind,
+ null,
+ isSatisfied,
+ ZonedDateTime.now()
+ );
+
+ final String annotationSignature = super.signAnnotation(
+ this.signature.getPrivateKey(),
+ annotation
+ );
+ annotation.setSignature(annotationSignature);
+ return annotation;
+ }
+
+ /**
+ * Initializes a hash provider
+ *
+ * @return HashProvider
+ * @throws AnnotatorException - If hashing algorithm not found,
+ * or if an unknown exception was thrown
+ */
+ private final void initHashProvider(HashType hashType) throws AnnotatorException {
+ try {
+ this.hashProvider = new HashProviderFactory().getProvider(hashType);
+ } catch (HashTypeException e) {
+ throw new AnnotatorException("Hashing algorithm not found, could not hash data or validate checksum", e);
+ } catch (Exception e) {
+ throw new AnnotatorException("Could not hash data or validate checksum", e);
}
-
- /**
- * Initializes a hash provider
- * @return HashProvider
- * @throws AnnotatorException - If hashing algorithm not found,
- * or if an unknown exception was thrown
- */
- private final void initHashProvider(HashType hashType) throws AnnotatorException {
- try {
- this.hashProvider = new HashProviderFactory().getProvider(hashType);
- } catch (HashTypeException e) {
- throw new AnnotatorException("Hashing algorithm not found, could not hash data or validate checksum", e);
- } catch (Exception e) {
- throw new AnnotatorException("Could not hash data or validate checksum", e);
- }
+ }
+
+ /**
+ * Reads a file on the local file system
+ *
+ * @param filePath
+ * @return String content of file
+ * @throws AnnotatorException - When bad file path or corrupted file given
+ */
+ private final String readFile(String filePath) throws AnnotatorException {
+ final String content;
+ try {
+ content = Files.readString(
+ Paths.get(filePath),
+ StandardCharsets.UTF_8
+ );
+ } catch (IOException e) {
+ throw new AnnotatorException("Failed to read file, could not validate checksum", e);
}
-
- /**
- * Reads a file on the local file system
- * @param filePath
- * @return String content of file
- * @throws AnnotatorException - When bad file path or corrupted file given
- */
- private final String readFile(String filePath) throws AnnotatorException {
- final String content;
- try {
- content = Files.readString(
- Paths.get(filePath),
- StandardCharsets.UTF_8
- );
- } catch (IOException e) {
- throw new AnnotatorException("Failed to read file, could not validate checksum", e);
+ return content;
+ }
+
+ /**
+ * Reads and hashes a file on the local file system in in chunks of 8KB
+ *
+ * @param filePath
+ * @return hash of the file's contents in string format
+ * @throws AnnotatorException - When bad file path or corrupted file given
+ */
+ private final String hashFile(String filePath) throws AnnotatorException {
+ try {
+ FileInputStream fs = new FileInputStream(filePath);
+ final byte[] buffer = new byte[8192];
+
+ int bytesRead = 0;
+ while (true) {
+ bytesRead = fs.read(buffer);
+ if (bytesRead == -1) { // indicates EOF
+ break;
+ } else {
+ this.hashProvider.update(buffer, 0, bytesRead);
}
- return content;
+ }
+
+ fs.close();
+ } catch (IOException e) {
+ throw new AnnotatorException(
+ "Failed to hash artifact, could not validate checksum",
+ e
+ );
}
- /**
- * Reads and hashes a file on the local file system in in chunks of 8KB
- * @param filePath
- * @return hash of the file's contents in string format
- * @throws AnnotatorException - When bad file path or corrupted file given
- */
- private final String hashFile(String filePath) throws AnnotatorException {
- try {
- FileInputStream fs = new FileInputStream(filePath);
- final byte[] buffer = new byte[8192];
-
- int bytesRead = 0;
- while (true) {
- bytesRead = fs.read(buffer);
- if (bytesRead == -1) { // indicates EOF
- break;
- } else {
- this.hashProvider.update(buffer, 0, bytesRead);
- }
- }
-
- fs.close();
- } catch(IOException e) {
- throw new AnnotatorException(
- "Failed to hash artifact, could not validate checksum",
- e
- );
- }
-
- return this.hashProvider.getValue();
- }
+ return this.hashProvider.getValue();
+ }
}
diff --git a/src/main/java/com/alvarium/annotators/MockAnnotator.java b/src/main/java/com/alvarium/annotators/MockAnnotator.java
index 2ce39fe..3e74a07 100644
--- a/src/main/java/com/alvarium/annotators/MockAnnotator.java
+++ b/src/main/java/com/alvarium/annotators/MockAnnotator.java
@@ -16,14 +16,12 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
-import java.time.Instant;
+import java.time.ZonedDateTime;
import com.alvarium.contracts.Annotation;
import com.alvarium.contracts.AnnotationType;
import com.alvarium.contracts.LayerType;
-import com.alvarium.hash.HashProviderFactory;
import com.alvarium.hash.HashType;
-import com.alvarium.hash.HashTypeException;
import com.alvarium.sign.SignatureInfo;
import com.alvarium.utils.PropertyBag;
@@ -45,19 +43,15 @@ protected MockAnnotator(MockAnnotatorConfig cfg, HashType hash, SignatureInfo si
this.layer = layer;
}
- public Annotation execute(PropertyBag ctx, byte[] data) throws AnnotatorException {
- final HashProviderFactory hashFactory = new HashProviderFactory();
+ public Annotation execute(PropertyBag ctx, byte[] data, String key) throws AnnotatorException {
try {
- final String key = hashFactory.getProvider(hash).derive(data);
final String host = InetAddress.getLocalHost().getHostName();
final String sig = signature.getPublicKey().getType().toString();
- final Annotation annotation = new Annotation(key, hash, host, layer, kind, sig, cfg.getShouldSatisfy(), Instant.now());
+ final Annotation annotation = new Annotation(key, hash, host, layer, kind, sig, cfg.getShouldSatisfy(), ZonedDateTime.now());
return annotation;
- } catch (HashTypeException e) {
- throw new AnnotatorException("failed to hash data", e);
} catch (UnknownHostException e) {
throw new AnnotatorException("Could not get hostname", e);
}
- }
+ }
}
diff --git a/src/main/java/com/alvarium/annotators/PkiAnnotator.java b/src/main/java/com/alvarium/annotators/PkiAnnotator.java
index 9c4d9af..fb88ef4 100644
--- a/src/main/java/com/alvarium/annotators/PkiAnnotator.java
+++ b/src/main/java/com/alvarium/annotators/PkiAnnotator.java
@@ -14,18 +14,17 @@
*******************************************************************************/
package com.alvarium.annotators;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.time.Instant;
-
-import org.apache.logging.log4j.Logger;
-
import com.alvarium.contracts.Annotation;
import com.alvarium.contracts.AnnotationType;
import com.alvarium.contracts.LayerType;
import com.alvarium.hash.HashType;
import com.alvarium.sign.SignatureInfo;
import com.alvarium.utils.PropertyBag;
+import org.apache.logging.log4j.Logger;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.time.ZonedDateTime;
class PkiAnnotator extends AbstractPkiAnnotator implements Annotator {
private final HashType hash;
@@ -41,9 +40,7 @@ protected PkiAnnotator(HashType hash, SignatureInfo signature, Logger logger, La
this.layer = layer;
}
- public Annotation execute(PropertyBag ctx, byte[] data) throws AnnotatorException {
- final String key = super.deriveHash(hash, data);
-
+ public Annotation execute(PropertyBag ctx, byte[] data, String key) throws AnnotatorException {
final Signable signable = Signable.fromJson(new String(data));
String host = "";
@@ -65,7 +62,7 @@ public Annotation execute(PropertyBag ctx, byte[] data) throws AnnotatorExceptio
kind,
null,
isSatisfied,
- Instant.now());
+ ZonedDateTime.now());
final String annotationSignature = super.signAnnotation(signature.getPrivateKey(), annotation);
annotation.setSignature(annotationSignature);
diff --git a/src/main/java/com/alvarium/annotators/PkiHttpAnnotator.java b/src/main/java/com/alvarium/annotators/PkiHttpAnnotator.java
index f91ca75..d200ded 100644
--- a/src/main/java/com/alvarium/annotators/PkiHttpAnnotator.java
+++ b/src/main/java/com/alvarium/annotators/PkiHttpAnnotator.java
@@ -19,8 +19,8 @@
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.nio.file.Paths;
-import java.time.Instant;
import java.nio.file.Path;
+import java.time.ZonedDateTime;
import com.alvarium.annotators.http.ParseResult;
import com.alvarium.annotators.http.ParseResultException;
@@ -50,16 +50,14 @@ protected PkiHttpAnnotator(HashType hash, SignatureInfo signature, Logger logger
this.layer = layer;
}
- public Annotation execute(PropertyBag ctx, byte[] data) throws AnnotatorException {
- final String key = super.deriveHash(hash, data);
-
+ public Annotation execute(PropertyBag ctx, byte[] data, String key) throws AnnotatorException {
HttpUriRequest request;
try {
request = ctx.getProperty(AnnotationType.PKIHttp.name(), HttpUriRequest.class);
} catch (IllegalArgumentException e) {
throw new AnnotatorException(String.format("Property %s not found", AnnotationType.PKIHttp.name()));
}
- ParseResult parsed;
+ ParseResult parsed;
try {
parsed = new ParseResult(request);
} catch (URISyntaxException e) {
@@ -86,15 +84,15 @@ public Annotation execute(PropertyBag ctx, byte[] data) throws AnnotatorExceptio
String host = "";
boolean isSatisfied;
- try{
+ try {
host = InetAddress.getLocalHost().getHostName();
isSatisfied = verifySignature(sig.getPublicKey(), signable);
} catch (UnknownHostException | AnnotatorException e) {
isSatisfied = false;
- this.logger.error("Error during PkiHttpAnnotator execution: ",e);
+ this.logger.error("Error during PkiHttpAnnotator execution: ", e);
}
-
+
final Annotation annotation = new Annotation(
key,
hash,
@@ -103,7 +101,7 @@ public Annotation execute(PropertyBag ctx, byte[] data) throws AnnotatorExceptio
kind,
null,
isSatisfied,
- Instant.now());
+ ZonedDateTime.now());
final String annotationSignature = super.signAnnotation(sig.getPrivateKey(), annotation);
annotation.setSignature(annotationSignature);
diff --git a/src/main/java/com/alvarium/annotators/SbomAnnotator.java b/src/main/java/com/alvarium/annotators/SbomAnnotator.java
index c5bd074..64a07d8 100644
--- a/src/main/java/com/alvarium/annotators/SbomAnnotator.java
+++ b/src/main/java/com/alvarium/annotators/SbomAnnotator.java
@@ -15,12 +15,12 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
-import java.time.Instant;
+import java.time.ZonedDateTime;
+import com.alvarium.annotators.sbom.SbomException;
import org.apache.logging.log4j.Logger;
import com.alvarium.annotators.sbom.SbomAnnotatorConfig;
-import com.alvarium.annotators.sbom.SbomException;
import com.alvarium.annotators.sbom.SbomProvider;
import com.alvarium.annotators.sbom.SbomProviderFactory;
import com.alvarium.contracts.Annotation;
@@ -46,18 +46,16 @@ protected SbomAnnotator(SbomAnnotatorConfig cfg, HashType hash, SignatureInfo si
this.kind = AnnotationType.SBOM;
this.layer = layer;
}
-
- @Override
- public Annotation execute(PropertyBag ctx, byte[] data) throws AnnotatorException {
- final String key = deriveHash(this.hash, data);
+ @Override
+ public Annotation execute(PropertyBag ctx, byte[] data, String key) throws AnnotatorException {
String host = "";
- try{
+ try {
host = InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
- this.logger.error("Error during SbomAnnotator execution: ",e);
+ this.logger.error("Error during SbomAnnotator execution: ", e);
}
-
+
boolean isSatisfied = false;
try {
final SbomProvider sbom = new SbomProviderFactory().getProvider(this.cfg, this.logger);
@@ -71,24 +69,24 @@ public Annotation execute(PropertyBag ctx, byte[] data) throws AnnotatorExceptio
} catch (Exception e) {
this.logger.error("Error during SbomAnnotator execution: ", e);
}
-
+
final Annotation annotation = new Annotation(
- key,
- hash,
- host,
+ key,
+ hash,
+ host,
layer,
- kind,
- null,
- isSatisfied,
- Instant.now()
+ kind,
+ null,
+ isSatisfied,
+ ZonedDateTime.now()
);
final String annotationSignature = super.signAnnotation(
- this.signature.getPrivateKey(),
+ this.signature.getPrivateKey(),
annotation
);
annotation.setSignature(annotationSignature);
- return annotation;
+ return annotation;
}
}
diff --git a/src/main/java/com/alvarium/annotators/SourceAnnotator.java b/src/main/java/com/alvarium/annotators/SourceAnnotator.java
index 8011d73..d37ee4f 100644
--- a/src/main/java/com/alvarium/annotators/SourceAnnotator.java
+++ b/src/main/java/com/alvarium/annotators/SourceAnnotator.java
@@ -16,7 +16,7 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
-import java.time.Instant;
+import java.time.ZonedDateTime;
import org.apache.logging.log4j.Logger;
@@ -36,19 +36,16 @@ class SourceAnnotator extends AbstractAnnotator implements Annotator {
private final AnnotationType kind;
private final SignatureInfo signatureInfo;
private final LayerType layer;
-
+
protected SourceAnnotator(HashType hash, SignatureInfo signatureInfo, Logger logger, LayerType layer) {
super(logger);
this.hash = hash;
this.kind = AnnotationType.SOURCE;
this.signatureInfo = signatureInfo;
this.layer = layer;
- }
-
- public Annotation execute(PropertyBag ctx, byte[] data) throws AnnotatorException {
- // hash incoming data
- final String key = super.deriveHash(this.hash, data);
+ }
+ public Annotation execute(PropertyBag ctx, byte[] data, String key) throws AnnotatorException {
// get hostname if available
String host = "";
boolean isSatisfied;
@@ -56,17 +53,17 @@ public Annotation execute(PropertyBag ctx, byte[] data) throws AnnotatorExceptio
host = InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
isSatisfied = false;
- this.logger.error("Error during SourceAnnotator execution: ",e);
+ this.logger.error("Error during SourceAnnotator execution: ", e);
}
isSatisfied = true;
// create an annotation without signature
final Annotation annotation = new Annotation(key, this.hash, host, layer, this.kind, null, isSatisfied,
- Instant.now());
-
+ ZonedDateTime.now());
+
final String signature = super.signAnnotation(signatureInfo.getPrivateKey(), annotation);
annotation.setSignature(signature);
return annotation;
- }
+ }
}
diff --git a/src/main/java/com/alvarium/annotators/SourceCodeAnnotator.java b/src/main/java/com/alvarium/annotators/SourceCodeAnnotator.java
index 00f659b..cdaab87 100644
--- a/src/main/java/com/alvarium/annotators/SourceCodeAnnotator.java
+++ b/src/main/java/com/alvarium/annotators/SourceCodeAnnotator.java
@@ -24,11 +24,12 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.Collator;
-import java.time.Instant;
+import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
+
import org.apache.logging.log4j.Logger;
import com.alvarium.contracts.Annotation;
@@ -43,180 +44,182 @@
class SourceCodeAnnotator extends AbstractAnnotator implements Annotator {
- private final HashType hash;
- private final AnnotationType kind;
- private final SignatureInfo signature;
- private final LayerType layer;
-
- private HashProvider hashProvider;
-
- protected SourceCodeAnnotator(HashType hash, SignatureInfo signature, Logger logger, LayerType layer) {
- super(logger);
- this.hash = hash;
- this.kind = AnnotationType.SourceCode;
- this.signature = signature;
- this.layer = layer;
+ private final HashType hash;
+ private final AnnotationType kind;
+ private final SignatureInfo signature;
+ private final LayerType layer;
+
+ private HashProvider hashProvider;
+
+ protected SourceCodeAnnotator(HashType hash, SignatureInfo signature, Logger logger, LayerType layer) {
+ super(logger);
+ this.hash = hash;
+ this.kind = AnnotationType.SourceCode;
+ this.signature = signature;
+ this.layer = layer;
+ }
+
+ // File (git working directory) is to be passed in the ctx bag
+ // expects commitHash and directory from ctx
+ @Override
+ public Annotation execute(PropertyBag ctx, byte[] data, String key) throws AnnotatorException {
+ this.initHashProvider(this.hash);
+ final SourceCodeAnnotatorProps props = ctx.getProperty(
+ AnnotationType.SourceCode.name(),
+ SourceCodeAnnotatorProps.class
+ );
+
+ String host = "";
+ boolean isSatisfied;
+ try {
+ host = InetAddress.getLocalHost().getHostName();
+ final String checksum = this.readChecksum(props.getChecksumPath());
+ final String generatedChecksum = this.generateChecksum(props.getSourceCodePath());
+ isSatisfied = generatedChecksum.equals(checksum);
+ } catch (UnknownHostException | AnnotatorException e) {
+ isSatisfied = false;
+ this.logger.error("Error during SourceCodeAnnotator execution: ", e);
}
- // File (git working directory) is to be passed in the ctx bag
- // expects commitHash and directory from ctx
- @Override
- public Annotation execute(PropertyBag ctx, byte[] data) throws AnnotatorException {
- this.initHashProvider(this.hash);
- final String key = this.hashProvider.derive(data);
-
- final SourceCodeAnnotatorProps props = ctx.getProperty(
- AnnotationType.SourceCode.name(),
- SourceCodeAnnotatorProps.class
- );
-
- String host = "";
- boolean isSatisfied;
- try{
- host = InetAddress.getLocalHost().getHostName();
- final String checksum = this.readChecksum(props.getChecksumPath());
- final String generatedChecksum = this.generateChecksum(props.getSourceCodePath());
- isSatisfied = generatedChecksum.equals(checksum);
- } catch (UnknownHostException | AnnotatorException e) {
- isSatisfied = false;
- this.logger.error("Error during SourceCodeAnnotator execution: ",e);
- }
-
- final Annotation annotation = new Annotation(
- key,
- hash,
- host,
- layer,
- kind,
- null,
- isSatisfied,
- Instant.now());
-
- final String annotationSignature = super.signAnnotation(signature.getPrivateKey(), annotation);
- annotation.setSignature(annotationSignature);
- return annotation;
+ final Annotation annotation = new Annotation(
+ key,
+ hash,
+ host,
+ layer,
+ kind,
+ null,
+ isSatisfied,
+ ZonedDateTime.now());
+
+ final String annotationSignature = super.signAnnotation(signature.getPrivateKey(), annotation);
+ annotation.setSignature(annotationSignature);
+ return annotation;
+ }
+
+ private String readChecksum(String path) throws AnnotatorException {
+ try {
+ final Path p = Paths.get(path);
+ return Files.readString(p);
+ } catch (IOException e) {
+ throw new AnnotatorException("Failed to read file, could not validate checksum", e);
+ } catch (SecurityException e) {
+ throw new AnnotatorException(
+ "Insufficient permission to access file, could not validate checksum",
+ e
+ );
+ } catch (OutOfMemoryError e) {
+ throw new AnnotatorException(
+ "Failed to read file due to size larger than 2GB, could not validate checksum " + e
+ );
+ } catch (Exception e) {
+ throw new AnnotatorException("Could not validate checksum");
}
-
- private String readChecksum(String path) throws AnnotatorException {
- try {
- final Path p = Paths.get(path);
- return Files.readString(p);
- } catch (IOException e) {
- throw new AnnotatorException("Failed to read file, could not validate checksum", e);
- } catch (SecurityException e) {
- throw new AnnotatorException(
- "Insufficient permission to access file, could not validate checksum",
- e
- );
- } catch (OutOfMemoryError e) {
- throw new AnnotatorException(
- "Failed to read file due to size larger than 2GB, could not validate checksum " + e
- );
- } catch (Exception e) {
- throw new AnnotatorException("Could not validate checksum");
- }
+ }
+
+ /**
+ * Initializes the hash provider used to hash the source code
+ *
+ * @return HashProvider
+ * @throws AnnotatorException - If hashing algorithm not found,
+ * or if an unknown exception was thrown
+ */
+ private final void initHashProvider(HashType hashType) throws AnnotatorException {
+ try {
+ this.hashProvider = new HashProviderFactory().getProvider(hashType);
+ } catch (HashTypeException e) {
+ throw new AnnotatorException("Hashing algorithm not found, could not hash data or generate checksum", e);
+ } catch (Exception e) {
+ throw new AnnotatorException("Could not hash data or generate checksum", e);
}
-
- /**
- * Initializes the hash provider used to hash the source code
- * @return HashProvider
- * @throws AnnotatorException - If hashing algorithm not found,
- * or if an unknown exception was thrown
- */
- private final void initHashProvider(HashType hashType) throws AnnotatorException {
- try {
- this.hashProvider = new HashProviderFactory().getProvider(hashType);
- } catch (HashTypeException e) {
- throw new AnnotatorException("Hashing algorithm not found, could not hash data or generate checksum", e);
- } catch (Exception e) {
- throw new AnnotatorException("Could not hash data or generate checksum", e);
+ }
+
+ /**
+ * Recursively gets all files in a directory as a list of absolute paths
+ *
+ * @param path
+ * @return List of all files in directory
+ */
+ private List getAllFiles(String path) {
+ List files = new ArrayList<>();
+ File directory = new File(path);
+
+ if (directory.isDirectory()) {
+ File[] directoryFiles = directory.listFiles();
+ if (directoryFiles != null) {
+ for (File file : directoryFiles) {
+ if (file.isFile()) {
+ files.add(file.getAbsolutePath());
+ } else if (file.isDirectory()) {
+ files.addAll(getAllFiles(file.getAbsolutePath()));
+ }
}
+ }
+ } else if (directory.isFile()) {
+ files.add(directory.getAbsolutePath());
}
-
- /**
- * Recursively gets all files in a directory as a list of absolute paths
- * @param path
- * @return List of all files in directory
- */
- private List getAllFiles(String path) {
- List files = new ArrayList<>();
- File directory = new File(path);
-
- if (directory.isDirectory()) {
- File[] directoryFiles = directory.listFiles();
- if (directoryFiles != null) {
- for (File file : directoryFiles) {
- if (file.isFile()) {
- files.add(file.getAbsolutePath());
- } else if (file.isDirectory()) {
- files.addAll(getAllFiles(file.getAbsolutePath()));
- }
- }
- }
- } else if (directory.isFile()) {
- files.add(directory.getAbsolutePath());
+ return files;
+ }
+
+ /**
+ * Reads and hashes a file on the local file system in in chunks of 8KB
+ *
+ * @param filePath
+ * @return hash of the file's contents in string format
+ * @throws AnnotatorException - When bad file path or corrupted file given
+ */
+ private final String readAndHashFile(String filePath) throws AnnotatorException {
+ try {
+ FileInputStream fs = new FileInputStream(filePath);
+ final byte[] buffer = new byte[8192];
+ int bytesRead = 0;
+ while (true) {
+ bytesRead = fs.read(buffer);
+ if (bytesRead == -1) { // indicates EOF
+ break;
+ } else {
+ this.hashProvider.update(buffer, 0, bytesRead);
}
- return files;
+ }
+ fs.close();
+ } catch (OutOfMemoryError e) {
+ throw new AnnotatorException(
+ "Failed to read file due to size larger than 2GB, could not validate checksum" + e
+ );
+ } catch (IOException e) {
+ throw new AnnotatorException(
+ "Failed to read file contents, could not generate checksum",
+ e
+ );
+ } catch (SecurityException e) {
+ throw new AnnotatorException(
+ "Insufficient permission to access file, could not validate checksum",
+ e
+ );
+ } catch (Exception e) {
+ throw new AnnotatorException("Could not validate checksum", e);
}
-
- /**
- * Reads and hashes a file on the local file system in in chunks of 8KB
- * @param filePath
- * @return hash of the file's contents in string format
- * @throws AnnotatorException - When bad file path or corrupted file given
- */
- private final String readAndHashFile(String filePath) throws AnnotatorException {
- try {
- FileInputStream fs = new FileInputStream(filePath);
- final byte[] buffer = new byte[8192];
- int bytesRead = 0;
- while (true) {
- bytesRead = fs.read(buffer);
- if (bytesRead == -1) { // indicates EOF
- break;
- } else {
- this.hashProvider.update(buffer, 0, bytesRead);
- }
- }
- fs.close();
- } catch (OutOfMemoryError e) {
- throw new AnnotatorException(
- "Failed to read file due to size larger than 2GB, could not validate checksum" + e
- );
- } catch (IOException e) {
- throw new AnnotatorException(
- "Failed to read file contents, could not generate checksum",
- e
- );
- } catch (SecurityException e) {
- throw new AnnotatorException(
- "Insufficient permission to access file, could not validate checksum",
- e
- );
- } catch (Exception e) {
- throw new AnnotatorException("Could not validate checksum", e);
- }
- return this.hashProvider.getValue();
+ return this.hashProvider.getValue();
+ }
+
+ /**
+ * Computes the hash of all files hashes and their corresponding paths in the specified directory and returns the
+ * hash value as a string.
+ *
+ * @param path the path of the directory to hash
+ * @return the hash value of the directory as a string
+ * @throws AnnotatorException if an error occurs while hashing the directory
+ */
+ private String generateChecksum(String path) throws AnnotatorException {
+ List filePaths = getAllFiles(path);
+ for (int i = 0; i < filePaths.size(); i++) {
+ String hashThenPath = readAndHashFile(filePaths.get(i)) + " " + filePaths.get(i);
+ filePaths.set(i, hashThenPath);
}
+ Collections.sort(filePaths, Collator.getInstance(Locale.US));
- /**
- * Computes the hash of all files hashes and their corresponding paths in the specified directory and returns the
- * hash value as a string.
- * @param path the path of the directory to hash
- * @return the hash value of the directory as a string
- * @throws AnnotatorException if an error occurs while hashing the directory
- */
- private String generateChecksum(String path) throws AnnotatorException {
- List filePaths = getAllFiles(path);
- for(int i = 0 ; i vulnerabilities;
@@ -88,7 +80,7 @@ public Annotation execute(PropertyBag ctx, byte[] data) throws AnnotatorExceptio
this.kind,
null,
isSatisfied,
- Instant.now()
+ ZonedDateTime.now()
);
final String annotationSignature = super.signAnnotation(
diff --git a/src/main/java/com/alvarium/contracts/Annotation.java b/src/main/java/com/alvarium/contracts/Annotation.java
index 4991d29..b9d37f6 100644
--- a/src/main/java/com/alvarium/contracts/Annotation.java
+++ b/src/main/java/com/alvarium/contracts/Annotation.java
@@ -15,22 +15,20 @@
package com.alvarium.contracts;
-import java.io.Serializable;
-import java.time.Instant;
-
import com.alvarium.hash.HashType;
-import com.alvarium.serializers.InstantConverter;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-
+import com.alvarium.serializers.Serialization;
+import com.alvarium.utils.IDGenerator;
import de.huxhorn.sulky.ulid.ULID;
+import java.io.Serializable;
+import java.time.ZonedDateTime;
+
/**
* A java bean that encapsulates all of the data related to a specific annotation.
* this will be generated by the annotators.
*/
public class Annotation implements Serializable {
- private final String id;
+ private final String id;
private final String key;
private final HashType hash;
private final String host;
@@ -38,8 +36,8 @@ public class Annotation implements Serializable {
private final LayerType layer;
private final AnnotationType kind;
private String signature;
- private final Boolean isSatisfied;
- private final Instant timestamp;
+ private final boolean isSatisfied;
+ private final ZonedDateTime timestamp;
// TagEnvKey is an environment key used to associate annotations with specific metadata,
// aiding in the linkage of scores across different layers of the stack. For instance, in the "app" layer,
// it is utilized to retrieve the commit SHA of the workload where the application is running,
@@ -47,9 +45,8 @@ public class Annotation implements Serializable {
public static final String TAG_ENV_KEY = "TAG";
public Annotation(String key, HashType hash, String host, LayerType layer, AnnotationType kind, String signature,
- Boolean isSatisfied, Instant timestamp) {
- ULID ulid = new ULID();
- this.id = ulid.nextULID();
+ Boolean isSatisfied, ZonedDateTime timestamp) {
+ this.id = IDGenerator.generate();
this.key = key;
this.hash = hash;
this.host = host;
@@ -58,85 +55,84 @@ public Annotation(String key, HashType hash, String host, LayerType layer, Annot
this.kind = kind;
this.signature = signature;
this.isSatisfied = isSatisfied;
- this.timestamp = timestamp;
- }
-
- //setters
-
- public void setSignature(String signature) {
- this.signature = signature;
- }
-
- // getters
-
- public String getId() {
- return this.id;
- }
-
- public String getKey() {
- return this.key;
- }
-
- public HashType getHash() {
- return this.hash;
- }
-
- public String getHost() {
- return this.host;
- }
+ this.timestamp = timestamp;
- public String getTag() {
- return this.tag;
- }
-
- public LayerType getLayer() {
- return this.layer;
- }
-
- public AnnotationType getKind() {
- return this.kind;
- }
-
- public String getSignature() {
- return this.signature;
- }
+ }
- public Boolean getIsSatisfied() {
- return this.isSatisfied;
- }
+ //setters
- public Instant getTimestamp() {
- return this.timestamp;
- }
-
- /**
- * returns the JSON representation of the Annotation object
- * @return json string representation
- */
- public String toJson() {
- Gson gson = new GsonBuilder().registerTypeAdapter(Instant.class, new InstantConverter())
- .create();
- return gson.toJson(this, Annotation.class);
- }
-
- /**
- * instaniates an Annotation object from a json representation
- * @param json input JSON string
- * @return Annotation Object
- */
- public static Annotation fromJson(String json) {
- Gson gson = new GsonBuilder().registerTypeAdapter(Instant.class, new InstantConverter())
- .create();
- return gson.fromJson(json, Annotation.class);
- }
-
- private String getTagValue(LayerType layer) {
- switch(layer){
- case Application:
- return System.getenv(TAG_ENV_KEY) == null ? "" : System.getenv(TAG_ENV_KEY);
- default:
- break;
- }
- return "";
+ public void setSignature(String signature) {
+ this.signature = signature;
+ }
+
+ // getters
+
+ public String getId() {
+ return this.id;
+ }
+
+ public String getKey() {
+ return this.key;
+ }
+
+ public HashType getHash() {
+ return this.hash;
+ }
+
+ public String getHost() {
+ return this.host;
+ }
+
+ public String getTag() {
+ return this.tag;
+ }
+
+ public LayerType getLayer() {
+ return this.layer;
+ }
+
+ public AnnotationType getKind() {
+ return this.kind;
+ }
+
+ public String getSignature() {
+ return this.signature;
+ }
+
+ public Boolean getIsSatisfied() {
+ return this.isSatisfied;
+ }
+
+ public ZonedDateTime getTimestamp() {
+ return this.timestamp;
+ }
+
+ /**
+ * returns the JSON representation of the Annotation object
+ *
+ * @return json string representation
+ */
+ public String toJson() {
+ return Serialization.toJson(this);
+ }
+
+ /**
+ * instaniates an Annotation object from a json representation
+ *
+ * @param json input JSON string
+ * @return Annotation Object
+ */
+ public static Annotation fromJson(String json) {
+ return Serialization.annotationFromJson(json);
+ }
+
+ private String getTagValue(LayerType layer) {
+ switch (layer) {
+ case Application:
+ return System.getenv(TAG_ENV_KEY) == null ? "" : System.getenv(TAG_ENV_KEY);
+ default:
+ break;
}
+ return "";
+ }
}
diff --git a/src/main/java/com/alvarium/contracts/AnnotationList.java b/src/main/java/com/alvarium/contracts/AnnotationList.java
index 1f1618a..f9f3e2a 100644
--- a/src/main/java/com/alvarium/contracts/AnnotationList.java
+++ b/src/main/java/com/alvarium/contracts/AnnotationList.java
@@ -14,11 +14,9 @@
*******************************************************************************/
package com.alvarium.contracts;
-import java.util.List;
+import com.alvarium.serializers.Serialization;
-import com.alvarium.serializers.AnnotationConverter;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
+import java.util.List;
/**
@@ -30,7 +28,7 @@ public class AnnotationList {
public AnnotationList(Annotation[] annotations) {
this.items = List.of(annotations);
}
-
+
public AnnotationList(List annotations) {
this.items = annotations;
}
@@ -40,18 +38,10 @@ public List getAnnotations() {
}
public String toJson() {
- Gson gson = new GsonBuilder()
- .registerTypeAdapter(Annotation.class, new AnnotationConverter())
- .create();
-
- return gson.toJson(this);
+ return Serialization.toJson(this);
}
public static AnnotationList fromJson(String json) {
- Gson gson = new GsonBuilder()
- .registerTypeAdapter(Annotation.class, new AnnotationConverter())
- .create();
-
- return gson.fromJson(json, AnnotationList.class);
+ return Serialization.annotationListFromJson(json);
}
}
diff --git a/src/main/java/com/alvarium/serializers/AnnotationConverter.java b/src/main/java/com/alvarium/serializers/AnnotationConverter.java
index e957605..8468316 100644
--- a/src/main/java/com/alvarium/serializers/AnnotationConverter.java
+++ b/src/main/java/com/alvarium/serializers/AnnotationConverter.java
@@ -1,6 +1,5 @@
-
/*******************************************************************************
- * Copyright 2021 Dell Inc.
+ * Copyright 2023 Dell Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
@@ -14,24 +13,27 @@
*******************************************************************************/
package com.alvarium.serializers;
-import java.lang.reflect.Type;
-
import com.alvarium.contracts.Annotation;
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonDeserializer;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParser;
-import com.google.gson.JsonSerializationContext;
-import com.google.gson.JsonSerializer;
+import com.google.gson.*;
+import java.lang.reflect.Type;
-public class AnnotationConverter implements JsonSerializer, JsonDeserializer {
+public class AnnotationConverter implements JsonSerializer {
+ @Override
public JsonElement serialize(Annotation src, Type typeOfSrc, JsonSerializationContext context) {
- return JsonParser.parseString(src.toJson());
- }
+ var json = new JsonObject();
+
+ json.add("id", new JsonPrimitive(src.getId()));
+ json.add("type", new JsonPrimitive(src.getKind().name()));
+ json.add("tag", new JsonPrimitive(src.getTag()));
+ json.add("hash", new JsonPrimitive(src.getHash().name()));
+ json.add("host", new JsonPrimitive(src.getHost()));
+ json.add("layer", new JsonPrimitive(src.getLayer().name()));
+ json.add("signature", src.getSignature() == null ? null : new JsonPrimitive(src.getSignature()));
+ json.add("timestamp", context.serialize(src.getTimestamp()));
+ json.add("isSatisfied", new JsonPrimitive(src.getIsSatisfied()));
- public Annotation deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) {
- return Annotation.fromJson(json.toString());
+ return json;
}
}
diff --git a/src/main/java/com/alvarium/serializers/AnnotationListConverter.java b/src/main/java/com/alvarium/serializers/AnnotationListConverter.java
new file mode 100644
index 0000000..ad9bdc2
--- /dev/null
+++ b/src/main/java/com/alvarium/serializers/AnnotationListConverter.java
@@ -0,0 +1,15 @@
+package com.alvarium.serializers;
+
+import com.alvarium.contracts.AnnotationList;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonSerializationContext;
+import com.google.gson.JsonSerializer;
+
+import java.lang.reflect.Type;
+
+public class AnnotationListConverter implements JsonSerializer {
+ @Override
+ public JsonElement serialize(AnnotationList src, Type typeOfSrc, JsonSerializationContext context) {
+ return context.serialize(src.getAnnotations());
+ }
+}
diff --git a/src/main/java/com/alvarium/serializers/InstantConverter.java b/src/main/java/com/alvarium/serializers/InstantConverter.java
deleted file mode 100644
index 614210a..0000000
--- a/src/main/java/com/alvarium/serializers/InstantConverter.java
+++ /dev/null
@@ -1,53 +0,0 @@
-
-/*******************************************************************************
- * Copyright 2021 Dell Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- *******************************************************************************/
-package com.alvarium.serializers;
-
-import java.lang.reflect.Type;
-import java.time.Instant;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.time.format.DateTimeFormatter;
-
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonDeserializer;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParseException;
-import com.google.gson.JsonPrimitive;
-import com.google.gson.JsonSerializationContext;
-import com.google.gson.JsonSerializer;
-
-/**
- * A converter of Instant datatype to RFC3339 string representation and vice versa
- */
-public class InstantConverter implements JsonSerializer, JsonDeserializer{
-
- public JsonElement serialize(Instant src, Type typeOfSrc, JsonSerializationContext context) {
- // a workaround to preserve the zone information
- DateTimeFormatter f = DateTimeFormatter.ISO_INSTANT.withZone(ZoneId.systemDefault());
- ZonedDateTime zdt = ZonedDateTime.parse(DateTimeFormatter.ISO_INSTANT.format(src), f);
- String raw = zdt.toString();
-
- if (raw.indexOf('[') > 0) {
- return new JsonPrimitive(zdt.toString().substring(0, raw.indexOf('[')));
- }
- return new JsonPrimitive(raw);
- }
-
- @Override
- public Instant deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
- throws JsonParseException {
- return DateTimeFormatter.ISO_ZONED_DATE_TIME.parse(json.getAsString(), Instant::from);
- }
-}
diff --git a/src/main/java/com/alvarium/serializers/PublishWrapperConverter.java b/src/main/java/com/alvarium/serializers/PublishWrapperConverter.java
new file mode 100644
index 0000000..cc44981
--- /dev/null
+++ b/src/main/java/com/alvarium/serializers/PublishWrapperConverter.java
@@ -0,0 +1,23 @@
+package com.alvarium.serializers;
+
+import com.alvarium.PublishWrapper;
+import com.google.gson.*;
+
+import java.lang.reflect.Type;
+import java.util.Base64;
+
+public class PublishWrapperConverter implements JsonSerializer {
+
+
+ @Override
+ public JsonElement serialize(PublishWrapper src, Type typeOfSrc, JsonSerializationContext context) {
+ var json = new JsonObject();
+ json.add("action", new JsonPrimitive(src.getAction().name()));
+ json.add("type", new JsonPrimitive(src.getMessageType()));
+
+ String contentJsonString = context.serialize(src.getContent()).toString();
+
+ json.add("content", new JsonPrimitive(Base64.getEncoder().encodeToString(contentJsonString.getBytes())));
+ return json;
+ }
+}
diff --git a/src/main/java/com/alvarium/serializers/Serialization.java b/src/main/java/com/alvarium/serializers/Serialization.java
new file mode 100644
index 0000000..3516735
--- /dev/null
+++ b/src/main/java/com/alvarium/serializers/Serialization.java
@@ -0,0 +1,43 @@
+package com.alvarium.serializers;
+
+import com.alvarium.PublishWrapper;
+import com.alvarium.contracts.Annotation;
+import com.alvarium.contracts.AnnotationList;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import java.time.ZonedDateTime;
+
+public class Serialization {
+
+
+ private static final Gson GSON = new GsonBuilder()
+ .registerTypeAdapter(PublishWrapper.class, new PublishWrapperConverter())
+ .registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeConverter())
+ .registerTypeAdapter(Annotation.class, new AnnotationConverter())
+ .registerTypeAdapter(AnnotationList.class, new AnnotationListConverter())
+ .disableHtmlEscaping()
+ .create();
+
+ public static String toJson(PublishWrapper wrapper) {
+ return GSON.toJson(wrapper);
+ }
+
+ public static String toJson(Annotation annotation) {
+ return GSON.toJson(annotation);
+ }
+
+ public static String toJson(AnnotationList list) {
+ return GSON.toJson(list);
+ }
+
+
+ public static Annotation annotationFromJson(String jsonAnnotation) {
+ return GSON.fromJson(jsonAnnotation, Annotation.class);
+ }
+
+ public static AnnotationList annotationListFromJson(String jsonAnnotation) {
+ return GSON.fromJson(jsonAnnotation, AnnotationList.class);
+ }
+
+}
diff --git a/src/main/java/com/alvarium/serializers/ZonedDateTimeConverter.java b/src/main/java/com/alvarium/serializers/ZonedDateTimeConverter.java
new file mode 100644
index 0000000..bd1ce69
--- /dev/null
+++ b/src/main/java/com/alvarium/serializers/ZonedDateTimeConverter.java
@@ -0,0 +1,38 @@
+
+/*******************************************************************************
+ * Copyright 2021 Dell Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ *******************************************************************************/
+package com.alvarium.serializers;
+
+import com.google.gson.*;
+
+import java.lang.reflect.Type;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * A converter of Instant datatype to RFC3339 string representation and vice versa
+ */
+public class ZonedDateTimeConverter implements JsonSerializer, JsonDeserializer {
+
+
+ public JsonElement serialize(ZonedDateTime src, Type typeOfSrc, JsonSerializationContext context) {
+ DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME.withZone(src.getZone());
+ return new JsonPrimitive(formatter.format(src));
+ }
+
+ @Override
+ public ZonedDateTime deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException {
+ return DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(json.getAsString(), ZonedDateTime::from);
+ }
+}
diff --git a/src/main/java/com/alvarium/utils/IDGenerator.java b/src/main/java/com/alvarium/utils/IDGenerator.java
new file mode 100644
index 0000000..a36cbe1
--- /dev/null
+++ b/src/main/java/com/alvarium/utils/IDGenerator.java
@@ -0,0 +1,15 @@
+package com.alvarium.utils;
+
+import de.huxhorn.sulky.ulid.ULID;
+
+public class IDGenerator {
+
+ private IDGenerator() {}
+
+ private static final ULID ULID = new ULID();
+
+ public static String generate() {
+ return ULID.nextULID();
+ }
+
+}
diff --git a/src/test/java/com/alvarium/PublishWrapperTest.java b/src/test/java/com/alvarium/PublishWrapperTest.java
index 441bf89..606fed7 100644
--- a/src/test/java/com/alvarium/PublishWrapperTest.java
+++ b/src/test/java/com/alvarium/PublishWrapperTest.java
@@ -15,6 +15,7 @@
package com.alvarium;
import java.time.Instant;
+import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -51,7 +52,7 @@ public void toJsonShouldParseAnnotationCorrectly() {
AnnotationType.TPM,
"signature",
true,
- Instant.now()
+ ZonedDateTime.now()
);
final List annotations = List.of(annotation, annotation);
final PublishWrapper wrapper = new PublishWrapper(
diff --git a/src/test/java/com/alvarium/SdkTest.java b/src/test/java/com/alvarium/SdkTest.java
index d6c84a7..4c21f8f 100644
--- a/src/test/java/com/alvarium/SdkTest.java
+++ b/src/test/java/com/alvarium/SdkTest.java
@@ -20,6 +20,7 @@
import java.nio.file.Paths;
import java.util.HashMap;
+import com.alvarium.hash.HashTypeException;
import com.alvarium.utils.PropertyBag;
import com.alvarium.annotators.Annotator;
import com.alvarium.annotators.AnnotatorException;
@@ -56,7 +57,7 @@ public void publish(byte[] data) {
}
public void close() {
System.out.println("Connections closed");
- }
+ }
}
public class SdkTest {
private final String testJson;
@@ -71,7 +72,7 @@ public void instantiateSdkShouldNotThrow() throws AnnotatorException, StreamExce
final SdkInfo sdkInfo = SdkInfo.fromJson(this.testJson);
// init annotators
- final Annotator[] annotators = new Annotator[sdkInfo.getAnnotators().length];
+ final Annotator[] annotators = new Annotator[sdkInfo.getAnnotators().length];
final AnnotatorFactory annotatorFactory = new AnnotatorFactory();
// init logger
@@ -87,7 +88,7 @@ public void instantiateSdkShouldNotThrow() throws AnnotatorException, StreamExce
}
@Test
- public void createShouldReturnSameData() throws AnnotatorException, StreamException {
+ public void createShouldReturnSameData() throws AnnotatorException, StreamException, HashTypeException {
final Sdk sdk = new MockSdk();
byte[] oldData = {0xA, 0x1};
byte[] newData = {0x1, 0xA};
@@ -97,7 +98,7 @@ public void createShouldReturnSameData() throws AnnotatorException, StreamExcept
}
@Test
- public void defaultSdkShouldCreateAnnotations() throws AnnotatorException, StreamException {
+ public void defaultSdkShouldCreateAnnotations() throws AnnotatorException, StreamException, HashTypeException {
final SdkInfo sdkInfo = SdkInfo.fromJson(this.testJson);
// init annotators
@@ -109,7 +110,7 @@ public void defaultSdkShouldCreateAnnotations() throws AnnotatorException, Strea
Configurator.setRootLevel(Level.DEBUG);
for (int i = 0; i < annotators.length; i++) {
- annotators[i] = annotatorFactory.getAnnotator(sdkInfo.getAnnotators()[i], sdkInfo, logger);
+ annotators[i] = annotatorFactory.getAnnotator(sdkInfo.getAnnotators()[i], sdkInfo, logger);
}
final Sdk sdk = new DefaultSdk(annotators, sdkInfo, logger);
@@ -122,19 +123,19 @@ public void defaultSdkShouldCreateAnnotations() throws AnnotatorException, Strea
@Test
public void defaultSdkShouldCreateTransitionAnnotations() throws AnnotatorException,
- StreamException {
+ StreamException, HashTypeException {
final SdkInfo sdkInfo = SdkInfo.fromJson(this.testJson);
// init annotators
final Annotator[] annotators = new Annotator[sdkInfo.getAnnotators().length];
final AnnotatorFactory annotatorFactory = new AnnotatorFactory();
-
+
// init logger
final Logger logger = LogManager.getRootLogger();
Configurator.setRootLevel(Level.DEBUG);
for (int i = 0; i < annotators.length; i++) {
- annotators[i] = annotatorFactory.getAnnotator(sdkInfo.getAnnotators()[i], sdkInfo, logger);
+ annotators[i] = annotatorFactory.getAnnotator(sdkInfo.getAnnotators()[i], sdkInfo, logger);
}
final Sdk sdk = new DefaultSdk(annotators, sdkInfo, logger);
@@ -146,7 +147,7 @@ public void defaultSdkShouldCreateTransitionAnnotations() throws AnnotatorExcept
}
@Test
- public void defaultSdkShouldMutateData() throws AnnotatorException, StreamException {
+ public void defaultSdkShouldMutateData() throws AnnotatorException, StreamException, HashTypeException {
final SdkInfo sdkInfo = SdkInfo.fromJson(this.testJson);
// init annotators
@@ -158,7 +159,7 @@ public void defaultSdkShouldMutateData() throws AnnotatorException, StreamExcept
Configurator.setRootLevel(Level.DEBUG);
for (int i = 0; i < annotators.length; i++) {
- annotators[i] = annotatorFactory.getAnnotator(sdkInfo.getAnnotators()[i], sdkInfo, logger);
+ annotators[i] = annotatorFactory.getAnnotator(sdkInfo.getAnnotators()[i], sdkInfo, logger);
}
final Sdk sdk = new DefaultSdk(annotators, sdkInfo, logger);
@@ -173,7 +174,7 @@ public void defaultSdkShouldMutateData() throws AnnotatorException, StreamExcept
@Test
public void defaultSdkShouldCreatePublishedAnnotations() throws AnnotatorException,
- StreamException {
+ StreamException, HashTypeException {
final SdkInfo sdkInfo = SdkInfo.fromJson(this.testJson);
// init annotators
@@ -185,7 +186,7 @@ public void defaultSdkShouldCreatePublishedAnnotations() throws AnnotatorExcepti
Configurator.setRootLevel(Level.DEBUG);
for (int i = 0; i < annotators.length; i++) {
- annotators[i] = annotatorFactory.getAnnotator(sdkInfo.getAnnotators()[i], sdkInfo, logger);
+ annotators[i] = annotatorFactory.getAnnotator(sdkInfo.getAnnotators()[i], sdkInfo, logger);
}
final Sdk sdk = new DefaultSdk(annotators, sdkInfo, logger);
diff --git a/src/test/java/com/alvarium/annotators/AnnotatorTest.java b/src/test/java/com/alvarium/annotators/AnnotatorTest.java
index 3a36430..dfe3470 100644
--- a/src/test/java/com/alvarium/annotators/AnnotatorTest.java
+++ b/src/test/java/com/alvarium/annotators/AnnotatorTest.java
@@ -87,8 +87,8 @@ public void mockAnnotatorShouldReturnSatisfiedAnnotation() throws AnnotatorExcep
final byte[] data = "test data".getBytes();
final PropertyBag ctx = new ImmutablePropertyBag(new HashMap<>());
- final Annotation satisfiedAnnotation = satisfiedAnnotator.execute(ctx, data);
- final Annotation unsatisfiedAnnotation = unsatisfiedAnnotator.execute(ctx, data);
+ final Annotation satisfiedAnnotation = satisfiedAnnotator.execute(ctx, data, "");
+ final Annotation unsatisfiedAnnotation = unsatisfiedAnnotator.execute(ctx, data, "");
assert satisfiedAnnotation.getIsSatisfied();
assert !unsatisfiedAnnotation.getIsSatisfied();
@@ -120,7 +120,7 @@ public void mockAnnotatorShouldReturnTag() throws AnnotatorException {
final byte[] data = "test data".getBytes();
final PropertyBag ctx = new ImmutablePropertyBag(new HashMap<>());
- final Annotation noHashAnnotation = noHashAnnotator.execute(ctx, data);
+ final Annotation noHashAnnotation = noHashAnnotator.execute(ctx, data, "");
assert "".equals(noHashAnnotation.getTag());
}
@@ -151,7 +151,7 @@ public void mockAnnotatorShouldReturnLayer() throws AnnotatorException {
final byte[] data = "test data".getBytes();
final PropertyBag ctx = new ImmutablePropertyBag(new HashMap<>());
- final Annotation noHashAnnotation = noHashAnnotator.execute(ctx, data);
+ final Annotation noHashAnnotation = noHashAnnotator.execute(ctx, data, "");
assert LayerType.Application.equals(noHashAnnotation.getLayer());
}
diff --git a/src/test/java/com/alvarium/annotators/ChecksumAnnotatorTest.java b/src/test/java/com/alvarium/annotators/ChecksumAnnotatorTest.java
index 576ad8b..875c034 100644
--- a/src/test/java/com/alvarium/annotators/ChecksumAnnotatorTest.java
+++ b/src/test/java/com/alvarium/annotators/ChecksumAnnotatorTest.java
@@ -102,14 +102,14 @@ public void executeShouldReturnAnnotation() throws AnnotatorException, HashTypeE
);
byte[] data = "pipeline1/1".getBytes();
- Annotation annotation = annotator.execute(ctx, data);
+ Annotation annotation = annotator.execute(ctx, data, "");
System.out.println(annotation.toJson());
assert annotation.getIsSatisfied();
// change artifact checksum
Files.write(checksumFile.toPath(), "bar".getBytes());
- annotation = annotator.execute(ctx, data);
+ annotation = annotator.execute(ctx, data, "");
System.out.println(annotation.toJson());
assert !annotation.getIsSatisfied();
diff --git a/src/test/java/com/alvarium/annotators/PkiAnnotatorTest.java b/src/test/java/com/alvarium/annotators/PkiAnnotatorTest.java
index 0fe642d..15a6d3e 100644
--- a/src/test/java/com/alvarium/annotators/PkiAnnotatorTest.java
+++ b/src/test/java/com/alvarium/annotators/PkiAnnotatorTest.java
@@ -69,7 +69,7 @@ public void executeShouldGetSatisfiedAnnotation() throws AnnotatorException {
final AnnotatorConfig[] annotators = {pkiCfg};
final SdkInfo config = new SdkInfo(annotators, new HashInfo(HashType.SHA256Hash), sigInfo, null, LayerType.Application);
final Annotator annotator = annotatorFactory.getAnnotator(pkiCfg, config, logger);
- final Annotation annotation = annotator.execute(ctx, data);
+ final Annotation annotation = annotator.execute(ctx, data, "");
assertTrue("isSatisfied should be true", annotation.getIsSatisfied());
}
@@ -99,7 +99,7 @@ public void executeShouldGetUnsatisfiedAnnotation() throws AnnotatorException {
final SdkInfo config = new SdkInfo(annotators, new HashInfo(HashType.SHA256Hash), sigInfo, null, LayerType.Application);
final Annotator annotator = annotatorFactory.getAnnotator(pkiCfg, config, logger);
- final Annotation annotation = annotator.execute(ctx, data);
+ final Annotation annotation = annotator.execute(ctx, data, "");
assertFalse("isSatisfied should be false", annotation.getIsSatisfied());
}
diff --git a/src/test/java/com/alvarium/annotators/PkiHttpAnnotatorTest.java b/src/test/java/com/alvarium/annotators/PkiHttpAnnotatorTest.java
index 5c7eff6..7339ee0 100644
--- a/src/test/java/com/alvarium/annotators/PkiHttpAnnotatorTest.java
+++ b/src/test/java/com/alvarium/annotators/PkiHttpAnnotatorTest.java
@@ -99,7 +99,7 @@ public void testAnnotationOK() throws AnnotatorException, RequestHandlerExceptio
final AnnotatorConfig[] annotators = {annotatorInfo};
final SdkInfo config = new SdkInfo(annotators, new HashInfo(HashType.SHA256Hash), sigInfo, null, LayerType.Application);
final Annotator annotator = annotatorFactory.getAnnotator(annotatorInfo, config, logger);
- final Annotation annotation = annotator.execute(ctx, data);
+ final Annotation annotation = annotator.execute(ctx, data, "");
assertTrue("isSatisfied should be true", annotation.getIsSatisfied());
}
@@ -131,7 +131,7 @@ public void testInvalidKeyType() throws AnnotatorException, RequestHandlerExcept
final AnnotatorConfig[] annotators = {annotatorInfo};
final SdkInfo config = new SdkInfo(annotators, new HashInfo(HashType.SHA256Hash), sigInfo, null, LayerType.Application);
final Annotator annotator = annotatorFactory.getAnnotator(annotatorInfo, config, logger);
- annotator.execute(ctx, data);
+ annotator.execute(ctx, data, "");
}
@Test
@@ -160,7 +160,7 @@ public void testKeyNotFound() throws AnnotatorException, RequestHandlerException
final AnnotatorConfig[] annotators = {annotatorInfo};
final SdkInfo config = new SdkInfo(annotators, new HashInfo(HashType.SHA256Hash), sigInfo, null, LayerType.Application);
final Annotator annotator = annotatorFactory.getAnnotator(annotatorInfo, config, logger);
- Annotation annotation = annotator.execute(ctx, data);
+ Annotation annotation = annotator.execute(ctx, data, "");
assertFalse("isSatisfied should be false", annotation.getIsSatisfied());
}
@@ -188,7 +188,7 @@ public void testEmptySignature() throws AnnotatorException, RequestHandlerExcept
final AnnotatorConfig[] annotators = {annotatorInfo};
final SdkInfo config = new SdkInfo(annotators, new HashInfo(HashType.SHA256Hash), sigInfo, null, LayerType.Application);
final Annotator annotator = annotatorFactory.getAnnotator(annotatorInfo, config, logger);
- final Annotation annotation = annotator.execute(ctx, data);
+ final Annotation annotation = annotator.execute(ctx, data, "");
assertFalse("isSatisfied should be false", annotation.getIsSatisfied());
}
@@ -216,7 +216,7 @@ public void testInvalidSignature() throws AnnotatorException, RequestHandlerExce
final AnnotatorConfig[] annotators = {annotatorInfo};
final SdkInfo config = new SdkInfo(annotators, new HashInfo(HashType.SHA256Hash), sigInfo, null, LayerType.Application);
final Annotator annotator = annotatorFactory.getAnnotator(annotatorInfo, config, logger);
- final Annotation annotation = annotator.execute(ctx, data);
+ final Annotation annotation = annotator.execute(ctx, data, "");
assertFalse("isSatisfied should be false", annotation.getIsSatisfied());
}
diff --git a/src/test/java/com/alvarium/annotators/SbomAnnotatorTest.java b/src/test/java/com/alvarium/annotators/SbomAnnotatorTest.java
index 8812615..2f2a6bd 100644
--- a/src/test/java/com/alvarium/annotators/SbomAnnotatorTest.java
+++ b/src/test/java/com/alvarium/annotators/SbomAnnotatorTest.java
@@ -52,7 +52,7 @@ public void executeShouldReturnSatisfiedAnnotation() throws Exception {
"./src/test/java/com/alvarium/annotators/sbom/spdx-valid.json"
);
final PropertyBag ctx = new ImmutablePropertyBag(map);
- final Annotation annotation = annotator.execute(ctx, data);
+ final Annotation annotation = annotator.execute(ctx, data, "");
assert annotation.getIsSatisfied();
}
@@ -67,7 +67,7 @@ public void executeShouldReturnUnsatisfiedAnnotation() throws Exception {
"./src/test/java/com/alvarium/annotators/sbom/spdx-valid.json"
);
final PropertyBag ctx = new ImmutablePropertyBag(map);
- final Annotation annotation = annotator.execute(ctx, data);
+ final Annotation annotation = annotator.execute(ctx, data, "");
assert !annotation.getIsSatisfied();
}
diff --git a/src/test/java/com/alvarium/annotators/SourceAnnotatorTest.java b/src/test/java/com/alvarium/annotators/SourceAnnotatorTest.java
index 20dbb88..f6fb664 100644
--- a/src/test/java/com/alvarium/annotators/SourceAnnotatorTest.java
+++ b/src/test/java/com/alvarium/annotators/SourceAnnotatorTest.java
@@ -70,7 +70,7 @@ public void executeShouldReturnAnnotation() throws AnnotatorException, IOExcepti
final byte[] data = "test data".getBytes();
final PropertyBag ctx = new ImmutablePropertyBag(new HashMap());
- final Annotation annotation = annotator.execute(ctx, data);
+ final Annotation annotation = annotator.execute(ctx, data, "");
System.out.println(annotation.toJson());
}
diff --git a/src/test/java/com/alvarium/annotators/SourceCodeAnnotatorTest.java b/src/test/java/com/alvarium/annotators/SourceCodeAnnotatorTest.java
index 767be8b..298ddb9 100644
--- a/src/test/java/com/alvarium/annotators/SourceCodeAnnotatorTest.java
+++ b/src/test/java/com/alvarium/annotators/SourceCodeAnnotatorTest.java
@@ -110,14 +110,14 @@ public void executeShouldReturnAnnotation() throws AnnotatorException, IOExcepti
byte[] data = "pipeline1/1".getBytes();
- Annotation annotation = annotator.execute(ctx, data);
+ Annotation annotation = annotator.execute(ctx, data, "");
System.out.println(annotation.toJson());
assert annotation.getIsSatisfied();
// tamper with existing file in source code
Files.write(f1.toPath(), "tampered".getBytes());
- annotation = annotator.execute(ctx, data);
+ annotation = annotator.execute(ctx, data, "");
System.out.println(annotation.toJson());
assert !annotation.getIsSatisfied();
diff --git a/src/test/java/com/alvarium/annotators/TlsAnnotatorTest.java b/src/test/java/com/alvarium/annotators/TlsAnnotatorTest.java
index 1a6cd3a..e286416 100644
--- a/src/test/java/com/alvarium/annotators/TlsAnnotatorTest.java
+++ b/src/test/java/com/alvarium/annotators/TlsAnnotatorTest.java
@@ -80,7 +80,7 @@ public void executeShouldReturnAnnotation() throws AnnotatorException, IOExcepti
map.put(AnnotationType.TLS.name(), socket);
final PropertyBag bag = new ImmutablePropertyBag(map);
- final Annotation annotation = annotator.execute(bag, data);
+ final Annotation annotation = annotator.execute(bag, data, "");
System.out.println(annotation.toJson());
}
}
diff --git a/src/test/java/com/alvarium/annotators/TpmAnnotatorTest.java b/src/test/java/com/alvarium/annotators/TpmAnnotatorTest.java
index 7b99ca3..bd9dd96 100644
--- a/src/test/java/com/alvarium/annotators/TpmAnnotatorTest.java
+++ b/src/test/java/com/alvarium/annotators/TpmAnnotatorTest.java
@@ -68,7 +68,7 @@ public void executeShouldCreateAnnotation() throws AnnotatorException {
PropertyBag ctx = new ImmutablePropertyBag(new HashMap());
byte[] data = {0x1, 0x2};
- Annotation annotation = tpm.execute(ctx, data);
+ Annotation annotation = tpm.execute(ctx, data, "");
System.out.println(annotation.toJson());
}
diff --git a/src/test/java/com/alvarium/annotators/VulnerabilityAnnotatorTest.java b/src/test/java/com/alvarium/annotators/VulnerabilityAnnotatorTest.java
index cf216f5..4929fd5 100644
--- a/src/test/java/com/alvarium/annotators/VulnerabilityAnnotatorTest.java
+++ b/src/test/java/com/alvarium/annotators/VulnerabilityAnnotatorTest.java
@@ -90,7 +90,7 @@ public void executeShouldReturnAnnotation() throws AnnotatorException, IOExcepti
map.put(AnnotationType.VULNERABILITY.name(), pomXmlFile.toPath().getParent().toString());
final PropertyBag ctx = new ImmutablePropertyBag(map);
- final Annotation annotation = annotator.execute(ctx, data);
+ final Annotation annotation = annotator.execute(ctx, data, "");
assert !annotation.getIsSatisfied();
}
@@ -139,7 +139,7 @@ public void executeShouldReturnSatisfiedAnnotation() throws AnnotatorException,
map.put(AnnotationType.VULNERABILITY.name(), pomXmlFile.toPath().getParent().toString());
final PropertyBag ctx = new ImmutablePropertyBag(map);
- final Annotation annotation = annotator.execute(ctx, data);
+ final Annotation annotation = annotator.execute(ctx, data, "");
assert annotation.getIsSatisfied();
}
diff --git a/src/test/java/com/alvarium/contracts/AnnotationListTest.java b/src/test/java/com/alvarium/contracts/AnnotationListTest.java
index 2a11159..6668c73 100644
--- a/src/test/java/com/alvarium/contracts/AnnotationListTest.java
+++ b/src/test/java/com/alvarium/contracts/AnnotationListTest.java
@@ -19,12 +19,15 @@
import java.io.IOException;
import java.time.Instant;
+import java.time.ZonedDateTime;
import java.util.List;
import com.alvarium.hash.HashType;
+import org.junit.Ignore;
import org.junit.Test;
+@Ignore
public class AnnotationListTest {
@Test
@@ -37,7 +40,7 @@ public void toJsonShouldParseCorrectly() {
AnnotationType.MOCK,
"signature",
true,
- Instant.now()
+ ZonedDateTime.now()
);
final AnnotationList annotations = new AnnotationList(List.of(annotation, annotation));
System.out.println(annotations.toJson());
diff --git a/src/test/java/com/alvarium/contracts/AnnotationTest.java b/src/test/java/com/alvarium/contracts/AnnotationTest.java
index b079072..6de01b5 100644
--- a/src/test/java/com/alvarium/contracts/AnnotationTest.java
+++ b/src/test/java/com/alvarium/contracts/AnnotationTest.java
@@ -20,7 +20,7 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
-import java.time.Instant;
+import java.time.*;
import java.time.format.DateTimeFormatter;
import com.alvarium.hash.HashType;
@@ -28,38 +28,37 @@
import org.junit.Test;
public class AnnotationTest {
- private final String testJson;
- private final Instant testTimestamp;
- private final String testId;
+ private final String testJson;
+ private final ZonedDateTime testTimestamp;
+ private final String testId;
- public AnnotationTest() throws IOException{
- String path = "./src/test/java/com/alvarium/contracts/data.json";
- testJson = Files.readString(Paths.get(path), StandardCharsets.US_ASCII);
+ public AnnotationTest() throws IOException {
+ String path = "./src/test/java/com/alvarium/contracts/data.json";
+ testJson = Files.readString(Paths.get(path), StandardCharsets.US_ASCII);
- testId = "01FE0RFFJY94R1ER2AM9BG63E2";
- testTimestamp = DateTimeFormatter.ISO_ZONED_DATE_TIME
- .parse("2021-08-24T12:22:33.334070489-05:00", Instant::from);
- }
+ testId = "01FE0RFFJY94R1ER2AM9BG63E2";
+ testTimestamp = DateTimeFormatter.ISO_ZONED_DATE_TIME
+ .parse("2021-08-24T12:22:33.334070489-05:00", ZonedDateTime::from);
+ }
- @Test
- public void toJsonShouldReturnTheRightRepresentation() {
- Annotation annotation = new Annotation("key", HashType.MD5Hash, "host", LayerType.Application, AnnotationType.TPM,
- "signature", true, testTimestamp);
- String result = annotation.toJson();
- System.out.println(result);
- }
-
- @Test
- public void fromJsonShouldReturnAnObjectWithTheRightProps() {
+ @Test
+ public void toJsonShouldReturnTheRightRepresentation() {
+ Annotation annotation = new Annotation("key", HashType.MD5Hash, "host", LayerType.Application, AnnotationType.TPM,
+ "signature", true, testTimestamp);
+ String result = annotation.toJson();
+ System.out.println(result);
+ }
- Annotation annotation = Annotation.fromJson(this.testJson);
- assertEquals(this.testId, annotation.getId());
- assertEquals("320", annotation.getKey());
- assertEquals(HashType.MD5Hash, annotation.getHash());
- assertEquals("host", annotation.getHost());
- assertEquals(AnnotationType.TPM, annotation.getKind());
- assertEquals("test sign", annotation.getSignature());
- assertEquals(true, annotation.getIsSatisfied());
- assertEquals(testTimestamp, annotation.getTimestamp());
- }
+ @Test
+ public void fromJsonShouldReturnAnObjectWithTheRightProps() {
+ Annotation annotation = Annotation.fromJson(this.testJson);
+ assertEquals(this.testId, annotation.getId());
+ assertEquals("320", annotation.getKey());
+ assertEquals(HashType.MD5Hash, annotation.getHash());
+ assertEquals("host", annotation.getHost());
+ assertEquals(AnnotationType.TPM, annotation.getKind());
+ assertEquals("test sign", annotation.getSignature());
+ assertEquals(true, annotation.getIsSatisfied());
+ assertEquals(testTimestamp, annotation.getTimestamp());
+ }
}