diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/action/runner/processor/ActionStepProcessorRunFcli.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/action/runner/processor/ActionStepProcessorRunFcli.java index fe5543cb3e..9b76b646b6 100644 --- a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/action/runner/processor/ActionStepProcessorRunFcli.java +++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/action/runner/processor/ActionStepProcessorRunFcli.java @@ -56,6 +56,7 @@ public class ActionStepProcessorRunFcli extends AbstractActionStepProcessorMapEn private static final String FMT_DEPENDENCY_SKIP_REASON = "%s.dependencySkipReason"; private static final String FMT_EXIT_CODE = "%s.exitCode"; private static final String FMT_RECORDS = "%s.records"; + private static final String FMT_METADATA = "%s.metadata"; private static final String FMT_STDOUT = "%s.stdout"; private static final String FMT_STDERR = "%s.stderr"; @@ -95,6 +96,7 @@ protected final void process(String name, ActionStepRunFcliEntry entry) { private FcliCommandExecutor createCmdExecutor(ActionStepRunFcliEntry entry, String cmd, FcliRecordConsumer recordConsumer) { var stdoutOutputType = getOutputTypeOrDefault(entry.getStdoutOutputType(), recordConsumer==null ? OutputType.show : OutputType.suppress ); var stderrOutputType = getOutputTypeOrDefault(entry.getStderrOutputType(), OutputType.show ); + ObjectNode[] metadataHolder = {null}; try { return FcliCommandExecutorFactory.builder() .cmd(cmd) @@ -102,11 +104,13 @@ private FcliCommandExecutor createCmdExecutor(ActionStepRunFcliEntry entry, Stri .defaultOptionsIfNotPresent(ctx.getConfig().getDefaultFcliRunOptions()) .stdoutOutputType(stdoutOutputType) .stderrOutputType(stderrOutputType) - .onResult(r->onFcliResult(entry, recordConsumer, r)) + .onResult(r->onFcliResult(entry, recordConsumer, metadataHolder, r)) .onSuccess(r->onFcliSuccess(entry)) .onException(e->onFcliException(entry, e)) .onFail(r->onFcliFail(entry, recordConsumer, r)) - .recordConsumer(recordConsumer).build().create(); + .recordConsumer(recordConsumer) + .metadataConsumer(m->metadataHolder[0]=m) + .build().create(); } catch ( Exception e ) { onFcliException(entry, e); return null; @@ -205,14 +209,15 @@ private void onFcliException(ActionStepRunFcliEntry fcli, Throwable t) { } } - private void onFcliResult(ActionStepRunFcliEntry fcli, FcliRecordConsumer recordConsumer, Result result) { - setResultVars(fcli, recordConsumer, result); + private void onFcliResult(ActionStepRunFcliEntry fcli, FcliRecordConsumer recordConsumer, ObjectNode[] metadataHolder, Result result) { + setResultVars(fcli, recordConsumer, metadataHolder, result); logStatus(fcli, result); } - private void setResultVars(ActionStepRunFcliEntry fcli, FcliRecordConsumer recordConsumer, Result result) { + private void setResultVars(ActionStepRunFcliEntry fcli, FcliRecordConsumer recordConsumer, ObjectNode[] metadataHolder, Result result) { var name = fcli.getKey(); vars.set(String.format(FMT_RECORDS, name), recordConsumer!=null ? recordConsumer.getRecords() : JsonHelper.getObjectMapper().createArrayNode()); + vars.set(String.format(FMT_METADATA, name), metadataHolder[0]!=null ? metadataHolder[0] : NullNode.instance); vars.set(String.format(FMT_STDOUT, name), result.getOut()); vars.set(String.format(FMT_STDERR, name), result.getErr()); vars.set(String.format(FMT_EXIT_CODE, name), new IntNode(result.getExitCode())); diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/util/FcliCommandExecutorFactory.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/util/FcliCommandExecutorFactory.java index 8c6e3165a5..2b9d072600 100644 --- a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/util/FcliCommandExecutorFactory.java +++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/cli/util/FcliCommandExecutorFactory.java @@ -48,6 +48,7 @@ public final class FcliCommandExecutorFactory { @NonNull private final String cmd; private final Consumer recordConsumer; + private final Consumer metadataConsumer; @Builder.Default private final OutputType stdoutOutputType = OutputType.show; @Builder.Default private final OutputType stderrOutputType = OutputType.show; private final Consumer onResult; // Always executed if fcli command didn't throw exception @@ -105,7 +106,7 @@ private int handleParseException(String[] resolvedArgs, ParameterException e) { public final Result execute() { if ( parseErrorResult!=null ) { return parseErrorResult; } - if ( recordConsumer!=null && canCollectRecords() ) { setPerCommandRecordConsumer(); } + if ( (recordConsumer!=null || metadataConsumer!=null) && canCollectRecords() ) { setPerCommandConsumers(); } return call(()->_execute()); } @@ -189,10 +190,15 @@ public final boolean canCollectRecords() { return FcliCommandSpecHelper.canCollectRecords(replicatedLeafCommandSpec); } - private void setPerCommandRecordConsumer() { + private void setPerCommandConsumers() { var userObj = replicatedLeafCommandSpec.userObject(); - if ( userObj instanceof IRecordCollectionSupport ) { - ((IRecordCollectionSupport)userObj).setRecordConsumer(recordConsumer, stdoutOutputType!=OutputType.show); + if ( userObj instanceof IRecordCollectionSupport rcs ) { + if ( recordConsumer!=null ) { + rcs.setRecordConsumer(recordConsumer, stdoutOutputType!=OutputType.show); + } + if ( metadataConsumer!=null ) { + rcs.setMetadataConsumer(metadataConsumer); + } } } diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/json/producer/AbstractObjectNodeProducer.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/json/producer/AbstractObjectNodeProducer.java index d498bddaaa..e979820a8c 100644 --- a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/json/producer/AbstractObjectNodeProducer.java +++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/json/producer/AbstractObjectNodeProducer.java @@ -24,6 +24,7 @@ import com.fortify.cli.common.exception.FcliBugException; import com.fortify.cli.common.json.transform.fields.AddFieldsTransformer; import com.fortify.cli.common.output.product.IProductHelper; +import com.fortify.cli.common.output.product.IResponseMetadataCollector; import com.fortify.cli.common.output.transform.IActionCommandResultSupplier; import com.fortify.cli.common.output.transform.IInputTransformer; import com.fortify.cli.common.output.transform.IRecordTransformer; @@ -50,12 +51,18 @@ public abstract class AbstractObjectNodeProducer implements IObjectNodeProducer @Getter @Singular private final List> inputTransformers; @Getter @Singular private final List> recordTransformers; @Getter private final QueryExpression queryExpression; + @Getter private final IResponseMetadataCollector responseMetadataCollector; + private ObjectNode responseMetadata; + + @Override + public ObjectNode getResponseMetadata() { return responseMetadata; } /** * Template method used by subclasses to feed input JSON to this base class for processing. */ protected final void process(JsonNode input, IObjectNodeConsumer consumer) { if ( input==null ) { return; } + collectMetadata(input); JsonNode transformed = applyInputTransformers(input); if ( transformed==null || transformed.isNull() ) { return; } if ( transformed.isObject() ) { @@ -83,6 +90,12 @@ private JsonNode applyInputTransformers(JsonNode input) { return current; } + private void collectMetadata(JsonNode rawInput) { + if ( responseMetadata==null && responseMetadataCollector!=null ) { + responseMetadata = responseMetadataCollector.collectResponseMetadata(rawInput); + } + } + protected Break processSingleRecord(ObjectNode node, IObjectNodeConsumer consumer) { ObjectNode current = node; for ( var t : recordTransformers ) { @@ -136,6 +149,7 @@ public B applyAllFrom(ObjectNodeProducerApplyFrom applyFrom) { applyRecordTransformationsFrom(applyFrom); applyQueryFrom(applyFrom); applyActionCommandResultSupplierFrom(applyFrom); + applyResponseMetadataCollectorFrom(applyFrom); return self(); } private void applyActionCommandResultSupplierFrom(ObjectNodeProducerApplyFrom applyFrom) { @@ -158,6 +172,10 @@ public B applyQueryFrom(ObjectNodeProducerApplyFrom applyFrom) { } return self(); } + public B applyResponseMetadataCollectorFrom(ObjectNodeProducerApplyFrom applyFrom) { + applyFrom.getSourceStream(getRequiredCommandHelper(), explicitProductHelper).forEach(this::addResponseMetadataCollectorFromObject); + return self(); + } protected ICommandHelper getRequiredCommandHelper() { if ( commandHelper==null ) { throw new FcliBugException("CommandHelper not configured; call commandHelper() before apply*From()"); @@ -173,5 +191,10 @@ private void addInputTransformersFromObject(Object o) { private void addRecordTransformersFromObject(Object o) { if ( o instanceof IRecordTransformer rt ) { recordTransformer(n->rt.transformRecord(n)); } } + private void addResponseMetadataCollectorFromObject(Object o) { + if ( o instanceof IResponseMetadataCollector rmc && this.responseMetadataCollector==null ) { + responseMetadataCollector(rmc); + } + } } } diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/json/producer/IObjectNodeProducer.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/json/producer/IObjectNodeProducer.java index 70f3f10c68..d8f6763d3f 100644 --- a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/json/producer/IObjectNodeProducer.java +++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/json/producer/IObjectNodeProducer.java @@ -21,6 +21,13 @@ public interface IObjectNodeProducer { void forEach(IObjectNodeConsumer consumer); + /** + * Return response-level metadata (e.g., total count, paging links) captured from + * the underlying data source. Available after {@link #forEach} has been invoked. + * Returns {@code null} if no metadata was captured. + */ + default ObjectNode getResponseMetadata() { return null; } + @FunctionalInterface interface IObjectNodeConsumer { Break accept(ObjectNode node); } } diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/json/producer/RequestObjectNodeProducer.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/json/producer/RequestObjectNodeProducer.java index e6541094f7..35eaa151be 100644 --- a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/json/producer/RequestObjectNodeProducer.java +++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/json/producer/RequestObjectNodeProducer.java @@ -18,6 +18,7 @@ import com.fortify.cli.common.rest.paging.INextPageRequestProducer; import com.fortify.cli.common.rest.paging.INextPageUrlProducer; import com.fortify.cli.common.rest.paging.INextPageUrlProducerSupplier; +import com.fortify.cli.common.rest.paging.IPagingSuppressor; import com.fortify.cli.common.rest.paging.PagingHelper; import com.fortify.cli.common.rest.unirest.IHttpRequestUpdater; import com.fortify.cli.common.rest.unirest.IUnirestInstanceSupplier; @@ -41,6 +42,7 @@ public class RequestObjectNodeProducer extends AbstractObjectNodeProducer { @Singular private final List requestUpdaters; private final INextPageRequestProducer nextPageRequestProducer; private final INextPageUrlProducer nextPageUrlProducer; + private final boolean pagingSuppressed; // Test-only support: if configured, simulate multi-page responses without performing HTTP requests @Singular private final List testPageBodies; @@ -52,6 +54,10 @@ public void forEach(IObjectNodeConsumer consumer) { return; } HttpRequest request = applyRequestUpdaters(baseRequest); + if ( pagingSuppressed ) { + request.asObject(JsonNode.class).ifSuccess(r->handleResponse(r, consumer)).ifFailure(IfFailureHandler::handle); + return; + } INextPageRequestProducer effectiveNextPageRequestProducer = nextPageRequestProducer; if ( effectiveNextPageRequestProducer==null && nextPageUrlProducer!=null && unirestInstance!=null ) { effectiveNextPageRequestProducer = PagingHelper.asNextPageRequestProducer(unirestInstance, nextPageUrlProducer); @@ -83,29 +89,14 @@ public RequestObjectNodeProducerBuilderImpl applyAllFrom(ObjectNodeProducerApply var ch = getRequiredCommandHelper(); ch.getCommandAs(IUnirestInstanceSupplier.class) .ifPresent(s -> super.unirestInstance(s.getUnirestInstance())); - applyRequestUpdatersFrom(applyFrom); - applyNextPageUrlProducerFrom(applyFrom); + applyFrom.getSourceStream(ch, getExplicitProductHelper()).forEach(this::applyFromObject); return self(); } - private void applyNextPageUrlProducerFrom(ObjectNodeProducerApplyFrom applyFrom) { - applyFrom.getSourceStream(getRequiredCommandHelper(), getExplicitProductHelper()).forEach(this::addNextPageUrlProducerFromObject); - } - - public void applyRequestUpdatersFrom(ObjectNodeProducerApplyFrom applyFrom) { - applyFrom.getSourceStream(getRequiredCommandHelper(), getExplicitProductHelper()).forEach(this::addRequestUpdaterFromObject); - } - - private void addRequestUpdaterFromObject(Object o) { - if (o instanceof IHttpRequestUpdater u) { - requestUpdater(u); - } - } - - private void addNextPageUrlProducerFromObject(Object o) { - if (o instanceof INextPageUrlProducerSupplier s) { - nextPageUrlProducer(s.getNextPageUrlProducer()); - } + private void applyFromObject(Object o) { + if (o instanceof IHttpRequestUpdater u) { requestUpdater(u); } + if (o instanceof INextPageUrlProducerSupplier s) { nextPageUrlProducer(s.getNextPageUrlProducer()); } + if (o instanceof IPagingSuppressor s && s.isPagingSuppressed()) { pagingSuppressed(true); } } /** Configure unirest instance to enable streaming paging conversion. */ diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/AbstractOutputCommand.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/AbstractOutputCommand.java index 0baef861f6..4e0fb91b2b 100644 --- a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/AbstractOutputCommand.java +++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/AbstractOutputCommand.java @@ -46,6 +46,7 @@ public abstract class AbstractOutputCommand extends AbstractRunnableCommand implements ISingularSupplier, IOutputHelperSupplier, IRecordCollectionSupport { @Getter private Consumer recordConsumer; + @Getter private Consumer metadataConsumer; @Getter private boolean stdoutSuppressedForRecordCollection; @Override @@ -125,4 +126,9 @@ public final void setRecordConsumer(Consumer consumer, boolean suppr this.recordConsumer = consumer; this.stdoutSuppressedForRecordCollection = suppressStdout; } + + @Override + public final void setMetadataConsumer(Consumer consumer) { + this.metadataConsumer = consumer; + } } diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/IRecordCollectionSupport.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/IRecordCollectionSupport.java index f4ba3e5fd5..1d307c167a 100644 --- a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/IRecordCollectionSupport.java +++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/cli/cmd/IRecordCollectionSupport.java @@ -25,4 +25,6 @@ public interface IRecordCollectionSupport { void setRecordConsumer(Consumer consumer, boolean suppressStdout); Consumer getRecordConsumer(); boolean isStdoutSuppressedForRecordCollection(); + default void setMetadataConsumer(Consumer consumer) {} + default Consumer getMetadataConsumer() { return null; } } diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/product/IResponseMetadataCollector.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/product/IResponseMetadataCollector.java new file mode 100644 index 0000000000..a840401e83 --- /dev/null +++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/product/IResponseMetadataCollector.java @@ -0,0 +1,34 @@ +/* + * Copyright 2021-2026 Open Text. + * + * The only warranties for products and services of Open Text + * and its affiliates and licensors ("Open Text") are as may + * be set forth in the express warranty statements accompanying + * such products and services. Nothing herein should be construed + * as constituting an additional warranty. Open Text shall not be + * liable for technical or editorial errors or omissions contained + * herein. The information contained herein is subject to change + * without notice. + */ +package com.fortify.cli.common.output.product; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +/** + * Interface for extracting response-level metadata (e.g., total record count, + * paging links) from a raw API response body before input transformation + * strips non-record data. + *

+ * Product helpers (e.g., SSCProductHelper, FoDProductHelper) implement this + * to capture metadata specific to their API response format. + */ +@FunctionalInterface +public interface IResponseMetadataCollector { + /** + * Extract metadata from the raw response body. Called before input + * transformation (which typically extracts only the records array). + * Returns {@code null} if no metadata is available. + */ + ObjectNode collectResponseMetadata(JsonNode responseBody); +} diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/StandardOutputWriter.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/StandardOutputWriter.java index c05ba000ac..f6fb25f56b 100644 --- a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/StandardOutputWriter.java +++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/output/standard/StandardOutputWriter.java @@ -15,6 +15,7 @@ import java.io.FileWriter; import java.io.OutputStreamWriter; import java.io.Writer; +import java.util.function.Consumer; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fortify.cli.common.cli.util.FcliCommandSpecHelper; @@ -51,6 +52,7 @@ public class StandardOutputWriter implements IOutputWriter { private final IOutputOptions outputOptions; private final IMessageResolver messageResolver; private final IRecordWriter recordCollector; // instance-level collector, may be null + private final Consumer metadataConsumer; // programmatic metadata callback, may be null private final boolean suppressOutput; public StandardOutputWriter(CommandSpec commandSpec, IOutputOptions outputOptions, StandardOutputConfig defaultOutputConfig) { @@ -72,9 +74,11 @@ public void close() { } }; this.suppressOutput = rcs.isStdoutSuppressedForRecordCollection(); + this.metadataConsumer = rcs.getMetadataConsumer(); } else { this.recordCollector = null; this.suppressOutput = false; + this.metadataConsumer = null; } } @@ -89,6 +93,11 @@ public void write(IObjectNodeProducer recordProducer) { } try (IRecordWriter rw = new OutputAndVariableRecordWriter()) { recordProducer.forEach(recordConsumer(rw)); + var metadata = recordProducer.getResponseMetadata(); + rw.setResponseMetadata(metadata); + if (metadataConsumer != null && metadata != null) { + metadataConsumer.accept(metadata); + } } } @@ -148,6 +157,13 @@ public void close() { } } + @Override + public void setResponseMetadata(ObjectNode metadata) { + if (outputRecordWriter != null) { + outputRecordWriter.setResponseMetadata(metadata); + } + } + private IRecordWriter createOutputRecordWriter() { return suppressOutput ? null : createUnsuppressed(); } diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/IRecordWriter.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/IRecordWriter.java index 00340171f5..46013bf133 100644 --- a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/IRecordWriter.java +++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/IRecordWriter.java @@ -19,4 +19,10 @@ public interface IRecordWriter extends Closeable { void append(ObjectNode node); void close(); + /** + * Set response-level metadata to be included in the output when envelope + * style is active. Must be called before {@link #close()} for the metadata + * to be written. Writers that do not support envelope style ignore this. + */ + default void setResponseMetadata(ObjectNode metadata) {} } diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/RecordWriterStyle.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/RecordWriterStyle.java index 6293142014..3e427e1406 100644 --- a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/RecordWriterStyle.java +++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/RecordWriterStyle.java @@ -100,6 +100,11 @@ public final boolean isFastOutput() { return getOrDefault(RecordWriterStyleElementGroup.FAST_OUTPUT)==RecordWriterStyleElement.fast_output; } + /** Indicates whether output should be wrapped in an envelope containing response metadata. Defaults to no-envelope. */ + public final boolean isEnvelope() { + return getOrDefault(RecordWriterStyleElementGroup.ENVELOPE)==RecordWriterStyleElement.envelope; + } + private final RecordWriterStyleElement getOrDefault(RecordWriterStyleElementGroup group) { return styleElementsByGroup.getOrDefault(group, group.defaultStyle()); } @@ -113,7 +118,8 @@ public static enum RecordWriterStyleElement { border(RecordWriterStyleElementGroup.BORDER), no_border(RecordWriterStyleElementGroup.BORDER), md_border(RecordWriterStyleElementGroup.BORDER), wrap(RecordWriterStyleElementGroup.WRAP), no_wrap(RecordWriterStyleElementGroup.WRAP), - fast_output(RecordWriterStyleElementGroup.FAST_OUTPUT), no_fast_output(RecordWriterStyleElementGroup.FAST_OUTPUT) + fast_output(RecordWriterStyleElementGroup.FAST_OUTPUT), no_fast_output(RecordWriterStyleElementGroup.FAST_OUTPUT), + envelope(RecordWriterStyleElementGroup.ENVELOPE), no_envelope(RecordWriterStyleElementGroup.ENVELOPE) ; @Getter private final RecordWriterStyleElementGroup group; @@ -135,7 +141,8 @@ public static enum RecordWriterStyleElementGroup { SINGULAR("array"), BORDER("no-border"), WRAP("wrap"), - FAST_OUTPUT("fast-output"); + FAST_OUTPUT("fast-output"), + ENVELOPE("no-envelope"); private final String defaultStyleElementName; diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/impl/AbstractRecordWriter.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/impl/AbstractRecordWriter.java index 82644161e5..55f1c146b0 100644 --- a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/impl/AbstractRecordWriter.java +++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/impl/AbstractRecordWriter.java @@ -27,12 +27,14 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.Setter; import lombok.SneakyThrows; //TODO Do proper exception handling instead of @SneakyThrows @RequiredArgsConstructor public abstract class AbstractRecordWriter implements IRecordWriter { @Getter(value = AccessLevel.PRIVATE, lazy=true) private final Writer writer = createWriter(); + @Getter(value = AccessLevel.PROTECTED) @Setter private ObjectNode responseMetadata; private T out; private Function recordFormatter; diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/impl/AbstractRecordWriterJackson.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/impl/AbstractRecordWriterJackson.java index 93f9fb2101..b782615473 100644 --- a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/impl/AbstractRecordWriterJackson.java +++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/impl/AbstractRecordWriterJackson.java @@ -38,14 +38,17 @@ protected Function createRecordFormatter(ObjectNode obje @Override protected void close(T out) throws IOException { writeEnd(out); + writeEnvelopeEnd(out); out.close(); } @Override protected void closeWithNoData(Writer writer) throws IOException { var out = createGenerator(writer); + writeEnvelopeStart(out); writeStart(out); writeEnd(out); + writeEnvelopeEnd(out); writer.flush(); out.close(); } @@ -54,10 +57,37 @@ protected void closeWithNoData(Writer writer) throws IOException { protected T createOut(Writer writer, ObjectNode formattedRecord) throws IOException { if ( formattedRecord==null ) { return null; } var result = createGenerator(writer); + writeEnvelopeStart(result); writeStart(result); return result; } + private void writeEnvelopeStart(T out) throws IOException { + if ( getConfig().getStyle().isEnvelope() ) { + doWriteEnvelopeStart(out); + } + } + + private void writeEnvelopeEnd(T out) throws IOException { + if ( getConfig().getStyle().isEnvelope() ) { + doWriteEnvelopeEnd(out); + } + } + + protected void doWriteEnvelopeStart(T out) throws IOException { + out.writeStartObject(); + out.writeFieldName("records"); + } + + protected void doWriteEnvelopeEnd(T out) throws IOException { + var metadata = getResponseMetadata(); + if ( metadata!=null ) { + out.writeFieldName("metadata"); + out.writeTree(metadata); + } + out.writeEndObject(); + } + protected abstract T createGenerator(Writer writer) throws IOException; protected abstract void writeStart(T out) throws IOException; protected abstract void writeEnd(T out) throws IOException; diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/impl/RecordWriterXml.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/impl/RecordWriterXml.java index 64369ec19d..77508d2dff 100644 --- a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/impl/RecordWriterXml.java +++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/output/writer/record/impl/RecordWriterXml.java @@ -57,4 +57,21 @@ protected void writeStart(ToXmlGenerator out) throws IOException { protected void writeEnd(ToXmlGenerator out) throws IOException { out.writeEndObject(); } + + @Override + protected void doWriteEnvelopeStart(ToXmlGenerator out) throws IOException { + out.setNextName(new QName(null, "envelope")); + out.writeStartObject(); + out.writeFieldName("records"); + } + + @Override + protected void doWriteEnvelopeEnd(ToXmlGenerator out) throws IOException { + var metadata = getResponseMetadata(); + if ( metadata!=null ) { + out.writeFieldName("metadata"); + out.writeTree(metadata); + } + out.writeEndObject(); + } } diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/cmd/AbstractRestCallCommand.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/cmd/AbstractRestCallCommand.java index 46af597770..01abdd8a2e 100644 --- a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/cmd/AbstractRestCallCommand.java +++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/cmd/AbstractRestCallCommand.java @@ -29,6 +29,7 @@ import com.fortify.cli.common.output.transform.IRecordTransformer; import com.fortify.cli.common.rest.paging.INextPageUrlProducer; import com.fortify.cli.common.rest.paging.INextPageUrlProducerSupplier; +import com.fortify.cli.common.rest.paging.IPagingSuppressor; import com.fortify.cli.common.rest.unirest.IUnirestInstanceSupplier; import com.fortify.cli.common.util.DisableTest; import com.fortify.cli.common.util.DisableTest.TestType; @@ -49,7 +50,7 @@ * * @author Ruud Senden */ -public abstract class AbstractRestCallCommand extends AbstractOutputCommand implements IBaseRequestSupplier, IUnirestInstanceSupplier, IInputTransformer, IRecordTransformer, INextPageUrlProducerSupplier { +public abstract class AbstractRestCallCommand extends AbstractOutputCommand implements IBaseRequestSupplier, IUnirestInstanceSupplier, IInputTransformer, IRecordTransformer, INextPageUrlProducerSupplier, IPagingSuppressor { @EnvSuffix("URI") @Parameters(index = "0", arity = "1..1", descriptionKey = "api.uri") String uri; @Option(names = {"--request", "-X"}, required = false, defaultValue = "GET") @@ -109,13 +110,14 @@ public final JsonNode transformRecord(JsonNode input) { return input; } + @Override + public boolean isPagingSuppressed() { + return noPaging; + } + @Override public final INextPageUrlProducer getNextPageUrlProducer() { - INextPageUrlProducer result = null; - if ( !noPaging ) { - result = _getNextPageUrlProducer(); - } - return result; + return applyOnProductHelper(INextPageUrlProducerSupplier.class, s->s.getNextPageUrlProducer(), null); } private final JsonNode _transformRecord(JsonNode input) { @@ -124,9 +126,6 @@ private final JsonNode _transformRecord(JsonNode input) { private final JsonNode _transformInput(JsonNode input) { return applyOnProductHelper(IInputTransformer.class, t->t.transformInput(input), input); } - private final INextPageUrlProducer _getNextPageUrlProducer() { - return applyOnProductHelper(INextPageUrlProducerSupplier.class, s->s.getNextPageUrlProducer(), null); - } protected String formatUri(String uri) { return uri; diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/AbstractFetchRangeMixin.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/AbstractFetchRangeMixin.java new file mode 100644 index 0000000000..e7fc7b5280 --- /dev/null +++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/rest/cli/mixin/AbstractFetchRangeMixin.java @@ -0,0 +1,53 @@ +/* + * Copyright 2021-2026 Open Text. + * + * The only warranties for products and services of Open Text + * and its affiliates and licensors ("Open Text") are as may + * be set forth in the express warranty statements accompanying + * such products and services. Nothing herein should be construed + * as constituting an additional warranty. Open Text shall not be + * liable for technical or editorial errors or omissions contained + * herein. The information contained herein is subject to change + * without notice. + */ +package com.fortify.cli.common.rest.cli.mixin; + +import com.fortify.cli.common.exception.FcliBugException; +import com.fortify.cli.common.rest.paging.FetchRange; +import com.fortify.cli.common.rest.paging.FetchRangeConverter; +import com.fortify.cli.common.rest.paging.IPagingSuppressor; +import com.fortify.cli.common.rest.unirest.IHttpRequestUpdater; + +import kong.unirest.HttpRequest; +import picocli.CommandLine.Option; + +public abstract class AbstractFetchRangeMixin implements IHttpRequestUpdater, IPagingSuppressor { + @Option(names = "--fetch", paramLabel = "", + converter = FetchRangeConverter.class) + private FetchRange fetchRange; + + public final boolean isFetchSpecified() { + return fetchRange != null; + } + + @Override + public final boolean isPagingSuppressed() { + return fetchRange != null; + } + + @Override + public final HttpRequest updateRequest(HttpRequest request) { + assertNoExistingPagingParams(request); + if ( fetchRange == null ) { return request; } + return applyFetchParams(request, fetchRange); + } + + protected abstract HttpRequest applyFetchParams(HttpRequest request, FetchRange range); + + private void assertNoExistingPagingParams(HttpRequest request) { + var url = request.getUrl(); + if ( url.matches(".*[?&](limit|start|offset)=.*") ) { + throw new FcliBugException("Request URL contains hardcoded paging params: " + url); + } + } +} diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/rest/paging/FetchRange.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/rest/paging/FetchRange.java new file mode 100644 index 0000000000..ed33019c2c --- /dev/null +++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/rest/paging/FetchRange.java @@ -0,0 +1,20 @@ +/* + * Copyright 2021-2026 Open Text. + * + * The only warranties for products and services of Open Text + * and its affiliates and licensors ("Open Text") are as may + * be set forth in the express warranty statements accompanying + * such products and services. Nothing herein should be construed + * as constituting an additional warranty. Open Text shall not be + * liable for technical or editorial errors or omissions contained + * herein. The information contained herein is subject to change + * without notice. + */ +package com.fortify.cli.common.rest.paging; + +/** + * Represents a fetch range consisting of an offset (start record, 0-based) and + * a maximum number of records to retrieve (limit). Used by fetch-range mixins to + * restrict paging to a specific slice of server-side results. + */ +public record FetchRange(int offset, int limit) {} diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/rest/paging/FetchRangeConverter.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/rest/paging/FetchRangeConverter.java new file mode 100644 index 0000000000..f28a9c9e8c --- /dev/null +++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/rest/paging/FetchRangeConverter.java @@ -0,0 +1,42 @@ +/* + * Copyright 2021-2026 Open Text. + * + * The only warranties for products and services of Open Text + * and its affiliates and licensors ("Open Text") are as may + * be set forth in the express warranty statements accompanying + * such products and services. Nothing herein should be construed + * as constituting an additional warranty. Open Text shall not be + * liable for technical or editorial errors or omissions contained + * herein. The information contained herein is subject to change + * without notice. + */ +package com.fortify.cli.common.rest.paging; + +import com.fortify.cli.common.exception.FcliSimpleException; + +import picocli.CommandLine.ITypeConverter; + +public class FetchRangeConverter implements ITypeConverter { + @Override + public FetchRange convert(String value) { + try { + var parts = value.split("-", 2); + int start, end; + if ( parts.length == 1 ) { + start = 1; + end = Integer.parseInt(parts[0].trim()); + if ( end < 1 ) throw new FcliSimpleException("--fetch value must be >= 1"); + } else { + start = Integer.parseInt(parts[0].trim()); + end = Integer.parseInt(parts[1].trim()); + if ( start < 1 ) throw new FcliSimpleException("--fetch start must be >= 1"); + if ( end < start ) throw new FcliSimpleException("--fetch end must be >= start (%d)".formatted(start)); + } + return new FetchRange(start - 1, end - start + 1); + } catch ( FcliSimpleException e ) { + throw e; + } catch ( Exception e ) { + throw new FcliSimpleException("Invalid --fetch value '%s'. Expected format: [-]".formatted(value)); + } + } +} diff --git a/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/rest/paging/IPagingSuppressor.java b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/rest/paging/IPagingSuppressor.java new file mode 100644 index 0000000000..1b8b13c9c8 --- /dev/null +++ b/fcli-core/fcli-common/src/main/java/com/fortify/cli/common/rest/paging/IPagingSuppressor.java @@ -0,0 +1,17 @@ +/* + * Copyright 2021-2026 Open Text. + * + * The only warranties for products and services of Open Text + * and its affiliates and licensors ("Open Text") are as may + * be set forth in the express warranty statements accompanying + * such products and services. Nothing herein should be construed + * as constituting an additional warranty. Open Text shall not be + * liable for technical or editorial errors or omissions contained + * herein. The information contained herein is subject to change + * without notice. + */ +package com.fortify.cli.common.rest.paging; + +public interface IPagingSuppressor { + boolean isPagingSuppressed(); +} diff --git a/fcli-core/fcli-common/src/main/resources/com/fortify/cli/common/i18n/FortifyCLIMessages.properties b/fcli-core/fcli-common/src/main/resources/com/fortify/cli/common/i18n/FortifyCLIMessages.properties index e0167c4339..788b219184 100644 --- a/fcli-core/fcli-common/src/main/resources/com/fortify/cli/common/i18n/FortifyCLIMessages.properties +++ b/fcli-core/fcli-common/src/main/resources/com/fortify/cli/common/i18n/FortifyCLIMessages.properties @@ -84,6 +84,9 @@ style = Select output style: ${COMPLETION-CANDIDATES}. to-file = Write output to the specified file. store = Store JSON results in an fcli variable for later reference. query = Only display records for which the given Spring Expression Language (SpEL) expression returns true. +fetch = Limit the number of records fetched from the server. Format: [-], where start \ + and end are 1-based, inclusive record numbers. Examples: 10 (first 10 records), 1-10 (same), \ + 21-30 (records 21 through 30). By default, all records are fetched. # Options and prompts defined in CommonOptionMixins fcli.confirm = Confirm operation. diff --git a/fcli-core/fcli-common/src/test/java/com/fortify/cli/common/rest/paging/FetchRangeTest.java b/fcli-core/fcli-common/src/test/java/com/fortify/cli/common/rest/paging/FetchRangeTest.java new file mode 100644 index 0000000000..69743f8292 --- /dev/null +++ b/fcli-core/fcli-common/src/test/java/com/fortify/cli/common/rest/paging/FetchRangeTest.java @@ -0,0 +1,77 @@ +/* + * Copyright 2021-2026 Open Text. + * + * The only warranties for products and services of Open Text + * and its affiliates and licensors ("Open Text") are as may + * be set forth in the express warranty statements accompanying + * such products and services. Nothing herein should be construed + * as constituting an additional warranty. Open Text shall not be + * liable for technical or editorial errors or omissions contained + * herein. The information contained herein is subject to change + * without notice. + */ +package com.fortify.cli.common.rest.paging; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +import com.fortify.cli.common.exception.FcliSimpleException; + +public class FetchRangeTest { + private final FetchRangeConverter converter = new FetchRangeConverter(); + + @Test + void endOnly() { + var result = converter.convert("10"); + assertEquals(0, result.offset()); + assertEquals(10, result.limit()); + } + + @Test + void startAndEndFromOne() { + var result = converter.convert("1-10"); + assertEquals(0, result.offset()); + assertEquals(10, result.limit()); + } + + @Test + void startAndEndMidRange() { + var result = converter.convert("21-30"); + assertEquals(20, result.offset()); + assertEquals(10, result.limit()); + } + + @Test + void singleRecord() { + var result = converter.convert("1"); + assertEquals(0, result.offset()); + assertEquals(1, result.limit()); + } + + @Test + void zeroEndRejected() { + assertThrows(FcliSimpleException.class, () -> converter.convert("0")); + } + + @Test + void zeroStartRejected() { + assertThrows(FcliSimpleException.class, () -> converter.convert("0-10")); + } + + @Test + void endBeforeStartRejected() { + assertThrows(FcliSimpleException.class, () -> converter.convert("30-21")); + } + + @Test + void nonNumericRejected() { + assertThrows(FcliSimpleException.class, () -> converter.convert("abc")); + } + + @Test + void extraSeparatorRejected() { + assertThrows(FcliSimpleException.class, () -> converter.convert("1-2-3")); + } +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/cli/mixin/FoDFetchRangeMixin.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/cli/mixin/FoDFetchRangeMixin.java new file mode 100644 index 0000000000..8a6af27441 --- /dev/null +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/cli/mixin/FoDFetchRangeMixin.java @@ -0,0 +1,27 @@ +/* + * Copyright 2021-2026 Open Text. + * + * The only warranties for products and services of Open Text + * and its affiliates and licensors ("Open Text") are as may + * be set forth in the express warranty statements accompanying + * such products and services. Nothing herein should be construed + * as constituting an additional warranty. Open Text shall not be + * liable for technical or editorial errors or omissions contained + * herein. The information contained herein is subject to change + * without notice. + */ +package com.fortify.cli.fod._common.cli.mixin; + +import com.fortify.cli.common.rest.cli.mixin.AbstractFetchRangeMixin; +import com.fortify.cli.common.rest.paging.FetchRange; + +import kong.unirest.HttpRequest; + +public final class FoDFetchRangeMixin extends AbstractFetchRangeMixin { + @Override + protected HttpRequest applyFetchParams(HttpRequest request, FetchRange range) { + return request + .queryString("offset", range.offset()) + .queryString("limit", range.limit()); + } +} diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/rest/helper/FoDProductHelper.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/rest/helper/FoDProductHelper.java index 0081c8fae9..6757cc116e 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/rest/helper/FoDProductHelper.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/rest/helper/FoDProductHelper.java @@ -16,8 +16,11 @@ import java.net.URL; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.fortify.cli.common.exception.FcliSimpleException; +import com.fortify.cli.common.json.JsonHelper; import com.fortify.cli.common.output.product.IProductHelper; +import com.fortify.cli.common.output.product.IResponseMetadataCollector; import com.fortify.cli.common.output.transform.IInputTransformer; import com.fortify.cli.common.rest.paging.INextPageUrlProducer; import com.fortify.cli.common.rest.paging.INextPageUrlProducerSupplier; @@ -26,7 +29,7 @@ // IMPORTANT: When updating/adding any methods in this class, FoDRestCallCommand // also likely needs to be updated -public class FoDProductHelper implements IProductHelper, IInputTransformer, INextPageUrlProducerSupplier +public class FoDProductHelper implements IProductHelper, IInputTransformer, INextPageUrlProducerSupplier, IResponseMetadataCollector { public static final FoDProductHelper INSTANCE = new FoDProductHelper(); private FoDProductHelper() {} @@ -40,6 +43,22 @@ public JsonNode transformInput(JsonNode input) { return FoDInputTransformer.getItems(input); } + @Override + public ObjectNode collectResponseMetadata(JsonNode responseBody) { + if ( responseBody==null || !responseBody.has("items") ) { return null; } + var metadata = JsonHelper.getObjectMapper().createObjectNode(); + if ( responseBody.has("totalCount") ) { + metadata.set("totalCount", responseBody.get("totalCount")); + } + if ( responseBody.has("offset") ) { + metadata.set("offset", responseBody.get("offset")); + } + if ( responseBody.has("limit") ) { + metadata.set("limit", responseBody.get("limit")); + } + return metadata.isEmpty() ? null : metadata; + } + public String getApiUrl(String url) { URL result = parseUrl(url); String host = result.getHost(); diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/cli/cmd/AbstractFoDScanListCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/cli/cmd/AbstractFoDScanListCommand.java index 255953fdca..6fda27de8b 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/cli/cmd/AbstractFoDScanListCommand.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/_common/scan/cli/cmd/AbstractFoDScanListCommand.java @@ -16,6 +16,7 @@ import com.fortify.cli.common.cli.util.CommandGroup; import com.fortify.cli.common.output.transform.IRecordTransformer; import com.fortify.cli.fod._common.cli.mixin.FoDDelimiterMixin; +import com.fortify.cli.fod._common.cli.mixin.FoDFetchRangeMixin; import com.fortify.cli.fod._common.output.cli.cmd.AbstractFoDBaseRequestOutputCommand; import com.fortify.cli.fod._common.rest.FoDUrls; import com.fortify.cli.fod._common.scan.helper.FoDScanHelper; @@ -29,6 +30,7 @@ @CommandGroup("*-scan") public abstract class AbstractFoDScanListCommand extends AbstractFoDBaseRequestOutputCommand implements IRecordTransformer { @Mixin private FoDDelimiterMixin delimiterMixin; // Is automatically injected in resolver mixins + @Mixin private FoDFetchRangeMixin fetchRangeMixin; @Mixin private FoDReleaseByQualifiedNameOrIdResolverMixin.RequiredOption releaseResolver; @Override diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/access_control/cli/cmd/FoDGroupListCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/access_control/cli/cmd/FoDGroupListCommand.java index 54a9c6c2f8..fb5b45a7c9 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/access_control/cli/cmd/FoDGroupListCommand.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/access_control/cli/cmd/FoDGroupListCommand.java @@ -19,6 +19,7 @@ import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; import com.fortify.cli.common.variable.DefaultVariablePropertyName; +import com.fortify.cli.fod._common.cli.mixin.FoDFetchRangeMixin; import com.fortify.cli.fod._common.output.cli.cmd.AbstractFoDBaseRequestOutputCommand; import com.fortify.cli.fod._common.rest.FoDUrls; import com.fortify.cli.fod._common.rest.query.FoDFiltersParamGenerator; @@ -35,6 +36,7 @@ @DefaultVariablePropertyName("id") public class FoDGroupListCommand extends AbstractFoDBaseRequestOutputCommand implements IRecordTransformer, IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.TableWithQuery outputHelper; + @Mixin private FoDFetchRangeMixin fetchRangeMixin; @Mixin private FoDFiltersParamMixin filterParamMixin; @Getter private IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new FoDFiltersParamGenerator() .add("groupId") diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/access_control/cli/cmd/FoDRoleListCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/access_control/cli/cmd/FoDRoleListCommand.java index 86e00ac8ad..9fd7e8a931 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/access_control/cli/cmd/FoDRoleListCommand.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/access_control/cli/cmd/FoDRoleListCommand.java @@ -19,6 +19,7 @@ import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; import com.fortify.cli.common.output.transform.IRecordTransformer; import com.fortify.cli.common.variable.DefaultVariablePropertyName; +import com.fortify.cli.fod._common.cli.mixin.FoDFetchRangeMixin; import com.fortify.cli.fod._common.output.cli.cmd.AbstractFoDBaseRequestOutputCommand; import com.fortify.cli.fod._common.rest.FoDUrls; import com.fortify.cli.fod.rest.lookup.helper.FoDLookupType; @@ -35,6 +36,7 @@ public class FoDRoleListCommand extends AbstractFoDBaseRequestOutputCommand impl private static final RenameFieldsTransformer RECORD_TRANSFORMER = new RenameFieldsTransformer( new String[] {"value:id", "text:name"}); @Getter @Mixin private OutputHelperMixins.TableWithQuery outputHelper; + @Mixin private FoDFetchRangeMixin fetchRangeMixin; @Override public HttpRequest getBaseRequest(UnirestInstance unirest) { diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/access_control/cli/cmd/FoDUserListCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/access_control/cli/cmd/FoDUserListCommand.java index 3f2c026b98..6d8a7e6136 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/access_control/cli/cmd/FoDUserListCommand.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/access_control/cli/cmd/FoDUserListCommand.java @@ -19,6 +19,7 @@ import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; import com.fortify.cli.common.variable.DefaultVariablePropertyName; +import com.fortify.cli.fod._common.cli.mixin.FoDFetchRangeMixin; import com.fortify.cli.fod._common.output.cli.cmd.AbstractFoDBaseRequestOutputCommand; import com.fortify.cli.fod._common.rest.FoDUrls; import com.fortify.cli.fod._common.rest.query.FoDFiltersParamGenerator; @@ -35,6 +36,7 @@ @DefaultVariablePropertyName("userId") public class FoDUserListCommand extends AbstractFoDBaseRequestOutputCommand implements IRecordTransformer, IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.TableWithQuery outputHelper; + @Mixin private FoDFetchRangeMixin fetchRangeMixin; @Mixin private FoDFiltersParamMixin filterParamMixin; @Getter private IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new FoDFiltersParamGenerator() .add("userId","userId") diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/app/cli/cmd/FoDAppListCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/app/cli/cmd/FoDAppListCommand.java index ff29c7217a..5620045d60 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/app/cli/cmd/FoDAppListCommand.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/app/cli/cmd/FoDAppListCommand.java @@ -17,6 +17,7 @@ import com.fortify.cli.common.output.transform.IRecordTransformer; import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; +import com.fortify.cli.fod._common.cli.mixin.FoDFetchRangeMixin; import com.fortify.cli.fod._common.output.cli.cmd.AbstractFoDBaseRequestOutputCommand; import com.fortify.cli.fod._common.rest.FoDUrls; import com.fortify.cli.fod._common.rest.query.FoDFiltersParamGenerator; @@ -32,6 +33,7 @@ @Command(name = OutputHelperMixins.List.CMD_NAME) public class FoDAppListCommand extends AbstractFoDBaseRequestOutputCommand implements IRecordTransformer, IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.List outputHelper; + @Mixin private FoDFetchRangeMixin fetchRangeMixin; @Mixin private FoDFiltersParamMixin filterParamMixin; @Getter private IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new FoDFiltersParamGenerator() .add("id","applicationId") diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/app/cli/cmd/FoDAppScanListCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/app/cli/cmd/FoDAppScanListCommand.java index 18d4f0b83e..253ac46d8e 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/app/cli/cmd/FoDAppScanListCommand.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/app/cli/cmd/FoDAppScanListCommand.java @@ -14,6 +14,7 @@ import com.fortify.cli.common.cli.util.CommandGroup; import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; +import com.fortify.cli.fod._common.cli.mixin.FoDFetchRangeMixin; import com.fortify.cli.fod._common.output.cli.cmd.AbstractFoDBaseRequestOutputCommand; import com.fortify.cli.fod._common.rest.FoDUrls; import com.fortify.cli.fod._common.scan.helper.FoDScanHelper; @@ -28,6 +29,7 @@ @Command(name = "list-scans", aliases = "lss") @CommandGroup("scan") public class FoDAppScanListCommand extends AbstractFoDBaseRequestOutputCommand { @Getter @Mixin private OutputHelperMixins.TableWithQuery outputHelper; + @Mixin private FoDFetchRangeMixin fetchRangeMixin; @Mixin private FoDAppResolverMixin.RequiredOption appResolver; @Override diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/attribute/cli/cmd/FoDAttributeListCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/attribute/cli/cmd/FoDAttributeListCommand.java index 112df29c99..7e3918c774 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/attribute/cli/cmd/FoDAttributeListCommand.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/attribute/cli/cmd/FoDAttributeListCommand.java @@ -15,6 +15,7 @@ import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; +import com.fortify.cli.fod._common.cli.mixin.FoDFetchRangeMixin; import com.fortify.cli.fod._common.output.cli.cmd.AbstractFoDBaseRequestOutputCommand; import com.fortify.cli.fod._common.rest.FoDUrls; import com.fortify.cli.fod._common.rest.query.FoDFiltersParamGenerator; @@ -29,6 +30,7 @@ @Command(name = OutputHelperMixins.List.CMD_NAME) public class FoDAttributeListCommand extends AbstractFoDBaseRequestOutputCommand implements IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.List outputHelper; + @Mixin private FoDFetchRangeMixin fetchRangeMixin; @Mixin private FoDFiltersParamMixin filterParamMixin; @Getter private IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new FoDFiltersParamGenerator() .add("id", "attributeId") diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/issue/cli/cmd/FoDIssueListCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/issue/cli/cmd/FoDIssueListCommand.java index dc60abb40d..9c909c10e5 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/issue/cli/cmd/FoDIssueListCommand.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/issue/cli/cmd/FoDIssueListCommand.java @@ -22,6 +22,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fortify.cli.common.exception.FcliSimpleException; import com.fortify.cli.common.json.JsonHelper; import com.fortify.cli.common.json.producer.AbstractObjectNodeProducer.AbstractObjectNodeProducerBuilder; import com.fortify.cli.common.json.producer.IObjectNodeProducer; @@ -33,6 +34,7 @@ import com.fortify.cli.common.util.Break; import com.fortify.cli.fod._common.cli.mixin.FoDAppOrReleaseMixin; import com.fortify.cli.fod._common.cli.mixin.FoDDelimiterMixin; +import com.fortify.cli.fod._common.cli.mixin.FoDFetchRangeMixin; import com.fortify.cli.fod._common.output.cli.cmd.AbstractFoDOutputCommand; import com.fortify.cli.fod._common.rest.FoDUrls; import com.fortify.cli.fod._common.rest.query.FoDFiltersParamGenerator; @@ -54,6 +56,7 @@ @Command(name = OutputHelperMixins.List.CMD_NAME) public class FoDIssueListCommand extends AbstractFoDOutputCommand implements IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.List outputHelper; + @Mixin private FoDFetchRangeMixin fetchRangeMixin; @Mixin private FoDDelimiterMixin delimiterMixin; @Mixin @Getter private FoDAppOrReleaseMixin appOrRelease; @Mixin private FoDFiltersParamMixin filterParamMixin; @@ -75,6 +78,9 @@ public class FoDIssueListCommand extends AbstractFoDOutputCommand implements ISe @Override protected IObjectNodeProducer getObjectNodeProducer(UnirestInstance unirest) { boolean releaseSpecified = appOrRelease.isReleaseSpecified(); + if (!releaseSpecified && fetchRangeMixin.isFetchSpecified()) { + throw new FcliSimpleException("--fetch cannot be combined with --app; use --release to specify a single release"); + } var result = releaseSpecified ? singleReleaseProducerBuilder(unirest, appOrRelease.getReleaseId(unirest)) : applicationProducerBuilder(unirest, appOrRelease.getAppId(unirest)); diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/microservice/cli/cmd/FoDMicroserviceListCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/microservice/cli/cmd/FoDMicroserviceListCommand.java index 04607fc76e..0f2f22c4fd 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/microservice/cli/cmd/FoDMicroserviceListCommand.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/microservice/cli/cmd/FoDMicroserviceListCommand.java @@ -16,6 +16,7 @@ import com.fasterxml.jackson.databind.node.ObjectNode; import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; import com.fortify.cli.common.output.transform.IRecordTransformer; +import com.fortify.cli.fod._common.cli.mixin.FoDFetchRangeMixin; import com.fortify.cli.fod._common.output.cli.cmd.AbstractFoDBaseRequestOutputCommand; import com.fortify.cli.fod._common.rest.FoDUrls; import com.fortify.cli.fod.app.cli.mixin.FoDAppResolverMixin; @@ -30,6 +31,7 @@ @Command(name = OutputHelperMixins.List.CMD_NAME) public class FoDMicroserviceListCommand extends AbstractFoDBaseRequestOutputCommand implements IRecordTransformer { @Getter @Mixin private OutputHelperMixins.List outputHelper; + @Mixin private FoDFetchRangeMixin fetchRangeMixin; @Mixin private FoDAppResolverMixin.RequiredOption appResolver; @Override diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/release/cli/cmd/FoDReleaseListCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/release/cli/cmd/FoDReleaseListCommand.java index 2d5fbecb5f..edc9ec2125 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/release/cli/cmd/FoDReleaseListCommand.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/release/cli/cmd/FoDReleaseListCommand.java @@ -17,6 +17,7 @@ import com.fortify.cli.common.output.transform.IRecordTransformer; import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; +import com.fortify.cli.fod._common.cli.mixin.FoDFetchRangeMixin; import com.fortify.cli.fod._common.output.cli.cmd.AbstractFoDBaseRequestOutputCommand; import com.fortify.cli.fod._common.rest.FoDUrls; import com.fortify.cli.fod._common.rest.query.FoDFiltersParamGenerator; @@ -33,6 +34,7 @@ @Command(name = OutputHelperMixins.List.CMD_NAME) public class FoDReleaseListCommand extends AbstractFoDBaseRequestOutputCommand implements IRecordTransformer, IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.List outputHelper; + @Mixin private FoDFetchRangeMixin fetchRangeMixin; @Mixin private FoDAppResolverMixin.OptionalOption appResolver; @Mixin private FoDFiltersParamMixin filterParamMixin; @Getter private IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new FoDFiltersParamGenerator() diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/release/cli/cmd/FoDReleaseScanListCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/release/cli/cmd/FoDReleaseScanListCommand.java index d9f2eb9015..aff1e77006 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/release/cli/cmd/FoDReleaseScanListCommand.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/release/cli/cmd/FoDReleaseScanListCommand.java @@ -15,6 +15,7 @@ import com.fortify.cli.common.cli.util.CommandGroup; import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; import com.fortify.cli.fod._common.cli.mixin.FoDDelimiterMixin; +import com.fortify.cli.fod._common.cli.mixin.FoDFetchRangeMixin; import com.fortify.cli.fod._common.output.cli.cmd.AbstractFoDBaseRequestOutputCommand; import com.fortify.cli.fod._common.rest.FoDUrls; import com.fortify.cli.fod._common.scan.helper.FoDScanHelper; @@ -29,6 +30,7 @@ @Command(name = "list-scans", aliases = "lss") @CommandGroup("scan") public class FoDReleaseScanListCommand extends AbstractFoDBaseRequestOutputCommand { @Getter @Mixin private OutputHelperMixins.TableWithQuery outputHelper; + @Mixin private FoDFetchRangeMixin fetchRangeMixin; @Mixin private FoDDelimiterMixin delimiterMixin; // Is automatically injected in resolver mixins @Mixin private FoDReleaseByQualifiedNameOrIdResolverMixin.RequiredOption releaseResolver; diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/report/cli/cmd/FoDReportListCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/report/cli/cmd/FoDReportListCommand.java index 2a96b9216a..748d224640 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/report/cli/cmd/FoDReportListCommand.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/report/cli/cmd/FoDReportListCommand.java @@ -15,6 +15,7 @@ import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; +import com.fortify.cli.fod._common.cli.mixin.FoDFetchRangeMixin; import com.fortify.cli.fod._common.output.cli.cmd.AbstractFoDBaseRequestOutputCommand; import com.fortify.cli.fod._common.rest.FoDUrls; import com.fortify.cli.fod._common.rest.query.FoDFiltersParamGenerator; @@ -29,6 +30,7 @@ @Command(name = OutputHelperMixins.List.CMD_NAME) public class FoDReportListCommand extends AbstractFoDBaseRequestOutputCommand implements IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.List outputHelper; + @Mixin private FoDFetchRangeMixin fetchRangeMixin; @Mixin private FoDFiltersParamMixin filterParamMixin; @Getter private IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new FoDFiltersParamGenerator() .add("id","reportId") diff --git a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/report/cli/cmd/FoDReportTemplateListCommand.java b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/report/cli/cmd/FoDReportTemplateListCommand.java index d417468b42..08410743bf 100644 --- a/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/report/cli/cmd/FoDReportTemplateListCommand.java +++ b/fcli-core/fcli-fod/src/main/java/com/fortify/cli/fod/report/cli/cmd/FoDReportTemplateListCommand.java @@ -15,6 +15,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fortify.cli.common.cli.util.CommandGroup; import com.fortify.cli.common.output.transform.IRecordTransformer; +import com.fortify.cli.fod._common.cli.mixin.FoDFetchRangeMixin; import com.fortify.cli.fod._common.output.cli.cmd.AbstractFoDBaseRequestOutputCommand; import com.fortify.cli.fod._common.output.cli.mixin.FoDOutputHelperMixins; import com.fortify.cli.fod._common.rest.FoDUrls; @@ -31,6 +32,7 @@ @Command(name = "list-templates", aliases = "lst") @CommandGroup("report-template") public final class FoDReportTemplateListCommand extends AbstractFoDBaseRequestOutputCommand implements IRecordTransformer { @Getter @Mixin private FoDOutputHelperMixins.Lookup outputHelper; + @Mixin private FoDFetchRangeMixin fetchRangeMixin; @Option(names = {"--group"}, defaultValue = "All") FoDReportTemplateGroupType groupType; diff --git a/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/_common/cli/mixin/SCDastFetchRangeMixin.java b/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/_common/cli/mixin/SCDastFetchRangeMixin.java new file mode 100644 index 0000000000..f7fedffd92 --- /dev/null +++ b/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/_common/cli/mixin/SCDastFetchRangeMixin.java @@ -0,0 +1,27 @@ +/* + * Copyright 2021-2026 Open Text. + * + * The only warranties for products and services of Open Text + * and its affiliates and licensors ("Open Text") are as may + * be set forth in the express warranty statements accompanying + * such products and services. Nothing herein should be construed + * as constituting an additional warranty. Open Text shall not be + * liable for technical or editorial errors or omissions contained + * herein. The information contained herein is subject to change + * without notice. + */ +package com.fortify.cli.sc_dast._common.cli.mixin; + +import com.fortify.cli.common.rest.cli.mixin.AbstractFetchRangeMixin; +import com.fortify.cli.common.rest.paging.FetchRange; + +import kong.unirest.HttpRequest; + +public final class SCDastFetchRangeMixin extends AbstractFetchRangeMixin { + @Override + protected HttpRequest applyFetchParams(HttpRequest request, FetchRange range) { + return request + .queryString("offset", range.offset()) + .queryString("limit", range.limit()); + } +} diff --git a/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/SCDastScanListCommand.java b/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/SCDastScanListCommand.java index 4eb717f496..7d5113dbea 100644 --- a/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/SCDastScanListCommand.java +++ b/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan/cli/cmd/SCDastScanListCommand.java @@ -13,6 +13,7 @@ package com.fortify.cli.sc_dast.scan.cli.cmd; import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; +import com.fortify.cli.sc_dast._common.cli.mixin.SCDastFetchRangeMixin; import com.fortify.cli.sc_dast._common.output.cli.cmd.AbstractSCDastBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.sc_dast.query.cli.mixin.SCDastQueryParamsMixin; @@ -25,6 +26,7 @@ @Command(name = OutputHelperMixins.List.CMD_NAME) public class SCDastScanListCommand extends AbstractSCDastBaseRequestOutputCommand { @Getter @Mixin private OutputHelperMixins.List outputHelper; + @Mixin private SCDastFetchRangeMixin fetchRangeMixin; // TODO Re-implement support for querying on scan type name based on // SCDastScanStatus.valueOf(scanStatus).getScanStatusType() // TODO Re-implement auto-generated queries based on -q / --query option diff --git a/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan_settings/cli/cmd/SCDastScanSettingsListCommand.java b/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan_settings/cli/cmd/SCDastScanSettingsListCommand.java index ff1a7f5dc3..89f27b9548 100644 --- a/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan_settings/cli/cmd/SCDastScanSettingsListCommand.java +++ b/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/scan_settings/cli/cmd/SCDastScanSettingsListCommand.java @@ -13,6 +13,7 @@ package com.fortify.cli.sc_dast.scan_settings.cli.cmd; import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; +import com.fortify.cli.sc_dast._common.cli.mixin.SCDastFetchRangeMixin; import com.fortify.cli.sc_dast._common.output.cli.cmd.AbstractSCDastBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.sc_dast.query.cli.mixin.SCDastQueryParamsMixin; @@ -25,6 +26,7 @@ @Command(name = OutputHelperMixins.List.CMD_NAME) public class SCDastScanSettingsListCommand extends AbstractSCDastBaseRequestOutputCommand { @Getter @Mixin private OutputHelperMixins.List outputHelper; + @Mixin private SCDastFetchRangeMixin fetchRangeMixin; // TODO Re-implement support for querying on scan type name based on // SCDastScanStatus.valueOf(scanStatus).getScanStatusType() // TODO Re-implement auto-generated queries based on -q / --query option diff --git a/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/sensor/cli/cmd/SCDastSensorListCommand.java b/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/sensor/cli/cmd/SCDastSensorListCommand.java index 936f15047b..3c93f67a7d 100644 --- a/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/sensor/cli/cmd/SCDastSensorListCommand.java +++ b/fcli-core/fcli-sc-dast/src/main/java/com/fortify/cli/sc_dast/sensor/cli/cmd/SCDastSensorListCommand.java @@ -13,6 +13,7 @@ package com.fortify.cli.sc_dast.sensor.cli.cmd; import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; +import com.fortify.cli.sc_dast._common.cli.mixin.SCDastFetchRangeMixin; import com.fortify.cli.sc_dast._common.output.cli.cmd.AbstractSCDastBaseRequestOutputCommand; import kong.unirest.HttpRequest; @@ -24,6 +25,7 @@ @Command(name=OutputHelperMixins.List.CMD_NAME) public class SCDastSensorListCommand extends AbstractSCDastBaseRequestOutputCommand { @Getter @Mixin private OutputHelperMixins.List outputHelper; + @Mixin private SCDastFetchRangeMixin fetchRangeMixin; public HttpRequest getBaseRequest(UnirestInstance unirest) { return unirest.get("/api/v2/scanners"); }; diff --git a/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/cmd/SCSastScanListCommand.java b/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/cmd/SCSastScanListCommand.java index 447f8d0514..e88ae61880 100644 --- a/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/cmd/SCSastScanListCommand.java +++ b/fcli-core/fcli-sc-sast/src/main/java/com/fortify/cli/sc_sast/scan/cli/cmd/SCSastScanListCommand.java @@ -21,6 +21,7 @@ import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; import com.fortify.cli.common.spel.SpelEvaluator; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamGenerator; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamValueGenerators; @@ -35,6 +36,7 @@ @Command(name = OutputHelperMixins.List.CMD_NAME) public class SCSastScanListCommand extends AbstractSSCBaseRequestOutputCommand implements IRecordTransformer, IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.List outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCQParamMixin qParamMixin; @Getter private IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new SSCQParamGenerator() .add("jobState", SSCQParamValueGenerators::plain) diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/_common/cli/mixin/SSCFetchRangeMixin.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/_common/cli/mixin/SSCFetchRangeMixin.java new file mode 100644 index 0000000000..7a5fac9064 --- /dev/null +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/_common/cli/mixin/SSCFetchRangeMixin.java @@ -0,0 +1,27 @@ +/* + * Copyright 2021-2026 Open Text. + * + * The only warranties for products and services of Open Text + * and its affiliates and licensors ("Open Text") are as may + * be set forth in the express warranty statements accompanying + * such products and services. Nothing herein should be construed + * as constituting an additional warranty. Open Text shall not be + * liable for technical or editorial errors or omissions contained + * herein. The information contained herein is subject to change + * without notice. + */ +package com.fortify.cli.ssc._common.cli.mixin; + +import com.fortify.cli.common.rest.cli.mixin.AbstractFetchRangeMixin; +import com.fortify.cli.common.rest.paging.FetchRange; + +import kong.unirest.HttpRequest; + +public final class SSCFetchRangeMixin extends AbstractFetchRangeMixin { + @Override + protected HttpRequest applyFetchParams(HttpRequest request, FetchRange range) { + return request + .queryString("start", range.offset()) + .queryString("limit", range.limit()); + } +} diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/_common/rest/ssc/helper/SSCProductHelper.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/_common/rest/ssc/helper/SSCProductHelper.java index 4c5d7c1a2c..0ba07d5bfd 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/_common/rest/ssc/helper/SSCProductHelper.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/_common/rest/ssc/helper/SSCProductHelper.java @@ -13,14 +13,17 @@ package com.fortify.cli.ssc._common.rest.ssc.helper; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fortify.cli.common.json.JsonHelper; import com.fortify.cli.common.output.product.IProductHelper; +import com.fortify.cli.common.output.product.IResponseMetadataCollector; import com.fortify.cli.common.output.transform.IInputTransformer; import com.fortify.cli.common.rest.paging.INextPageUrlProducer; import com.fortify.cli.common.rest.paging.INextPageUrlProducerSupplier; //IMPORTANT: When updating/adding any methods in this class, SSCRestCallCommand //also likely needs to be updated -public class SSCProductHelper implements IProductHelper, IInputTransformer, INextPageUrlProducerSupplier +public class SSCProductHelper implements IProductHelper, IInputTransformer, INextPageUrlProducerSupplier, IResponseMetadataCollector { public static final SSCProductHelper INSTANCE = new SSCProductHelper(); private SSCProductHelper() {} @@ -33,4 +36,17 @@ public INextPageUrlProducer getNextPageUrlProducer() { public JsonNode transformInput(JsonNode input) { return SSCInputTransformer.getDataOrSelf(input); } + + @Override + public ObjectNode collectResponseMetadata(JsonNode responseBody) { + if ( responseBody==null || !responseBody.has("data") ) { return null; } + var metadata = JsonHelper.getObjectMapper().createObjectNode(); + if ( responseBody.has("count") ) { + metadata.set("totalCount", responseBody.get("count")); + } + if ( responseBody.has("links") ) { + metadata.set("links", responseBody.get("links")); + } + return metadata.isEmpty() ? null : metadata; + } } diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCAppVersionUserListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCAppVersionUserListCommand.java index 51438b4124..6bd430ee6c 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCAppVersionUserListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCAppVersionUserListCommand.java @@ -14,6 +14,7 @@ import com.fortify.cli.common.cli.util.CommandGroup; import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; import com.fortify.cli.ssc.appversion.cli.mixin.SSCAppVersionResolverMixin; @@ -27,6 +28,7 @@ @Command(name = "list-appversion-users", aliases = "lsavu") @CommandGroup("appversion-user") public class SSCAppVersionUserListCommand extends AbstractSSCBaseRequestOutputCommand { @Getter @Mixin private OutputHelperMixins.TableWithQuery outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCAppVersionResolverMixin.RequiredOption parentResolver; // TODO Can we do any server-side filtering? diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCPermissionListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCPermissionListCommand.java index d85d8bed34..82a77964eb 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCPermissionListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCPermissionListCommand.java @@ -18,6 +18,7 @@ import com.fortify.cli.common.cli.util.CommandGroup; import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; import com.fortify.cli.common.output.transform.IRecordTransformer; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; import com.fortify.cli.ssc.access_control.cli.mixin.SSCRoleResolverMixin; @@ -32,6 +33,7 @@ @Command(name = "list-permissions", aliases = {"lsp"}) @CommandGroup("permission") public class SSCPermissionListCommand extends AbstractSSCBaseRequestOutputCommand implements IRecordTransformer { @Getter @Mixin private OutputHelperMixins.TableWithQuery outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCRoleResolverMixin.OptionalOption roleResolverMixin; @Override diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCRoleListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCRoleListCommand.java index 0cac8ef629..39ee841a28 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCRoleListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCRoleListCommand.java @@ -16,6 +16,7 @@ import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamGenerator; @@ -31,6 +32,7 @@ @Command(name = "list-roles", aliases = "lsr") @CommandGroup("role") public class SSCRoleListCommand extends AbstractSSCBaseRequestOutputCommand implements IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.TableWithQuery outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCQParamMixin qParamMixin; @Getter private IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new SSCQParamGenerator() .add("id", SSCQParamValueGenerators::plain) diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCTokenDefinitionListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCTokenDefinitionListCommand.java index 2b0c8683ae..dfd5a8d7b3 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCTokenDefinitionListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCTokenDefinitionListCommand.java @@ -16,6 +16,7 @@ import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamGenerator; @@ -31,6 +32,7 @@ @Command(name = "list-token-definitions", aliases = "lstd") @CommandGroup("token-definition") public class SSCTokenDefinitionListCommand extends AbstractSSCBaseRequestOutputCommand implements IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.TableWithQuery outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCQParamMixin qParamMixin; @Getter private IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new SSCQParamGenerator() .add("type", SSCQParamValueGenerators::wrapInQuotes) diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCUserListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCUserListCommand.java index 629c6a90fb..280b28e9aa 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCUserListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/access_control/cli/cmd/SSCUserListCommand.java @@ -16,6 +16,7 @@ import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamGenerator; @@ -31,6 +32,7 @@ @Command(name = "list-users", aliases = "lsu") @CommandGroup("user") public class SSCUserListCommand extends AbstractSSCBaseRequestOutputCommand implements IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.TableWithQuery outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCQParamMixin qParamMixin; @Getter private IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new SSCQParamGenerator() .add("id", SSCQParamValueGenerators::plain) diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/alert/cli/cmd/SSCAlertDefinitionListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/alert/cli/cmd/SSCAlertDefinitionListCommand.java index 07770061b6..3719036346 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/alert/cli/cmd/SSCAlertDefinitionListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/alert/cli/cmd/SSCAlertDefinitionListCommand.java @@ -16,6 +16,7 @@ import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamGenerator; @@ -31,6 +32,7 @@ @Command(name = OutputHelperMixins.ListDefinitions.CMD_NAME) @CommandGroup("definition") public class SSCAlertDefinitionListCommand extends AbstractSSCBaseRequestOutputCommand implements IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.ListDefinitions outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCQParamMixin qParamMixin; @Getter private IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new SSCQParamGenerator() .add("id", SSCQParamValueGenerators::plain) diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/alert/cli/cmd/SSCAlertListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/alert/cli/cmd/SSCAlertListCommand.java index 168fa205dc..6f0a7f6fff 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/alert/cli/cmd/SSCAlertListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/alert/cli/cmd/SSCAlertListCommand.java @@ -18,6 +18,7 @@ import com.fortify.cli.common.output.transform.IRecordTransformer; import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamGenerator; @@ -33,6 +34,7 @@ @Command(name = OutputHelperMixins.List.CMD_NAME) public class SSCAlertListCommand extends AbstractSSCBaseRequestOutputCommand implements IRecordTransformer, IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.List outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCQParamMixin qParamMixin; @Getter private IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new SSCQParamGenerator() .add("id", SSCQParamValueGenerators::plain) diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/app/cli/cmd/SSCAppListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/app/cli/cmd/SSCAppListCommand.java index 05c89d7c8c..70bf2d28eb 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/app/cli/cmd/SSCAppListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/app/cli/cmd/SSCAppListCommand.java @@ -15,6 +15,7 @@ import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamGenerator; @@ -30,6 +31,7 @@ @Command(name = OutputHelperMixins.List.CMD_NAME) public class SSCAppListCommand extends AbstractSSCBaseRequestOutputCommand implements IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.List outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCQParamMixin qParamMixin; @Getter private IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new SSCQParamGenerator() .add("id", SSCQParamValueGenerators::plain) diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/cmd/SSCAppVersionListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/cmd/SSCAppVersionListCommand.java index eb12ee9c43..1485a47fac 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/cmd/SSCAppVersionListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/cmd/SSCAppVersionListCommand.java @@ -17,6 +17,7 @@ import com.fortify.cli.common.output.transform.IRecordTransformer; import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamGenerator; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamValueGenerators; @@ -35,6 +36,7 @@ @Command(name = OutputHelperMixins.List.CMD_NAME) public class SSCAppVersionListCommand extends AbstractSSCBaseRequestOutputCommand implements IRecordTransformer, IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.List outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCQParamMixin qParamMixin; @Getter private IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new SSCQParamGenerator() .add("id", SSCQParamValueGenerators::plain) @@ -47,7 +49,7 @@ public class SSCAppVersionListCommand extends AbstractSSCBaseRequestOutputComman @Override public HttpRequest getBaseRequest(UnirestInstance unirest) { - return unirest.get("/api/v1/projectVersions?limit=100"); + return unirest.get("/api/v1/projectVersions"); } @Override diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/artifact/cli/cmd/SSCArtifactListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/artifact/cli/cmd/SSCArtifactListCommand.java index a60f83d639..a7dbcec53e 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/artifact/cli/cmd/SSCArtifactListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/artifact/cli/cmd/SSCArtifactListCommand.java @@ -14,6 +14,7 @@ import com.fortify.cli.common.output.cli.cmd.IBaseRequestSupplier; import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; import com.fortify.cli.ssc.appversion.cli.mixin.SSCAppVersionResolverMixin; @@ -25,6 +26,7 @@ @Command(name = OutputHelperMixins.List.CMD_NAME) public class SSCArtifactListCommand extends AbstractSSCArtifactOutputCommand implements IBaseRequestSupplier { @Getter @Mixin private OutputHelperMixins.List outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCAppVersionResolverMixin.RequiredOption parentResolver; @Override diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/attribute/cli/cmd/SSCAttributeDefinitionListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/attribute/cli/cmd/SSCAttributeDefinitionListCommand.java index b3c6061540..cfda0aae17 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/attribute/cli/cmd/SSCAttributeDefinitionListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/attribute/cli/cmd/SSCAttributeDefinitionListCommand.java @@ -16,6 +16,7 @@ import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamGenerator; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamValueGenerators; @@ -30,6 +31,7 @@ @Command(name = OutputHelperMixins.ListDefinitions.CMD_NAME) @CommandGroup("definition") public class SSCAttributeDefinitionListCommand extends AbstractSSCBaseRequestOutputCommand implements IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.ListDefinitions outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCQParamMixin qParamMixin; @Getter private IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new SSCQParamGenerator() .add("id", SSCQParamValueGenerators::plain) @@ -41,7 +43,7 @@ public class SSCAttributeDefinitionListCommand extends AbstractSSCBaseRequestOut @Override public HttpRequest getBaseRequest(UnirestInstance unirest) { - return unirest.get("/api/v1/attributeDefinitions?limit=100&orderby=category,name"); + return unirest.get("/api/v1/attributeDefinitions?orderby=category,name"); } @Override diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/issue/cli/cmd/SSCIssueFilterSetListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/issue/cli/cmd/SSCIssueFilterSetListCommand.java index ffeb25a7a3..3b5c9e6911 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/issue/cli/cmd/SSCIssueFilterSetListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/issue/cli/cmd/SSCIssueFilterSetListCommand.java @@ -14,6 +14,7 @@ import com.fortify.cli.common.cli.util.CommandGroup; import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; import com.fortify.cli.ssc.appversion.cli.mixin.SSCAppVersionResolverMixin; @@ -27,6 +28,7 @@ @Command(name = "list-filtersets", aliases = {"lsfs"}) @CommandGroup("filter-set") public class SSCIssueFilterSetListCommand extends AbstractSSCBaseRequestOutputCommand { @Getter @Mixin private OutputHelperMixins.TableWithQuery outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCAppVersionResolverMixin.RequiredOption parentResolver; @Override diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/issue/cli/cmd/SSCIssueListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/issue/cli/cmd/SSCIssueListCommand.java index 1cc5a0401d..0d2c63363a 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/issue/cli/cmd/SSCIssueListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/issue/cli/cmd/SSCIssueListCommand.java @@ -23,6 +23,7 @@ import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamGenerator; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamValueGenerators; @@ -45,6 +46,7 @@ @Command(name = OutputHelperMixins.List.CMD_NAME) public class SSCIssueListCommand extends AbstractSSCOutputCommand implements IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.List outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCAppVersionResolverMixin.RequiredOption parentResolver; @Mixin private SSCIssueFilterSetResolverMixin.FilterSetOption filterSetResolver; @Mixin private SSCQParamMixin qParamMixin; @@ -70,7 +72,7 @@ protected IObjectNodeProducer getObjectNodeProducer(UnirestInstance unirest) { } public HttpRequest getBaseRequest(UnirestInstance unirest, String appVersionId, SSCIssueFilterSetDescriptor filterSetDescriptor) { - GetRequest request = unirest.get("/api/v1/projectVersions/{id}/issues?limit=100&qm=issues") + GetRequest request = unirest.get("/api/v1/projectVersions/{id}/issues?qm=issues") .routeParam("id", appVersionId); if ( filterSetDescriptor!=null ) { request.queryString("filterset", filterSetDescriptor.getGuid()); diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/issue_template/cli/cmd/AbstractSSCIssueTemplateListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/issue_template/cli/cmd/AbstractSSCIssueTemplateListCommand.java index 92bf9f2233..eae41505e4 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/issue_template/cli/cmd/AbstractSSCIssueTemplateListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/issue_template/cli/cmd/AbstractSSCIssueTemplateListCommand.java @@ -14,6 +14,7 @@ import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamGenerator; @@ -25,6 +26,7 @@ import picocli.CommandLine.Mixin; public abstract class AbstractSSCIssueTemplateListCommand extends AbstractSSCBaseRequestOutputCommand implements IServerSideQueryParamGeneratorSupplier { + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin protected SSCQParamMixin qParamMixin; protected IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new SSCQParamGenerator() .add("id", SSCQParamValueGenerators::plain) diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/performance_indicator/cli/cmd/SSCPerformanceIndicatorDefinitionListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/performance_indicator/cli/cmd/SSCPerformanceIndicatorDefinitionListCommand.java index 4a4cba7113..cb38d452ae 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/performance_indicator/cli/cmd/SSCPerformanceIndicatorDefinitionListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/performance_indicator/cli/cmd/SSCPerformanceIndicatorDefinitionListCommand.java @@ -14,6 +14,7 @@ import com.fortify.cli.common.cli.util.CommandGroup; import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; @@ -26,6 +27,7 @@ @Command(name = OutputHelperMixins.ListDefinitions.CMD_NAME) @CommandGroup("definition") public class SSCPerformanceIndicatorDefinitionListCommand extends AbstractSSCBaseRequestOutputCommand { @Getter @Mixin private OutputHelperMixins.ListDefinitions outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Override public HttpRequest getBaseRequest(UnirestInstance unirest) { diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/performance_indicator/cli/cmd/SSCPerformanceIndicatorListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/performance_indicator/cli/cmd/SSCPerformanceIndicatorListCommand.java index ab100fb43f..e2977ac9bb 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/performance_indicator/cli/cmd/SSCPerformanceIndicatorListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/performance_indicator/cli/cmd/SSCPerformanceIndicatorListCommand.java @@ -15,6 +15,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; import com.fortify.cli.common.output.transform.IRecordTransformer; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; import com.fortify.cli.ssc.appversion.cli.mixin.SSCAppVersionResolverMixin; @@ -29,6 +30,7 @@ @Command(name = OutputHelperMixins.List.CMD_NAME) public class SSCPerformanceIndicatorListCommand extends AbstractSSCBaseRequestOutputCommand implements IRecordTransformer { @Getter @Mixin private OutputHelperMixins.List outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCAppVersionResolverMixin.RequiredOption parentResolver; @Override diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/plugin/cli/cmd/SSCPluginListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/plugin/cli/cmd/SSCPluginListCommand.java index fbbe727170..32319fd6a8 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/plugin/cli/cmd/SSCPluginListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/plugin/cli/cmd/SSCPluginListCommand.java @@ -14,6 +14,7 @@ import com.fortify.cli.common.mcp.MCPInclude; import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import kong.unirest.HttpRequest; @@ -26,11 +27,12 @@ @Command(name = OutputHelperMixins.List.CMD_NAME) public class SSCPluginListCommand extends AbstractSSCBaseRequestOutputCommand { @Getter @Mixin private OutputHelperMixins.List outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; // TODO Can we do any server-side filtering? @Override public HttpRequest getBaseRequest(UnirestInstance unirest) { - return unirest.get("/api/v1/plugins?orderBy=pluginType,pluginName,pluginVersion&limit=100"); + return unirest.get("/api/v1/plugins?orderBy=pluginType,pluginName,pluginVersion"); } @Override diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/report/cli/cmd/SSCReportListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/report/cli/cmd/SSCReportListCommand.java index 0baeeb9b29..135a6dde38 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/report/cli/cmd/SSCReportListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/report/cli/cmd/SSCReportListCommand.java @@ -17,6 +17,7 @@ import com.fortify.cli.common.output.transform.IRecordTransformer; import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamGenerator; @@ -33,6 +34,7 @@ @Command(name = OutputHelperMixins.List.CMD_NAME) public class SSCReportListCommand extends AbstractSSCBaseRequestOutputCommand implements IRecordTransformer, IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.List outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCQParamMixin qParamMixin; @Getter private IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new SSCQParamGenerator() .add("id", SSCQParamValueGenerators::plain) diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/report/cli/cmd/SSCReportTemplateListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/report/cli/cmd/SSCReportTemplateListCommand.java index ec41a898b6..84bb395ad5 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/report/cli/cmd/SSCReportTemplateListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/report/cli/cmd/SSCReportTemplateListCommand.java @@ -14,6 +14,7 @@ import com.fortify.cli.common.cli.util.CommandGroup; import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; @@ -26,6 +27,7 @@ @Command(name = OutputHelperMixins.ListTemplates.CMD_NAME) @CommandGroup("template") public class SSCReportTemplateListCommand extends AbstractSSCBaseRequestOutputCommand { @Getter @Mixin private OutputHelperMixins.ListTemplates outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; // TODO Can we do any server-side filtering? @Override diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/system_state/cli/cmd/SSCStateActivitiesListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/system_state/cli/cmd/SSCStateActivitiesListCommand.java index c50ade3a53..8d89e8334a 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/system_state/cli/cmd/SSCStateActivitiesListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/system_state/cli/cmd/SSCStateActivitiesListCommand.java @@ -19,6 +19,7 @@ import com.fortify.cli.common.output.transform.IRecordTransformer; import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamGenerator; @@ -34,6 +35,7 @@ @Command(name = "list-activities", aliases = {"lsa"}) @CommandGroup("activity") public class SSCStateActivitiesListCommand extends AbstractSSCBaseRequestOutputCommand implements IRecordTransformer, IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.TableWithQuery outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCQParamMixin qParamMixin; @Getter private IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new SSCQParamGenerator() .add("userName", SSCQParamValueGenerators::wrapInQuotes) diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/system_state/cli/cmd/SSCStateEventListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/system_state/cli/cmd/SSCStateEventListCommand.java index b46a5c9a53..337abcbb28 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/system_state/cli/cmd/SSCStateEventListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/system_state/cli/cmd/SSCStateEventListCommand.java @@ -19,6 +19,7 @@ import com.fortify.cli.common.output.transform.IRecordTransformer; import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamGenerator; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamValueGenerators; @@ -33,6 +34,7 @@ @Command(name = "list-events", aliases = {"lse"}) @CommandGroup("event") public class SSCStateEventListCommand extends AbstractSSCBaseRequestOutputCommand implements IRecordTransformer, IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.TableWithQuery outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCQParamMixin qParamMixin; @Getter private IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new SSCQParamGenerator() .add("userName", SSCQParamValueGenerators::wrapInQuotes) @@ -48,7 +50,7 @@ public JsonNode transformRecord(JsonNode record) { @Override public HttpRequest getBaseRequest(UnirestInstance unirest) { - return unirest.get("/api/v1/events?limit=100"); + return unirest.get("/api/v1/events"); } @Override diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/system_state/cli/cmd/SSCStateJobListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/system_state/cli/cmd/SSCStateJobListCommand.java index 4e6816ebf4..5b9f9c6a9a 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/system_state/cli/cmd/SSCStateJobListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/system_state/cli/cmd/SSCStateJobListCommand.java @@ -16,6 +16,7 @@ import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; import com.fortify.cli.common.rest.query.IServerSideQueryParamGeneratorSupplier; import com.fortify.cli.common.rest.query.IServerSideQueryParamValueGenerator; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; import com.fortify.cli.ssc._common.rest.ssc.query.SSCQParamGenerator; @@ -31,6 +32,7 @@ @Command(name = "list-jobs", aliases = {"lsj"}) @CommandGroup("job") public class SSCStateJobListCommand extends AbstractSSCBaseRequestOutputCommand implements IServerSideQueryParamGeneratorSupplier { @Getter @Mixin private OutputHelperMixins.TableWithQuery outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCQParamMixin qParamMixin; @Getter private IServerSideQueryParamValueGenerator serverSideQueryParamGenerator = new SSCQParamGenerator() .add("jobClass", SSCQParamValueGenerators::wrapInQuotes) diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/system_state/cli/cmd/SSCStateRulepackListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/system_state/cli/cmd/SSCStateRulepackListCommand.java index 694f1e03fc..01e9b29c75 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/system_state/cli/cmd/SSCStateRulepackListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/system_state/cli/cmd/SSCStateRulepackListCommand.java @@ -14,6 +14,7 @@ import com.fortify.cli.common.cli.util.CommandGroup; import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import kong.unirest.HttpRequest; @@ -25,6 +26,7 @@ @Command(name = "list-rulepacks", aliases = {"lsr"}) @CommandGroup("rulepack") public class SSCStateRulepackListCommand extends AbstractSSCBaseRequestOutputCommand { @Getter @Mixin private OutputHelperMixins.TableWithQuery outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Override public HttpRequest getBaseRequest(UnirestInstance unirest) { diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/variable/cli/cmd/SSCVariableDefinitionListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/variable/cli/cmd/SSCVariableDefinitionListCommand.java index 649473876b..3082ca50fc 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/variable/cli/cmd/SSCVariableDefinitionListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/variable/cli/cmd/SSCVariableDefinitionListCommand.java @@ -14,6 +14,7 @@ import com.fortify.cli.common.cli.util.CommandGroup; import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; @@ -26,6 +27,7 @@ @Command(name = OutputHelperMixins.ListDefinitions.CMD_NAME) @CommandGroup("definition") public class SSCVariableDefinitionListCommand extends AbstractSSCBaseRequestOutputCommand { @Getter @Mixin private OutputHelperMixins.ListDefinitions outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Override public HttpRequest getBaseRequest(UnirestInstance unirest) { diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/variable/cli/cmd/SSCVariableListCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/variable/cli/cmd/SSCVariableListCommand.java index 7d8ffdfe04..16acda5b88 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/variable/cli/cmd/SSCVariableListCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/variable/cli/cmd/SSCVariableListCommand.java @@ -13,6 +13,7 @@ package com.fortify.cli.ssc.variable.cli.cmd; import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; +import com.fortify.cli.ssc._common.cli.mixin.SSCFetchRangeMixin; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCBaseRequestOutputCommand; import com.fortify.cli.ssc._common.rest.ssc.SSCUrls; import com.fortify.cli.ssc.appversion.cli.mixin.SSCAppVersionResolverMixin; @@ -26,6 +27,7 @@ @Command(name = OutputHelperMixins.List.CMD_NAME) public class SSCVariableListCommand extends AbstractSSCBaseRequestOutputCommand { @Getter @Mixin private OutputHelperMixins.List outputHelper; + @Mixin private SSCFetchRangeMixin fetchRangeMixin; @Mixin private SSCAppVersionResolverMixin.RequiredOption parentResolver; @Override diff --git a/gradle.properties b/gradle.properties index 52da247657..4adf83d589 100644 --- a/gradle.properties +++ b/gradle.properties @@ -46,7 +46,7 @@ fcliMainClassName=com.fortify.cli.app.FortifyCLI # given schema version, it is very important to maintain this correctly. At all cost, # we should avoid for example updating only patch version if there are any structural # changes. -fcliActionSchemaVersion=2.7.0 +fcliActionSchemaVersion=2.8.0 org.gradle.parallel=true # Ensure JDK IO subsystem is opened for all Gradle daemon JVM processes (suppresses native subprocess control warning)