diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/_common/rest/SSCUrls.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/_common/rest/SSCUrls.java index 0914149168..e47aba5d75 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/_common/rest/SSCUrls.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/_common/rest/SSCUrls.java @@ -236,6 +236,9 @@ public static String PLUGIN(String pluginId) { } public static final String PORTLETS_ISSUE_AGING = ApiBase + "/portlets/issueaging"; public static final String PROJECT_VERSIONS = ApiBase + "/projectVersions"; + public static String PROJECT_VERSIONS_ACTION(String projectVersionId) { + return String.format(ApiBase + "/projectVersions/%s/action", projectVersionId); + } public static final String PROJECT_VERSIONS_ACTION_AUDIT_BY_AUDIT_ASSISTANT = ApiBase + "/projectVersions/action/auditByAuditAssistant"; public static final String PROJECT_VERSIONS_ACTION_COPY_CURRENT_STATE = ApiBase + "/projectVersions/action/copyCurrentState"; public static final String PROJECT_VERSIONS_ACTION_COPY_FROM_PARTIAL = ApiBase + "/projectVersions/action/copyFromPartial"; diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/cmd/SSCAppVersionCopyStateCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/cmd/SSCAppVersionCopyStateCommand.java index d54a68843e..8c63262cb3 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/cmd/SSCAppVersionCopyStateCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/cmd/SSCAppVersionCopyStateCommand.java @@ -12,20 +12,23 @@ *******************************************************************************/ package com.fortify.cli.ssc.appversion.cli.cmd; -import java.util.HashMap; - import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fortify.cli.common.json.JsonHelper; import com.fortify.cli.common.output.cli.cmd.IJsonNodeSupplier; import com.fortify.cli.common.output.cli.mixin.OutputHelperMixins; import com.fortify.cli.common.output.transform.IActionCommandResultSupplier; import com.fortify.cli.common.output.transform.IRecordTransformer; import com.fortify.cli.ssc._common.output.cli.cmd.AbstractSSCJsonNodeOutputCommand; import com.fortify.cli.ssc._common.rest.SSCUrls; +import com.fortify.cli.ssc.appversion.cli.mixin.SSCAppVersionRefreshOptions; import com.fortify.cli.ssc.appversion.cli.mixin.SSCDelimiterMixin; import com.fortify.cli.ssc.appversion.helper.SSCAppVersionDescriptor; import com.fortify.cli.ssc.appversion.helper.SSCAppVersionHelper; +import com.fortify.cli.ssc.system_state.helper.SSCJobDescriptor; +import com.fortify.cli.ssc.system_state.helper.SSCJobHelper; import kong.unirest.UnirestInstance; import lombok.Getter; import picocli.CommandLine.Command; @@ -37,15 +40,13 @@ public class SSCAppVersionCopyStateCommand extends AbstractSSCJsonNodeOutputComm @Getter @Mixin private OutputHelperMixins.TableNoQuery outputHelper; - @Getter @Mixin private SSCDelimiterMixin delimiterMixin; - + @Mixin private SSCAppVersionRefreshOptions refreshOptions; @Option(names = {"--copy-from", "--from"}, required = true, descriptionKey = "fcli.ssc.appversion.resolver.copy-from.nameOrId") @Getter private String fromAppVersionNameOrId; - @Option(names = {"--copy-to", "--to"}, required = true, descriptionKey = "fcli.ssc.appversion.resolver.copy-to.nameOrId") @Getter private String toAppVersionNameOrId; @@ -56,6 +57,11 @@ public JsonNode getJsonNode(UnirestInstance unirest) { SSCAppVersionDescriptor fromAppVersionDescriptor = SSCAppVersionHelper.getRequiredAppVersion(unirest, getFromAppVersionNameOrId(), delimiterMixin.getDelimiter()); SSCAppVersionDescriptor toAppVersionDescriptor = SSCAppVersionHelper.getRequiredAppVersion(unirest, getToAppVersionNameOrId(), delimiterMixin.getDelimiter()); + if(refreshOptions.isRefresh() && fromAppVersionDescriptor.isRefreshRequired()){ + SSCJobDescriptor refreshJobDesc = SSCAppVersionHelper.refreshMetrics(unirest, fromAppVersionDescriptor); + SSCJobHelper.waitForJob(unirest,refreshJobDesc); + } + return mapper.valueToTree(copyState(unirest, fromAppVersionDescriptor, toAppVersionDescriptor)); } @@ -75,16 +81,19 @@ public boolean isSingular() { return true; } - private static final HashMap copyState(UnirestInstance unirest, SSCAppVersionDescriptor sourceAppVersion, SSCAppVersionDescriptor targetAppVersion) { - HashMap appVersionIds = new HashMap(); - appVersionIds.put("previousProjectVersionId", sourceAppVersion.getVersionId()); - appVersionIds.put("projectVersionId", targetAppVersion.getVersionId()); + private static final JsonNode copyState(UnirestInstance unirest, SSCAppVersionDescriptor fromAppVersionDescriptor, SSCAppVersionDescriptor toAppVersionDescriptor) { + ObjectNode copyStateOptions = JsonHelper.getObjectMapper().createObjectNode(); + copyStateOptions.put("previousProjectVersionId", fromAppVersionDescriptor.getIntVersionId()); + copyStateOptions.put("projectVersionId", toAppVersionDescriptor.getIntVersionId()); + + ObjectNode body = JsonHelper.getObjectMapper().createObjectNode(); + body .put("type", "copy_current_state") + .set("values", copyStateOptions); - unirest.post(SSCUrls.PROJECT_VERSIONS_ACTION_COPY_CURRENT_STATE) - .body(appVersionIds) + unirest .post(SSCUrls.PROJECT_VERSIONS_ACTION(toAppVersionDescriptor.getVersionId())) + .body(body) .asObject(JsonNode.class).getBody(); - return appVersionIds; + return copyStateOptions; } - } diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/cmd/SSCAppVersionCreateCommand.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/cmd/SSCAppVersionCreateCommand.java index 69b0270526..cf704bfb0f 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/cmd/SSCAppVersionCreateCommand.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/cmd/SSCAppVersionCreateCommand.java @@ -31,6 +31,7 @@ import com.fortify.cli.ssc.app.helper.SSCAppHelper; import com.fortify.cli.ssc.appversion.cli.mixin.SSCAppAndVersionNameResolverMixin; import com.fortify.cli.ssc.appversion.cli.mixin.SSCAppVersionCopyFromMixin; +import com.fortify.cli.ssc.appversion.cli.mixin.SSCAppVersionRefreshOptions; import com.fortify.cli.ssc.appversion.helper.SSCAppAndVersionNameDescriptor; import com.fortify.cli.ssc.appversion.helper.SSCAppVersionCreateCopyFromBuilder; import com.fortify.cli.ssc.appversion.helper.SSCAppVersionDescriptor; @@ -40,6 +41,8 @@ import com.fortify.cli.ssc.issue.cli.mixin.SSCIssueTemplateResolverMixin; import com.fortify.cli.ssc.issue.helper.SSCIssueTemplateDescriptor; +import com.fortify.cli.ssc.system_state.helper.SSCJobDescriptor; +import com.fortify.cli.ssc.system_state.helper.SSCJobHelper; import kong.unirest.HttpRequest; import kong.unirest.UnirestInstance; import lombok.Getter; @@ -49,17 +52,18 @@ @Command(name = OutputHelperMixins.Create.CMD_NAME) public class SSCAppVersionCreateCommand extends AbstractSSCJsonNodeOutputCommand implements IRecordTransformer, IActionCommandResultSupplier { - @Getter @Mixin private OutputHelperMixins.Create outputHelper; private final ObjectMapper objectMapper = new ObjectMapper(); + @Getter @Mixin private OutputHelperMixins.Create outputHelper; @Mixin private SSCAppAndVersionNameResolverMixin.PositionalParameter sscAppAndVersionNameResolver; @Mixin private SSCIssueTemplateResolverMixin.OptionalOption issueTemplateResolver; @Mixin private SSCAttributeUpdateMixin.OptionalAttrOption attrUpdateMixin; @Mixin private SSCAppVersionUserMixin.OptionalUserAddOption userAddMixin; + @Mixin private SSCAppVersionCopyFromMixin copyFromMixin; + @Mixin private SSCAppVersionRefreshOptions refreshOptions; @Option(names={"--description","-d"}, required = false) private String description; @Option(names={"--active"}, required = false, defaultValue="true", arity="1") private boolean active; - @Mixin private SSCAppVersionCopyFromMixin copyFromMixin; @Option(names={"--auto-required-attrs"}, required = false) private boolean autoRequiredAttrs = false; @Option(names={"--skip-if-exists"}, required = false) @@ -73,9 +77,11 @@ public JsonNode getJsonNode(UnirestInstance unirest) { } SSCAttributeUpdateBuilder attrUpdateBuilder = getAttrUpdateBuilder(unirest); SSCAppVersionUserUpdateBuilder authUpdateBuilder = getAuthUpdateBuilder(unirest); - SSCAppVersionCreateCopyFromBuilder copyFromBuilder = getCopyFromBuilder(unirest); SSCAppVersionDescriptor descriptor = createUncommittedAppVersion(unirest); + + SSCAppVersionCreateCopyFromBuilder copyFromBuilder = getCopyFromBuilder(unirest); + SSCBulkResponse bulkResponse = new SSCBulkRequestBuilder() .request("attrUpdate", attrUpdateBuilder.buildRequest(descriptor.getVersionId())) .request("userUpdate", authUpdateBuilder.buildRequest(descriptor.getVersionId())) @@ -105,9 +111,19 @@ public boolean isSingular() { private final SSCAppVersionCreateCopyFromBuilder getCopyFromBuilder(UnirestInstance unirest) { SSCAppVersionCreateCopyFromBuilder builder = new SSCAppVersionCreateCopyFromBuilder(unirest); if(copyFromMixin.isCopyRequested()) { + SSCAppVersionDescriptor fromAppVersionDesc = SSCAppVersionHelper.getRequiredAppVersion(unirest, copyFromMixin.getAppVersionNameOrId(), sscAppAndVersionNameResolver.getDelimiter()); + builder .setCopyRequested(true) - .setCopyFrom(SSCAppVersionHelper.getRequiredAppVersion(unirest, copyFromMixin.getAppVersionNameOrId(), sscAppAndVersionNameResolver.getDelimiter())) + .setCopyFrom(fromAppVersionDesc) .setCopyOptions(copyFromMixin.getCopyOptions()); + + // refreshMetrics if the source PV is required to fully copy the tags, audit or comments + if(builder.copyStateEnabled() + && refreshOptions.isRefresh() + && fromAppVersionDesc.isRefreshRequired()){ + SSCJobDescriptor refreshJobDesc = SSCAppVersionHelper.refreshMetrics(unirest, fromAppVersionDesc); + SSCJobHelper.waitForJob(unirest,refreshJobDesc); + } } return builder; diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/mixin/SSCAppVersionRefreshOptions.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/mixin/SSCAppVersionRefreshOptions.java new file mode 100644 index 0000000000..88fa380b84 --- /dev/null +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/cli/mixin/SSCAppVersionRefreshOptions.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright 2021, 2023 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.appversion.cli.mixin; + +import com.fortify.cli.common.cli.mixin.CommonOptionMixins; +import lombok.Getter; +import picocli.CommandLine.Mixin; +import picocli.CommandLine.Option; + +@Getter +public class SSCAppVersionRefreshOptions { + @Option(names = "--refresh", negatable = true, descriptionKey = "fcli.ssc.appversion.create.refresh", + defaultValue = "true", fallbackValue = "true") + private boolean refresh; +} diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/helper/SSCAppVersionCreateCopyFromBuilder.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/helper/SSCAppVersionCreateCopyFromBuilder.java index 91a9334265..374edd0072 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/helper/SSCAppVersionCreateCopyFromBuilder.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/helper/SSCAppVersionCreateCopyFromBuilder.java @@ -12,11 +12,9 @@ *******************************************************************************/ package com.fortify.cli.ssc.appversion.helper; -import java.util.HashMap; - +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.fortify.cli.common.json.JsonHelper; import com.fortify.cli.ssc._common.rest.SSCUrls; -import com.fortify.cli.ssc.system_state.helper.SSCJobDescriptor; -import com.fortify.cli.ssc.system_state.helper.SSCJobHelper; import kong.unirest.HttpRequest; import kong.unirest.UnirestInstance; @@ -24,29 +22,18 @@ public final class SSCAppVersionCreateCopyFromBuilder { private final UnirestInstance unirest; - private HashMap copyFromPartialOptions = new HashMap(); - private HashMap copyStateOptions = new HashMap(); + private ObjectNode copyFromPartialOptions = JsonHelper.getObjectMapper().createObjectNode(); + private ObjectNode copyStateOptions = JsonHelper.getObjectMapper().createObjectNode(); private SSCAppVersionDescriptor previousProjectVersion; private boolean copyRequested = false; - private boolean copyState; + private boolean copyState = false; public SSCAppVersionCreateCopyFromBuilder(UnirestInstance unirest) { this.unirest = unirest; } - public final HttpRequest buildCopyFromRefreshRequest(String projectVersionId) { - if(!copyState || !copyRequested){ - return null; - } - - this.copyFromPartialOptions.put("projectVersionId", projectVersionId); - return unirest - .post(SSCUrls.PROJECT_VERSIONS_ACTION_COPY_FROM_PARTIAL) - .body(copyFromPartialOptions); - } - public final HttpRequest buildCopyFromPartialRequest(String projectVersionId) { if(!copyRequested){ return null; @@ -58,25 +45,27 @@ public final HttpRequest buildCopyFromPartialRequest(String projectVersionId) .body(copyFromPartialOptions); } + public final HttpRequest buildCopyStateRequest(String projectVersionId) { if(!copyState || !copyRequested){ return null; } - // refreshMetrics if the source PV is required to fully copy the tags, audit or comments - if(this.previousProjectVersion.isRefreshRequired()){ - SSCJobDescriptor refreshJobDesc = SSCAppVersionHelper.refreshMetrics(unirest, this.previousProjectVersion); - SSCJobHelper.waitForJob(unirest,refreshJobDesc); - } - this.copyStateOptions.put("projectVersionId", projectVersionId); + + this.copyStateOptions.put("projectVersionId", Integer.parseInt(projectVersionId)); + + ObjectNode body = JsonHelper.getObjectMapper().createObjectNode(); + body .put("type", "copy_current_state") + .set("values", copyStateOptions); + return unirest - .post(SSCUrls.PROJECT_VERSIONS_ACTION_COPY_CURRENT_STATE) - .body(copyStateOptions); + .post(SSCUrls.PROJECT_VERSIONS_ACTION(projectVersionId)) + .body(body); } public final SSCAppVersionCreateCopyFromBuilder setCopyFrom(SSCAppVersionDescriptor previousProjectVersionDescriptor) { this.previousProjectVersion = previousProjectVersionDescriptor; this.copyFromPartialOptions.put("previousProjectVersionId", previousProjectVersionDescriptor.getVersionId()); - this.copyStateOptions.put("previousProjectVersionId", previousProjectVersionDescriptor.getVersionId()); + this.copyStateOptions.put("previousProjectVersionId", previousProjectVersionDescriptor.getIntVersionId()); return this; } diff --git a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/helper/SSCAppVersionDescriptor.java b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/helper/SSCAppVersionDescriptor.java index e628ca3eae..75c24d2c6a 100644 --- a/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/helper/SSCAppVersionDescriptor.java +++ b/fcli-core/fcli-ssc/src/main/java/com/fortify/cli/ssc/appversion/helper/SSCAppVersionDescriptor.java @@ -47,4 +47,8 @@ public String getAppAndVersionName() { public String getQualifierPrefix(String delimiter) { return applicationName+delimiter; } + + @JsonIgnore + public int getIntVersionId() {return Integer.parseInt(versionId);} + } diff --git a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/i18n/SSCMessages.properties b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/i18n/SSCMessages.properties index 4063f60e3b..6853573db6 100644 --- a/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/i18n/SSCMessages.properties +++ b/fcli-core/fcli-ssc/src/main/resources/com/fortify/cli/ssc/i18n/SSCMessages.properties @@ -228,6 +228,8 @@ fcli.ssc.appversion.create.active = Specify whether application version should b or not (false). fcli.ssc.appversion.create.skip-if-exists = Skip application version creation if an application version with \ the specified name already exists. +fcli.ssc.appversion.create.refresh = By default, this command will refresh the source application version's metrics when copying from it. \ + Note that for large applications this can lead to an error if the timeout expires. fcli.ssc.appversion.create.copy-options = Comma separated list of elements to copy (Requires --copy-from). By default, all are copied. \ Allowed values: ${COMPLETION-CANDIDATES}. fcli.ssc.appversion.delete.usage.header = Delete an application version.