Skip to content

Commit 38ff1f1

Browse files
Add GetStates command and update with custom state functionality (AST-81676) (#399)
* Add notify step to release.yml (AST-000) * fix input to inputs * fix input to inputs * fix input to inputs * fix input to inputs * fix input to inputs * fix input to inputs * change if condition to notify job * Add custom states support * Add custom states support * Add tests * ignore added test * refactor * refactor * Change stateId from Long to String * revert if case in push satate in triage update command * Change id from Long to Integer --------- Co-authored-by: AlvoBen <[email protected]>
1 parent 31ceb15 commit 38ff1f1

File tree

6 files changed

+114
-14
lines changed

6 files changed

+114
-14
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.checkmarx.ast.predicate;
2+
3+
import com.checkmarx.ast.utils.JsonParser;
4+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
5+
import com.fasterxml.jackson.annotation.JsonInclude;
6+
import com.fasterxml.jackson.annotation.JsonProperty;
7+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
8+
import com.fasterxml.jackson.databind.type.TypeFactory;
9+
import lombok.Value;
10+
11+
import java.util.List;
12+
13+
@Value
14+
@JsonDeserialize()
15+
@JsonInclude(JsonInclude.Include.NON_NULL)
16+
@JsonIgnoreProperties(ignoreUnknown = true)
17+
public class CustomState {
18+
Integer id;
19+
String name;
20+
String type;
21+
22+
public CustomState(@JsonProperty("id") Integer id,
23+
@JsonProperty("name") String name,
24+
@JsonProperty("type") String type) {
25+
this.id = id;
26+
this.name = name;
27+
this.type = type;
28+
}
29+
30+
public static <T> T fromLine(String line) {
31+
return JsonParser.parse(line, TypeFactory.defaultInstance().constructType(CustomState.class));
32+
}
33+
34+
public static <T> List<T> listFromLine(String line) {
35+
return JsonParser.parse(line, TypeFactory.defaultInstance().constructCollectionType(List.class, CustomState.class));
36+
}
37+
}

src/main/java/com/checkmarx/ast/predicate/Predicate.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.apache.commons.lang3.StringUtils;
1313

1414
import java.io.IOException;
15+
import java.lang.reflect.Field;
1516
import java.util.List;
1617

1718
@Value
@@ -29,13 +30,14 @@ public class Predicate {
2930
String createdBy;
3031
String createdAt;
3132
String updatedAt;
33+
String stateId;
3234

3335
@JsonCreator
3436
public Predicate(@JsonProperty("ID") String id, @JsonProperty("SimilarityID") String similarityId,
3537
@JsonProperty("ProjectID") String projectId, @JsonProperty("State") String state,
3638
@JsonProperty("Severity") String severity, @JsonProperty("Comment") String comment,
3739
@JsonProperty("CreatedBy") String createdBy, @JsonProperty("CreatedAt") String createdAt,
38-
@JsonProperty("UpdatedAt") String updatedAt) {
40+
@JsonProperty("UpdatedAt") String updatedAt, @JsonProperty("StateId") String stateId) {
3941
this.id = id;
4042
this.similarityId = similarityId;
4143
this.projectId = projectId;
@@ -45,6 +47,7 @@ public Predicate(@JsonProperty("ID") String id, @JsonProperty("SimilarityID") St
4547
this.createdBy = createdBy;
4648
this.createdAt = createdAt;
4749
this.updatedAt = updatedAt;
50+
this.stateId = stateId;
4851
}
4952

5053
public static <T> T fromLine(String line) {
@@ -68,6 +71,22 @@ protected static <T> T parse(String line, JavaType type) {
6871
return result;
6972
}
7073

74+
public static boolean validator(List<String> arguments, Object parsedLine) {
75+
{
76+
for (Field field : parsedLine.getClass().getDeclaredFields()) {
77+
field.setAccessible(true);
78+
try {
79+
if (field.get(parsedLine) == null && !field.getName().equals("stateId")) {
80+
return false;
81+
}
82+
} catch (IllegalAccessException e) {
83+
return false;
84+
}
85+
}
86+
return true;
87+
}
88+
}
89+
7190
private static boolean isValidJSON(final String json) {
7291
try {
7392
final ObjectMapper mapper = new ObjectMapper();

src/main/java/com/checkmarx/ast/wrapper/CxConstants.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ public final class CxConstants {
3232
static final String SUB_CMD_CANCEL = "cancel";
3333
static final String CMD_TRIAGE = "triage";
3434
static final String SUB_CMD_UPDATE = "update";
35+
static final String SUB_CMD_GET_STATES = "get-states";
36+
static final String ALL_STATES_FLAG = "--all";
3537
static final String CMD_RESULT = "results";
3638
static final String FORMAT = "--format";
3739
static final String SCAN_INFO_FORMAT = "--scan-info-format";
@@ -44,6 +46,7 @@ public final class CxConstants {
4446
static final String STATE = "--state";
4547
static final String COMMENT = "--comment";
4648
static final String SEVERITY = "--severity";
49+
static final String CUSTOM_STATE_ID = "--custom-state-id";
4750
static final String REPORT_FORMAT = "--report-format";
4851
static final String OUTPUT_NAME = "--output-name";
4952
static final String OUTPUT_PATH = "--output-path";

src/main/java/com/checkmarx/ast/wrapper/CxWrapper.java

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.checkmarx.ast.codebashing.CodeBashing;
55
import com.checkmarx.ast.kicsRealtimeResults.KicsRealtimeResults;
66
import com.checkmarx.ast.learnMore.LearnMore;
7+
import com.checkmarx.ast.predicate.CustomState;
78
import com.checkmarx.ast.predicate.Predicate;
89
import com.checkmarx.ast.project.Project;
910
import com.checkmarx.ast.remediation.KicsRemediation;
@@ -23,6 +24,7 @@
2324
import org.slf4j.LoggerFactory;
2425

2526
import java.io.IOException;
27+
import java.lang.reflect.Field;
2628
import java.nio.file.Files;
2729
import java.util.ArrayList;
2830
import java.util.List;
@@ -161,12 +163,32 @@ public List<Predicate> triageShow(@NonNull UUID projectId, String similarityId,
161163

162164
arguments.addAll(jsonArguments());
163165

164-
return Execution.executeCommand(withConfigArguments(arguments), logger, Predicate::listFromLine);
166+
return Execution.executeCommand(withConfigArguments(arguments), logger, Predicate::listFromLine, Predicate::validator);
167+
}
168+
169+
public List<Predicate> triageGetStates(boolean all) throws IOException, InterruptedException, CxException {
170+
this.logger.info("Executing 'triage get-states' command using the CLI.");
171+
172+
List<String> arguments = new ArrayList<>();
173+
arguments.add(CxConstants.CMD_TRIAGE);
174+
arguments.add(CxConstants.SUB_CMD_GET_STATES);
175+
if (all) {
176+
arguments.add(CxConstants.ALL_STATES_FLAG);
177+
}
178+
179+
return Execution.executeCommand(withConfigArguments(arguments), logger, CustomState::listFromLine);
165180
}
166181

167182
public void triageUpdate(@NonNull UUID projectId, String similarityId, String scanType, String state, String comment, String severity) throws IOException, InterruptedException, CxException {
183+
triageUpdate(projectId, similarityId, scanType, state, comment, severity, null);
184+
}
185+
186+
public void triageUpdate(@NonNull UUID projectId, String similarityId, String scanType, String state, String comment, String severity, String customStateId) throws IOException, InterruptedException, CxException {
168187
this.logger.info("Executing 'triage update' command using the CLI.");
169-
this.logger.info("Updating the similarityId {} with state {} and severity {}.", similarityId, state, severity);
188+
this.logger.info("Updating the similarityId {} with state {} with customStateId {} and severity {}.", similarityId, state, customStateId, severity);
189+
190+
boolean emptyState = state == null || state.isEmpty();
191+
boolean emptyCustomStateId = customStateId == null || customStateId.isEmpty();
170192

171193
List<String> arguments = new ArrayList<>();
172194
arguments.add(CxConstants.CMD_TRIAGE);
@@ -179,6 +201,10 @@ public void triageUpdate(@NonNull UUID projectId, String similarityId, String sc
179201
arguments.add(scanType);
180202
arguments.add(CxConstants.STATE);
181203
arguments.add(state);
204+
if (!emptyCustomStateId) {
205+
arguments.add(CxConstants.CUSTOM_STATE_ID);
206+
arguments.add(customStateId);
207+
}
182208
if (!StringUtils.isBlank(comment)) {
183209
arguments.add(CxConstants.COMMENT);
184210
arguments.add(comment);
@@ -232,7 +258,9 @@ public ScanResult ScanAsca(String fileSource, boolean ascaLatestVersion, String
232258

233259
appendAgentToArguments(agent, arguments);
234260

235-
return Execution.executeCommand(withConfigArguments(arguments), logger, ScanResult::fromLine);
261+
return Execution.executeCommand(withConfigArguments(arguments), logger, ScanResult::fromLine,
262+
(args, ignored) ->
263+
(args.size() >= 3 && args.get(1).equals(CxConstants.CMD_SCAN) && args.get(2).equals(CxConstants.SUB_CMD_ASCA)));
236264
}
237265

238266
private static void appendAgentToArguments(String agent, List<String> arguments) {

src/main/java/com/checkmarx/ast/wrapper/Execution.java

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.util.List;
1717
import java.util.Locale;
1818
import java.util.Objects;
19+
import java.util.function.BiFunction;
1920
import java.util.function.Function;
2021

2122
public final class Execution {
@@ -42,34 +43,37 @@ static <T> T executeCommand(List<String> arguments,
4243
Logger logger,
4344
Function<String, T> lineParser)
4445
throws IOException, InterruptedException, CxException {
46+
return executeCommand(arguments, logger, lineParser, Execution::areAllFieldsNotNull);
47+
}
48+
49+
static <T> T executeCommand(List<String> arguments,
50+
Logger logger,
51+
Function<String, T> lineParser,
52+
BiFunction<List<String>, T, Boolean> customValidator)
53+
throws IOException, InterruptedException, CxException {
4554
Process process = buildProcess(arguments);
4655
try (BufferedReader br = getReader(process)) {
4756
T executionResult = null;
4857
String line;
49-
StringBuilder stringBuilder = new StringBuilder();
58+
StringBuilder output = new StringBuilder();
5059
while ((line = br.readLine()) != null) {
5160
logger.info(line);
52-
stringBuilder.append(line).append(LINE_SEPARATOR);
61+
output.append(line).append(LINE_SEPARATOR);
5362
T parsedLine = lineParser.apply(line);
5463
if (parsedLine != null) {
55-
if (areAllFieldsNotNull(parsedLine) || isAscaRequest(arguments)) {
56-
executionResult = parsedLine;
57-
}
64+
executionResult = customValidator.apply(arguments, parsedLine) ? parsedLine : null;
5865
}
5966
}
6067
process.waitFor();
6168
if (process.exitValue() != 0) {
62-
throw new CxException(process.exitValue(), stringBuilder.toString());
69+
throw new CxException(process.exitValue(), output.toString());
6370
}
6471
return executionResult;
6572
}
6673
}
6774

68-
public static boolean isAscaRequest(List<String> arguments) {
69-
return (arguments.size() >= 3 && arguments.get(1).equals("scan") && arguments.get(2).equals("asca"));
70-
}
7175

72-
private static boolean areAllFieldsNotNull(Object obj) {
76+
private static boolean areAllFieldsNotNull(List<String> arguments, Object obj) {
7377
for (Field field : obj.getClass().getDeclaredFields()) {
7478
field.setAccessible(true);
7579
try {

src/test/java/com/checkmarx/ast/PredicateTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
import com.checkmarx.ast.results.result.Result;
66
import com.checkmarx.ast.scan.Scan;
77
import com.checkmarx.ast.wrapper.CxConstants;
8+
import org.junit.Ignore;
89
import org.junit.jupiter.api.Assertions;
10+
import org.junit.jupiter.api.Disabled;
911
import org.junit.jupiter.api.Test;
1012

1113
import java.util.List;
@@ -44,4 +46,11 @@ void testTriage() throws Exception {
4446
Assertions.fail("Triage update failed. Should not throw exception");
4547
}
4648
}
49+
50+
@Test
51+
@Disabled("Ignore this tests until get states api will be in production")
52+
void testGetStates() throws Exception {
53+
List<Predicate> states = wrapper.triageGetStates(false);
54+
Assertions.assertNotNull(states);
55+
}
4756
}

0 commit comments

Comments
 (0)