Skip to content

Commit

Permalink
Merge pull request #631 from fortify/develop
Browse files Browse the repository at this point in the history
Prepare for next release
  • Loading branch information
rsenden authored Oct 30, 2024
2 parents 2e57620 + d81d923 commit c646d2a
Show file tree
Hide file tree
Showing 12 changed files with 400 additions and 173 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ private static final void addOptionDescriptor(List<IOptionDescriptor> result, Ac
.name(getOptionName(parameter.getName()))
.aliases(getOptionAliases(parameter.getCliAliasesArray()))
.description(parameter.getDescription())
.bool(parameter.getType()!=null && parameter.getType().equals("boolean"))
.build());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public static interface IOptionDescriptor {
String getName();
List<String> getAliases();
String getDescription();
boolean isBool();

default String getOptionNamesAndAliasesString(String delimiter) {
var name = getName();
Expand All @@ -59,6 +60,7 @@ public static class OptionDescriptor implements IOptionDescriptor {
private final String name;
private final List<String> aliases;
private final String description;
private final boolean bool;
}

@Data
Expand Down Expand Up @@ -107,13 +109,16 @@ private Map<String, String> parseArgs(List<String> validationErrors, String[] ar
var argWithPossibleValue = argsDeque.pop();
var argElts = argWithPossibleValue.split("=", 2);
var arg = argElts[0];
if ( !optionsByNameAndAliases.containsKey(arg) ) {
var optionDescriptor = optionsByNameAndAliases.get(arg);
if ( optionDescriptor==null ) {
validationErrors.add("Unknown command line option: "+arg);
} else if ( argElts.length==2 ) {
result.put(arg, argElts[1]);
} else {
var nextArg = argsDeque.peek();
var value = optionsByNameAndAliases.containsKey(nextArg) ? null : argsDeque.pop();
var value = nextArg==null || optionsByNameAndAliases.containsKey(nextArg)
? (optionDescriptor.isBool() ? "true" : null)
: argsDeque.pop();
result.put(arg, value);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ public static abstract class AbstractFoDAppAttributeUpdateMixin {
}

public static class OptionalAttrCreateOption extends AbstractFoDAppAttributeUpdateMixin {
@Option(names = {"--attrs", "--attributes"}, required = false, split=",", paramLabel = PARAM_LABEL, descriptionKey = "fcli.fod.app.create.attr")
@Option(names = {"--attrs", "--attributes"}, required = false, split=",", paramLabel = PARAM_LABEL)
@Getter private Map<String, String> attributes;
}

public static class OptionalAttrOption extends AbstractFoDAppAttributeUpdateMixin {
@Option(names = {"--attrs", "--attributes"}, required = false, split=",", paramLabel = PARAM_LABEL, descriptionKey = "fcli.fod.app.update.attr")
@Option(names = {"--attrs", "--attributes"}, required = false, split=",", paramLabel = PARAM_LABEL)
@Getter private Map<String, String> attributes;
}

public static class RequiredPositionalParameter extends AbstractFoDAppAttributeUpdateMixin {
@EnvSuffix("ATTRS") @Parameters(index = "0..*", arity = "1..*", paramLabel = PARAM_LABEL, descriptionKey = "fcli.fod.app.update.attr")
@EnvSuffix("ATTRS") @Parameters(index = "0..*", arity = "1..*", paramLabel = PARAM_LABEL)
@Getter private Map<String, String> attributes;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@
import static com.fortify.cli.common.util.DisableTest.TestType.MULTI_OPT_PLURAL_NAME;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import com.fasterxml.jackson.databind.JsonNode;
import com.fortify.cli.common.cli.util.EnvSuffix;
Expand All @@ -27,11 +24,7 @@
import com.fortify.cli.common.util.DisableTest;
import com.fortify.cli.common.util.StringUtils;
import com.fortify.cli.fod._common.output.cli.cmd.AbstractFoDJsonNodeOutputCommand;
import com.fortify.cli.fod._common.util.FoDEnums;
import com.fortify.cli.fod.access_control.helper.FoDUserGroupHelper;
import com.fortify.cli.fod.access_control.helper.FoDUserHelper;
import com.fortify.cli.fod.app.attr.cli.mixin.FoDAttributeUpdateOptions;
import com.fortify.cli.fod.app.attr.helper.FoDAttributeHelper;
import com.fortify.cli.fod.app.cli.mixin.FoDAppTypeOptions;
import com.fortify.cli.fod.app.cli.mixin.FoDCriticalityTypeOptions;
import com.fortify.cli.fod.app.cli.mixin.FoDMicroserviceAndReleaseNameResolverMixin;
Expand Down Expand Up @@ -85,26 +78,19 @@ public JsonNode getJsonNode(UnirestInstance unirest) {
var releaseNameDescriptor = releaseNameResolverMixin.getMicroserviceAndReleaseNameDescriptor();
var microserviceName = releaseNameDescriptor.getMicroserviceName();
validateMicroserviceName(microserviceName);

var ownerId = FoDUserHelper.getUserDescriptor(unirest, owner, true).getUserId();
List<String> microservices = StringUtils.isBlank(microserviceName)
? Collections.emptyList() : new ArrayList<>(Arrays.asList(microserviceName));
FoDAppCreateRequest appCreateRequest = FoDAppCreateRequest.builder()
.applicationName(applicationName)
.applicationDescription(description)
.businessCriticalityType(criticalityType.getCriticalityType().name())
.emailList(FoDAppHelper.getEmailList(notifications))
.releaseName(releaseNameDescriptor.getReleaseName())
.businessCriticality(criticalityType.getCriticalityType())
.notify(notifications)
.microserviceAndReleaseNameDescriptor(releaseNameDescriptor)
.releaseDescription(releaseDescription)
.sdlcStatusType(String.valueOf(sdlcStatus.getSdlcStatusType()))
.ownerId(ownerId)
.applicationType(appType.getAppType().getFoDValue())
.hasMicroservices(appType.getAppType().isMicroservice())
.microservices(FoDAppHelper.getMicroservicesNode(microservices))
.attributes(FoDAttributeHelper.getAttributesNode(unirest, FoDEnums.AttributeTypes.All,
appAttrs.getAttributes(), autoRequiredAttrs))
.userGroupIds(FoDUserGroupHelper.getUserGroupsNode(unirest, userGroups)).build();

.sdlcStatus(sdlcStatus.getSdlcStatusType())
.owner(unirest, owner)
.appType(appType.getAppType())
.autoAttributes(unirest, appAttrs.getAttributes(), autoRequiredAttrs)
.userGroups(unirest, userGroups)
.build().validate();
return FoDAppHelper.createApp(unirest, appCreateRequest).asJsonNode();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,29 @@
*******************************************************************************/
package com.fortify.cli.fod.app.helper;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.formkiq.graalvm.annotations.Reflectable;
import com.fortify.cli.common.json.JsonHelper;
import com.fortify.cli.common.util.StringUtils;
import com.fortify.cli.fod._common.util.FoDEnums;
import com.fortify.cli.fod.access_control.helper.FoDUserGroupHelper;
import com.fortify.cli.fod.access_control.helper.FoDUserHelper;
import com.fortify.cli.fod.app.attr.helper.FoDAttributeHelper;
import com.fortify.cli.fod.app.cli.mixin.FoDAppTypeOptions.FoDAppType;
import com.fortify.cli.fod.app.cli.mixin.FoDCriticalityTypeOptions.FoDCriticalityType;
import com.fortify.cli.fod.app.cli.mixin.FoDSdlcStatusTypeOptions.FoDSdlcStatusType;
import com.fortify.cli.fod.release.helper.FoDQualifiedReleaseNameDescriptor;

import kong.unirest.UnirestInstance;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
Expand All @@ -35,10 +55,98 @@ public class FoDAppCreateRequest {
private String sdlcStatusType;
private Integer ownerId;
private String applicationType;
private Boolean hasMicroservices;
@Builder.Default private boolean hasMicroservices = false;
private JsonNode microservices;
private String releaseMicroserviceName;
private JsonNode attributes;
private JsonNode userGroupIds;
private Boolean autoRequiredAttrs;

@JsonIgnore
public final ObjectNode asObjectNode() {
ObjectNode body = JsonHelper.getObjectMapper().valueToTree(this);
// if microservice, remove applicationType field
if (isHasMicroservices()) {
body.remove("applicationType");
}
return body;
}

@JsonIgnore
public final FoDAppCreateRequest validate(Consumer<List<String>> validationMessageConsumer) {
var messages = new ArrayList<String>();
validateRequired(messages, applicationName, "Required application name not specified");
validateRequired(messages, businessCriticalityType, "Required application business criticality not specified");
validateRequired(messages, releaseName, "Required release name not specified");
validateRequired(messages, sdlcStatusType, "Required release SDLC status not specified");
validateRequired(messages, ownerId, "Required application owner not specified");
validateRequired(messages, applicationType, "Required application type not specified");
if ( hasMicroservices ) {
validateRequired(messages, releaseMicroserviceName, "Required release microservice name not specified");
}
if ( !messages.isEmpty() ) {
validationMessageConsumer.accept(messages);
}
return this;
}

@JsonIgnore
public final FoDAppCreateRequest validate() {
return validate(messages->{throw new IllegalArgumentException("Unable to create application:\n\t"+String.join("\n\t", messages)); });
}

@JsonIgnore
private final void validateRequired(List<String> messages, Object obj, String message) {
if ( obj==null || (obj instanceof String && StringUtils.isBlank((String)obj)) ) {
messages.add(message);
}
}

public static class FoDAppCreateRequestBuilder {
public FoDAppCreateRequestBuilder appType(FoDAppType appType) {
if ( appType==null ) { return hasMicroservices(false).applicationType(null); }
else { return hasMicroservices(appType.isMicroservice()).applicationType(appType.getFoDValue()); }
}

public FoDAppCreateRequestBuilder autoAttributes(UnirestInstance unirest, Map<String, String> attributes, boolean autoRequiredAttrs) {
return attributes(FoDAttributeHelper.getAttributesNode(unirest, FoDEnums.AttributeTypes.All, attributes, autoRequiredAttrs));
}

public FoDAppCreateRequestBuilder businessCriticality(FoDCriticalityType businessCriticalityType) {
return businessCriticalityType(businessCriticalityType==null ? null : businessCriticalityType.name());
}

public FoDAppCreateRequestBuilder notify(ArrayList<String> notifications) {
return emailList(FoDAppHelper.getEmailList(notifications));
}

public FoDAppCreateRequestBuilder microserviceName(String microserviceName) {
List<String> microservices = StringUtils.isBlank(microserviceName)
? Collections.emptyList() : new ArrayList<>(Arrays.asList(microserviceName));
microservices(FoDAppHelper.getMicroservicesNode(microservices));
return releaseMicroserviceName(microserviceName);
}

public FoDAppCreateRequestBuilder microserviceAndReleaseNameDescriptor(FoDMicroserviceAndReleaseNameDescriptor microserviceAndReleaseNameDescriptor) {
microserviceName(microserviceAndReleaseNameDescriptor==null ? null : microserviceAndReleaseNameDescriptor.getMicroserviceName());
return releaseName(microserviceAndReleaseNameDescriptor==null ? null : microserviceAndReleaseNameDescriptor.getReleaseName());
}

public FoDAppCreateRequestBuilder releaseNameDescriptor(FoDQualifiedReleaseNameDescriptor releaseNameDescriptor) {
applicationName(releaseNameDescriptor==null ? null : releaseNameDescriptor.getAppName());
microserviceName(releaseNameDescriptor==null ? null : releaseNameDescriptor.getMicroserviceName());
return releaseName(releaseNameDescriptor==null ? null : releaseNameDescriptor.getReleaseName());
}

public FoDAppCreateRequestBuilder owner(UnirestInstance unirest, String owner) {
return ownerId(owner==null ? null : FoDUserHelper.getUserDescriptor(unirest, owner, true).getUserId());
}

public FoDAppCreateRequestBuilder sdlcStatus(FoDSdlcStatusType sdlcStatusType) {
return sdlcStatusType(sdlcStatusType==null ? null : sdlcStatusType.name());
}

public FoDAppCreateRequestBuilder userGroups(UnirestInstance unirest, ArrayList<String> userGroups) {
return userGroupIds(FoDUserGroupHelper.getUserGroupsNode(unirest, userGroups));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fortify.cli.common.json.JsonHelper;
import com.fortify.cli.common.util.StringUtils;
import com.fortify.cli.fod._common.rest.FoDUrls;
import com.fortify.cli.fod._common.rest.helper.FoDDataHelper;
import com.fortify.cli.fod.app.cli.mixin.FoDAppTypeOptions.FoDAppType;
Expand Down Expand Up @@ -62,16 +61,8 @@ public static final FoDAppDescriptor getAppDescriptor(UnirestInstance unirest, S
}

public static final FoDAppDescriptor createApp(UnirestInstance unirest, FoDAppCreateRequest appCreateRequest) {
ObjectNode body = objectMapper.valueToTree(appCreateRequest);
// if microservice, remove applicationType field and set releaseMicroserviceName if not already set
if (appCreateRequest.getHasMicroservices()) {
body.remove("applicationType");
if (StringUtils.isBlank(appCreateRequest.getReleaseMicroserviceName())) {
body.replace("releaseMicroserviceName", appCreateRequest.getMicroservices().get(0));
}
}
var appId = unirest.post(FoDUrls.APPLICATIONS)
.body(body).asObject(JsonNode.class).getBody().get("applicationId").asText();
.body(appCreateRequest.asObjectNode()).asObject(JsonNode.class).getBody().get("applicationId").asText();
return getAppDescriptor(unirest, appId, true);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ public static final FoDMicroserviceDescriptor createMicroservice(UnirestInstance
.body(body).asObject(JsonNode.class).getBody();
return getDescriptor(appDescriptor, response, msRequest.getMicroserviceName());
}

public static final FoDMicroserviceDescriptor createMicroservice(UnirestInstance unirest, FoDAppDescriptor appDescriptor, String microserviceName) {
var request = FoDMicroserviceUpdateRequest.builder().microserviceName(microserviceName).build();
return createMicroservice(unirest, appDescriptor, request);
}

public static final FoDMicroserviceDescriptor updateMicroservice(UnirestInstance unirest, FoDMicroserviceDescriptor currentMs, FoDMicroserviceUpdateRequest msRequest) {
FoDAppDescriptor appDescriptor = FoDAppHelper.getAppDescriptor(unirest, currentMs.getApplicationId(), true);
Expand Down
Loading

0 comments on commit c646d2a

Please sign in to comment.