Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 23 additions & 16 deletions src/main/java/io/naftiko/spec/NaftikoSpec.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,32 +15,39 @@

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicReference;

import com.fasterxml.jackson.annotation.JsonInclude;

import io.naftiko.spec.consumes.ClientSpec;
import io.naftiko.spec.util.BindingSpec;

/**
* Naftiko Specification Root, including version and capabilities
* Naftiko Specification Root, including version and capabilities.
*
* <h2>Thread safety</h2>
* Each scalar field is held in an {@link AtomicReference} so that fluent builders and
* Control-port runtime edits can replace values atomically while engine threads read them.
* The {@code binds} and {@code consumes} collections are {@link CopyOnWriteArrayList}s.
* This satisfies SonarQube rule {@code java:S3077}.
*/
public class NaftikoSpec {

private volatile String naftiko;

private volatile InfoSpec info;
private final AtomicReference<String> naftiko = new AtomicReference<>();
private final AtomicReference<InfoSpec> info = new AtomicReference<>();
private final AtomicReference<CapabilitySpec> capability = new AtomicReference<>();

@JsonInclude(JsonInclude.Include.NON_EMPTY)
private final List<BindingSpec> binds;

private volatile CapabilitySpec capability;

@JsonInclude(JsonInclude.Include.NON_EMPTY)
private final List<ClientSpec> consumes;

public NaftikoSpec(String naftiko, InfoSpec info, CapabilitySpec capability) {
this.naftiko = naftiko;
this.info = info;
this.naftiko.set(naftiko);
this.info.set(info);
this.binds = new CopyOnWriteArrayList<>();
this.capability = capability;
this.capability.set(capability);
this.consumes = new CopyOnWriteArrayList<>();
}

Expand All @@ -49,33 +56,33 @@ public NaftikoSpec() {
}

public String getNaftiko() {
return naftiko;
return naftiko.get();
}

public void setNaftiko(String naftiko) {
this.naftiko = naftiko;
this.naftiko.set(naftiko);
}

public InfoSpec getInfo() {
return info;
return info.get();
}

public void setInfo(InfoSpec info) {
this.info = info;
this.info.set(info);
}

public List<BindingSpec> getBinds() {
return binds;
}

public CapabilitySpec getCapability() {
return capability;
return capability.get();
}

public void setCapability(CapabilitySpec capability) {
this.capability = capability;
this.capability.set(capability);
}

public List<ClientSpec> getConsumes() {
return consumes;
}
Expand Down
76 changes: 42 additions & 34 deletions src/main/java/io/naftiko/spec/OperationSpec.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,39 @@

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicReference;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;

/**
* Operation Specification Element
* Operation Specification Element.
*
* <h2>Thread safety</h2>
* Each scalar field is held in an {@link AtomicReference} so that fluent builders and
* Control-port runtime edits can replace values atomically while engine threads read them.
* The {@code inputParameters} and {@code outputParameters} lists are {@link CopyOnWriteArrayList}s.
* This satisfies SonarQube rule {@code java:S3077}.
*/
public class OperationSpec {

@JsonIgnore
private volatile ResourceSpec parentResource;
private final AtomicReference<ResourceSpec> parentResource = new AtomicReference<>();

private volatile String method;
private final AtomicReference<String> method = new AtomicReference<>();

private volatile String name;
private final AtomicReference<String> name = new AtomicReference<>();

private volatile String label;
private final AtomicReference<String> label = new AtomicReference<>();

@JsonInclude(JsonInclude.Include.NON_NULL)
private volatile String description;
private final AtomicReference<String> description = new AtomicReference<>();

@JsonInclude(JsonInclude.Include.NON_EMPTY)
private final List<InputParameterSpec> inputParameters;

@JsonInclude(JsonInclude.Include.NON_NULL)
private volatile String outputRawFormat;
private final AtomicReference<String> outputRawFormat = new AtomicReference<>();

@JsonInclude(JsonInclude.Include.NON_NULL)
private volatile String outputSchema;
private final AtomicReference<String> outputSchema = new AtomicReference<>();

@JsonInclude(JsonInclude.Include.NON_EMPTY)
private final List<OutputParameterSpec> outputParameters;
Expand All @@ -60,83 +65,86 @@ public OperationSpec(ResourceSpec parentResource, String method, String name, St
}

public OperationSpec(ResourceSpec parentResource, String method, String name, String label, String description, String outputRawFormat, String outputSchema) {
this.parentResource = parentResource;
this.method = method;
this.name = name;
this.label = label;
this.description = description;
this.outputRawFormat = outputRawFormat;
this.outputSchema = outputSchema;
this.parentResource.set(parentResource);
this.method.set(method);
this.name.set(name);
this.label.set(label);
this.description.set(description);
this.outputRawFormat.set(outputRawFormat);
this.outputSchema.set(outputSchema);
this.inputParameters = new CopyOnWriteArrayList<>();
this.outputParameters = new CopyOnWriteArrayList<>();
}

public ResourceSpec getParentResource() {
return parentResource;
return parentResource.get();
}

/**
* Sets the parent resource for this operation.
* This is called during deserialization to establish the parent-child relationship.
*
*
* @param parentResource the parent ResourceSpec
*/
public void setParentResource(ResourceSpec parentResource) {
this.parentResource = parentResource;
this.parentResource.set(parentResource);
}

public String getMethod() {
return method;
return method.get();
}

public void setMethod(String method) {
this.method = method;
this.method.set(method);
}

public String getName() {
return name;
return name.get();
}

public void setName(String name) {
this.name = name;
this.name.set(name);
}

public String getLabel() {
return label;
return label.get();
}

public void setLabel(String label) {
this.label = label;
this.label.set(label);
}

@JsonInclude(JsonInclude.Include.NON_NULL)
public String getDescription() {
return description;
return description.get();
}

public void setDescription(String description) {
this.description = description;
this.description.set(description);
}

public List<InputParameterSpec> getInputParameters() {
return inputParameters;
}

@JsonInclude(JsonInclude.Include.NON_NULL)
public String getOutputRawFormat() {
return outputRawFormat;
return outputRawFormat.get();
}

public void setOutputRawFormat(String outputRawFormat) {
this.outputRawFormat = outputRawFormat;
this.outputRawFormat.set(outputRawFormat);
}

@JsonInclude(JsonInclude.Include.NON_NULL)
public String getOutputSchema() {
return outputSchema;
return outputSchema.get();
}

public void setOutputSchema(String outputSchema) {
this.outputSchema = outputSchema;
this.outputSchema.set(outputSchema);
}

public List<OutputParameterSpec> getOutputParameters() {
return outputParameters;
}
Expand Down
62 changes: 33 additions & 29 deletions src/main/java/io/naftiko/spec/aggregates/AggregateFunctionSpec.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,41 +13,42 @@
*/
package io.naftiko.spec.aggregates;

import io.naftiko.spec.InputParameterSpec;
import io.naftiko.spec.OutputParameterSpec;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicReference;

import com.fasterxml.jackson.annotation.JsonInclude;
import io.naftiko.spec.util.StepOutputMappingSpec;
import io.naftiko.spec.util.OperationStepSpec;

import io.naftiko.spec.InputParameterSpec;
import io.naftiko.spec.OutputParameterSpec;
import io.naftiko.spec.exposes.ServerCallSpec;
import io.naftiko.spec.util.OperationStepSpec;
import io.naftiko.spec.util.StepOutputMappingSpec;

/**
* Aggregate Function Specification Element.
*
* A reusable invocable unit within an aggregate. Adapter units reference it via
* ref: aggregate-namespace.function-name.
* <p>A reusable invocable unit within an aggregate. Adapter units reference it via
* {@code ref: aggregate-namespace.function-name}.</p>
*
* <h2>Thread safety</h2>
* Each scalar field is held in an {@link AtomicReference}; the {@code with} parameter map is
* stored as an immutable snapshot inside an {@link AtomicReference} so that fluent builders and
* Control-port runtime edits can replace it atomically. List fields use {@link CopyOnWriteArrayList}.
* This satisfies SonarQube rule {@code java:S3077}.
*/
public class AggregateFunctionSpec {

private volatile String name;
private volatile String description;

@JsonInclude(JsonInclude.Include.NON_NULL)
private volatile SemanticsSpec semantics;
private final AtomicReference<String> name = new AtomicReference<>();
private final AtomicReference<String> description = new AtomicReference<>();
private final AtomicReference<SemanticsSpec> semantics = new AtomicReference<>();
private final AtomicReference<ServerCallSpec> call = new AtomicReference<>();
private final AtomicReference<Map<String, Object>> with = new AtomicReference<>();

@JsonInclude(JsonInclude.Include.NON_EMPTY)
private final List<InputParameterSpec> inputParameters;

@JsonInclude(JsonInclude.Include.NON_NULL)
private volatile ServerCallSpec call;

@JsonInclude(JsonInclude.Include.NON_NULL)
private volatile Map<String, Object> with;

@JsonInclude(JsonInclude.Include.NON_EMPTY)
private final List<OperationStepSpec> steps;

Expand All @@ -65,47 +66,50 @@ public AggregateFunctionSpec() {
}

public String getName() {
return name;
return name.get();
}

public void setName(String name) {
this.name = name;
this.name.set(name);
}

public String getDescription() {
return description;
return description.get();
}

public void setDescription(String description) {
this.description = description;
this.description.set(description);
}

@JsonInclude(JsonInclude.Include.NON_NULL)
public SemanticsSpec getSemantics() {
return semantics;
return semantics.get();
}

public void setSemantics(SemanticsSpec semantics) {
this.semantics = semantics;
this.semantics.set(semantics);
}

public List<InputParameterSpec> getInputParameters() {
return inputParameters;
}

@JsonInclude(JsonInclude.Include.NON_NULL)
public ServerCallSpec getCall() {
return call;
return call.get();
}

public void setCall(ServerCallSpec call) {
this.call = call;
this.call.set(call);
}

@JsonInclude(JsonInclude.Include.NON_NULL)
public Map<String, Object> getWith() {
return with;
return with.get();
}

public void setWith(Map<String, Object> with) {
this.with = with != null ? new ConcurrentHashMap<>(with) : null;
this.with.set(with != null ? Map.copyOf(with) : null);
}

public List<OperationStepSpec> getSteps() {
Expand Down
Loading
Loading