RED-7886 - Endpoint for rule validation #360
@ -17,6 +17,7 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RequestPart;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
@ -57,27 +58,38 @@ public class RulesController implements RulesResource {
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasAuthority('" + WRITE_RULES + "')")
|
||||
public ResponseEntity<?> upload(@RequestBody RulesUploadRequestModel rules) {
|
||||
public ResponseEntity<DroolsSyntaxValidationResponse> upload(@RequestBody RulesUploadRequestModel rules) {
|
||||
|
||||
RulesUploadRequest rulesUploadRequest = RulesUploadRequest.fromModel(rules);
|
||||
DroolsSyntaxValidationResponse droolsSyntaxValidationResponse = DroolsSyntaxValidationResponse.builder()
|
||||
.build();
|
||||
DroolsSyntaxValidationResponse droolsSyntaxValidationResponse = DroolsSyntaxValidationResponse.builder().build();
|
||||
try {
|
||||
DroolsSyntaxValidation droolsSyntaxValidation = rulesValidationService.validateRules(rulesUploadRequest.getRuleFileType(), rulesUploadRequest.getRules());
|
||||
var rulesSyntaxWarningMessages = droolsSyntaxValidation.getDroolsSyntaxDeprecatedWarnings()
|
||||
.stream()
|
||||
.map(warningMessage -> RuleSyntaxWarningMessage.builder().line(warningMessage.getLine()).column(warningMessage.getColumn()).message(warningMessage.getMessage())
|
||||
.map(warningMessage -> RuleSyntaxWarningMessage.builder()
|
||||
.line(warningMessage.getLine())
|
||||
.column(warningMessage.getColumn())
|
||||
.message(warningMessage.getMessage())
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
droolsSyntaxValidationResponse.setRulesSyntaxWarningMessages(rulesSyntaxWarningMessages);
|
||||
if (!droolsSyntaxValidation.isCompiled()) {
|
||||
var rulesSyntaxErrorMessages = droolsSyntaxValidation.getDroolsSyntaxErrorMessages()
|
||||
.stream()
|
||||
.map(errorMessage -> RuleSyntaxErrorMessage.builder().line(errorMessage.getLine()).column(errorMessage.getColumn()).message(errorMessage.getMessage())
|
||||
.map(errorMessage -> RuleSyntaxErrorMessage.builder()
|
||||
.line(errorMessage.getLine())
|
||||
.column(errorMessage.getColumn())
|
||||
.message(errorMessage.getMessage())
|
||||
.build())
|
||||
.toList();
|
||||
droolsSyntaxValidationResponse.setRulesSyntaxErrorMessages(rulesSyntaxErrorMessages);
|
||||
return new ResponseEntity<>(droolsSyntaxValidationResponse, HttpStatus.BAD_REQUEST);
|
||||
if (!rules.isDryRun()) {
|
||||
return new ResponseEntity<>(droolsSyntaxValidationResponse, HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
}
|
||||
|
||||
if (rules.isDryRun()) {
|
||||
return ResponseEntity.ok(droolsSyntaxValidationResponse);
|
||||
}
|
||||
} catch (FeignException e) {
|
||||
if (e.status() == HttpStatus.BAD_REQUEST.value()) {
|
||||
@ -117,20 +129,23 @@ public class RulesController implements RulesResource {
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasAuthority('" + WRITE_RULES + "')")
|
||||
public ResponseEntity<?> uploadFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @RequestPart(name = "file") MultipartFile file) {
|
||||
public ResponseEntity<DroolsSyntaxValidationResponse> uploadFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId,
|
||||
@RequestParam(value = DRY_RUN_PARAMETER) boolean dryRun,
|
||||
@RequestPart(name = "file") MultipartFile file) {
|
||||
|
||||
return uploadFile(dossierTemplateId, RuleFileType.ENTITY, file);
|
||||
return uploadFile(dossierTemplateId, RuleFileType.ENTITY, dryRun, file);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@PreAuthorize("hasAuthority('" + WRITE_RULES + "')")
|
||||
public ResponseEntity<?> uploadFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId,
|
||||
@PathVariable(RULE_FILE_TYPE_PARAMETER_NAME) RuleFileType ruleFileType,
|
||||
@RequestPart(name = "file") MultipartFile file) {
|
||||
public ResponseEntity<DroolsSyntaxValidationResponse> uploadFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId,
|
||||
@PathVariable(RULE_FILE_TYPE_PARAMETER_NAME) RuleFileType ruleFileType,
|
||||
@RequestParam(value = DRY_RUN_PARAMETER) boolean dryRun,
|
||||
@RequestPart(name = "file") MultipartFile file) {
|
||||
|
||||
try {
|
||||
return upload(new RulesUploadRequestModel(new String(file.getBytes(), StandardCharsets.UTF_8), dossierTemplateId, ruleFileType));
|
||||
return upload(new RulesUploadRequestModel(new String(file.getBytes(), StandardCharsets.UTF_8), dossierTemplateId, ruleFileType, dryRun));
|
||||
} catch (IOException e) {
|
||||
throw new FileUploadException("Could not upload file.", e);
|
||||
}
|
||||
|
||||
@ -7,12 +7,14 @@ import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RequestPart;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileType;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.DroolsSyntaxValidationResponse;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesResponse;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesUploadRequestModel;
|
||||
|
||||
@ -33,6 +35,8 @@ public interface RulesResource {
|
||||
String RULE_FILE_TYPE_PARAMETER_NAME = "ruleFileType";
|
||||
String RULE_FILE_TYPE_PATH_VARIABLE = "/{ruleFileType}";
|
||||
|
||||
String DRY_RUN_PARAMETER = "dryRun";
|
||||
|
||||
|
||||
/**
|
||||
* Upload rules to be used by redaction service.
|
||||
@ -42,8 +46,8 @@ public interface RulesResource {
|
||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||
@PostMapping(value = RULES_PATH, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||
@Operation(summary = "Takes object containing string or rules as argument, which will be used by the redaction service.")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Rules upload successful."), @ApiResponse(responseCode = "400", description = "Uploaded rules could not be verified.")})
|
||||
ResponseEntity<?> upload(@RequestBody RulesUploadRequestModel rules);
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Rules upload successful or rules validation done."), @ApiResponse(responseCode = "400", description = "Uploaded rules could not be verified.")})
|
||||
ResponseEntity<DroolsSyntaxValidationResponse> upload(@RequestBody RulesUploadRequestModel rules);
|
||||
|
||||
|
||||
@ResponseBody
|
||||
@ -70,17 +74,20 @@ public interface RulesResource {
|
||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||
@PostMapping(value = RULES_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE + UPLOAD_PATH, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
@Operation(summary = "Takes object containing string or rules as argument, which will be used by the redaction service.")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Rules upload successful."), @ApiResponse(responseCode = "400", description = "Uploaded rules could not be verified.")})
|
||||
ResponseEntity<?> uploadFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId, @Schema(type = "string", format = "binary", name = "file") @RequestPart(name = "file") MultipartFile file);
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Rules upload successful or rules validation done."), @ApiResponse(responseCode = "400", description = "Uploaded rules could not be verified.")})
|
||||
ResponseEntity<DroolsSyntaxValidationResponse> uploadFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId,
|
||||
@RequestParam(value = DRY_RUN_PARAMETER) boolean dryRun,
|
||||
@Schema(type = "string", format = "binary", name = "file") @RequestPart(name = "file") MultipartFile file);
|
||||
|
||||
|
||||
@ResponseStatus(value = HttpStatus.NO_CONTENT)
|
||||
@PostMapping(value = RULES_PATH + DOSSIER_TEMPLATE_PATH_VARIABLE + RULE_FILE_TYPE_PATH_VARIABLE + UPLOAD_PATH, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||
@Operation(summary = "Takes object containing string or rules as argument, which will be used by the redaction service.")
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "204", description = "Rules upload successful."), @ApiResponse(responseCode = "400", description = "Uploaded rules could not be verified.")})
|
||||
ResponseEntity<?> uploadFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId,
|
||||
@PathVariable(RULE_FILE_TYPE_PARAMETER_NAME) RuleFileType ruleFileType,
|
||||
@Schema(type = "string", format = "binary", name = "file") @RequestPart(name = "file") MultipartFile file);
|
||||
@ApiResponses(value = {@ApiResponse(responseCode = "200", description = "Rules upload successful or rules validation done"), @ApiResponse(responseCode = "400", description = "Uploaded rules could not be verified.")})
|
||||
ResponseEntity<DroolsSyntaxValidationResponse> uploadFile(@PathVariable(DOSSIER_TEMPLATE_PARAMETER_NAME) String dossierTemplateId,
|
||||
@PathVariable(RULE_FILE_TYPE_PARAMETER_NAME) RuleFileType ruleFileType,
|
||||
@RequestParam(value = DRY_RUN_PARAMETER) boolean dryRun,
|
||||
@Schema(type = "string", format = "binary", name = "file") @RequestPart(name = "file") MultipartFile file);
|
||||
|
||||
|
||||
@ResponseBody
|
||||
|
||||
@ -1,18 +1,31 @@
|
||||
package com.iqser.red.service.peristence.v1.server.integration.tests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
import com.iqser.red.service.peristence.v1.server.integration.client.RulesClient;
|
||||
import com.iqser.red.service.peristence.v1.server.integration.client.VersionClient;
|
||||
import com.iqser.red.service.peristence.v1.server.integration.service.DossierTemplateTesterAndProvider;
|
||||
import com.iqser.red.service.peristence.v1.server.integration.utils.AbstractPersistenceServerServiceTest;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileType;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.DroolsSyntaxValidationResponse;
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.rules.RulesUploadRequestModel;
|
||||
import com.iqser.red.service.redaction.v1.model.DroolsSyntaxDeprecatedWarnings;
|
||||
import com.iqser.red.service.redaction.v1.model.DroolsSyntaxErrorMessage;
|
||||
import com.iqser.red.service.redaction.v1.model.DroolsSyntaxValidation;
|
||||
import com.iqser.red.service.redaction.v1.model.RuleValidationModel;
|
||||
|
||||
import feign.FeignException;
|
||||
import software.amazon.awssdk.http.HttpStatusCode;
|
||||
|
||||
public class RulesTest extends AbstractPersistenceServerServiceTest {
|
||||
|
||||
@ -31,16 +44,104 @@ public class RulesTest extends AbstractPersistenceServerServiceTest {
|
||||
|
||||
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
|
||||
|
||||
rulesClient.upload(new RulesUploadRequestModel("lorem ipsum", dossierTemplate.getId(), RuleFileType.ENTITY));
|
||||
var response = rulesClient.upload(new RulesUploadRequestModel("lorem ipsum", dossierTemplate.getId(), RuleFileType.ENTITY, false));
|
||||
assertThat(response.getStatusCode().value()).isEqualTo(HttpStatus.SC_OK);
|
||||
assertThat(versionClient.getVersions(List.of(dossierTemplate.getId()))
|
||||
.get(dossierTemplate.getId())
|
||||
.getRulesVersion()).isEqualTo(3); //1. beim Anlegen des DossierTemplates; 2. bei provideTestTemplate(), damit es ACTIVE ist
|
||||
.get(dossierTemplate.getId()).getRulesVersion()).isEqualTo(3); //1. beim Anlegen des DossierTemplates; 2. bei provideTestTemplate(), damit es ACTIVE ist
|
||||
assertThat(rulesClient.download(dossierTemplate.getId()).getRules()).isEqualTo("lorem ipsum");
|
||||
|
||||
rulesClient.upload(new RulesUploadRequestModel("lorem ipsum dolor sit amet", dossierTemplate.getId(), RuleFileType.ENTITY));
|
||||
assertThat(versionClient.getVersions(List.of(dossierTemplate.getId())).get(dossierTemplate.getId()).getRulesVersion()).isEqualTo(4);
|
||||
response = rulesClient.upload(new RulesUploadRequestModel("lorem ipsum dolor sit amet", dossierTemplate.getId(), RuleFileType.ENTITY, false));
|
||||
assertThat(response.getStatusCode().value()).isEqualTo(HttpStatusCode.OK);
|
||||
assertThat(versionClient.getVersions(List.of(dossierTemplate.getId()))
|
||||
.get(dossierTemplate.getId()).getRulesVersion()).isEqualTo(4);
|
||||
assertThat(rulesClient.download(dossierTemplate.getId()).getRules()).isEqualTo("lorem ipsum dolor sit amet");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRulesWithRunDrySetTrue() {
|
||||
|
||||
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
|
||||
|
||||
List<DroolsSyntaxDeprecatedWarnings> warningMessages = new ArrayList<>();
|
||||
warningMessages.add(DroolsSyntaxDeprecatedWarnings.builder().line(1).column(0).message("this function is deprecated").build());
|
||||
List<DroolsSyntaxErrorMessage> errorMessages = new ArrayList<>();
|
||||
errorMessages.add(DroolsSyntaxErrorMessage.builder().line(1).column(0).message("error message").build());
|
||||
var request = new RulesUploadRequestModel("lorem ipsum", dossierTemplate.getId(), RuleFileType.ENTITY, true);
|
||||
// case 1: dry-run true, no error messages just warning messages
|
||||
when(redactionClient.testRules(new RuleValidationModel(request.getRuleFileType().name(), request.getRules()))).thenReturn(DroolsSyntaxValidation.builder()
|
||||
.droolsSyntaxErrorMessages(Collections.emptyList())
|
||||
.droolsSyntaxDeprecatedWarnings(
|
||||
warningMessages)
|
||||
.build());
|
||||
|
||||
ResponseEntity<DroolsSyntaxValidationResponse> response = rulesClient.upload(request);
|
||||
assertThat(response.getStatusCode().value()).isEqualTo(HttpStatus.SC_OK);
|
||||
assertThat(response.getBody().getRulesSyntaxWarningMessages()).isNotEmpty();
|
||||
assertThat(response.getBody().getRulesSyntaxErrorMessages()).isEmpty();
|
||||
|
||||
assertThat(versionClient.getVersions(List.of(dossierTemplate.getId()))
|
||||
.get(dossierTemplate.getId()).getRulesVersion()).isEqualTo(2); //1. beim Anlegen des DossierTemplates; 2. bei provideTestTemplate()
|
||||
|
||||
// case 2: dry-run true, error messages and warning messages
|
||||
when(redactionClient.testRules(new RuleValidationModel(request.getRuleFileType().name(), request.getRules()))).thenReturn(DroolsSyntaxValidation.builder()
|
||||
.droolsSyntaxErrorMessages(errorMessages)
|
||||
.droolsSyntaxDeprecatedWarnings(
|
||||
warningMessages)
|
||||
.build());
|
||||
|
||||
response = rulesClient.upload(request);
|
||||
assertThat(response.getStatusCode().value()).isEqualTo(HttpStatus.SC_OK);
|
||||
assertThat(response.getBody().getRulesSyntaxWarningMessages()).isNotEmpty();
|
||||
assertThat(response.getBody().getRulesSyntaxErrorMessages()).isNotEmpty();
|
||||
|
||||
assertThat(versionClient.getVersions(List.of(dossierTemplate.getId()))
|
||||
.get(dossierTemplate.getId()).getRulesVersion()).isEqualTo(2); //1. beim Anlegen des DossierTemplates; 2. bei provideTestTemplate()
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRulesWithRunDrySetFalse() {
|
||||
|
||||
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
|
||||
|
||||
List<DroolsSyntaxDeprecatedWarnings> warningMessages = new ArrayList<>();
|
||||
warningMessages.add(DroolsSyntaxDeprecatedWarnings.builder().line(1).column(0).message("this function is deprecated").build());
|
||||
List<DroolsSyntaxErrorMessage> errorMessages = new ArrayList<>();
|
||||
errorMessages.add(DroolsSyntaxErrorMessage.builder().line(1).column(0).message("error message").build());
|
||||
var request = new RulesUploadRequestModel("lorem ipsum", dossierTemplate.getId(), RuleFileType.ENTITY, false);
|
||||
// case 1: dry-run false, error messages and warning messages
|
||||
when(redactionClient.testRules(new RuleValidationModel(request.getRuleFileType().name(), request.getRules()))).thenReturn(DroolsSyntaxValidation.builder()
|
||||
.droolsSyntaxErrorMessages(errorMessages)
|
||||
.droolsSyntaxDeprecatedWarnings(
|
||||
warningMessages)
|
||||
.build());
|
||||
try {
|
||||
rulesClient.upload(request);
|
||||
} catch(FeignException e) {
|
||||
assertThat(e.status()).isEqualTo(HttpStatus.SC_BAD_REQUEST);
|
||||
}
|
||||
|
||||
assertThat(versionClient.getVersions(List.of(dossierTemplate.getId()))
|
||||
.get(dossierTemplate.getId()).getRulesVersion()).isEqualTo(2); //1. beim Anlegen des DossierTemplates; 2. bei provideTestTemplate()
|
||||
|
||||
|
||||
// case 2: dry-run false, no error messages just warning messages
|
||||
when(redactionClient.testRules(new RuleValidationModel(request.getRuleFileType().name(), request.getRules()))).thenReturn(DroolsSyntaxValidation.builder()
|
||||
.droolsSyntaxErrorMessages(Collections.emptyList())
|
||||
.droolsSyntaxDeprecatedWarnings(
|
||||
warningMessages)
|
||||
.build());
|
||||
|
||||
ResponseEntity<DroolsSyntaxValidationResponse> response = rulesClient.upload(request);
|
||||
assertThat(response.getStatusCode().value()).isEqualTo(HttpStatus.SC_OK);
|
||||
assertThat(response.getBody().getRulesSyntaxWarningMessages()).isNotEmpty();
|
||||
assertThat(response.getBody().getRulesSyntaxErrorMessages()).isEmpty();
|
||||
|
||||
assertThat(versionClient.getVersions(List.of(dossierTemplate.getId()))
|
||||
.get(dossierTemplate.getId()).getRulesVersion()).isEqualTo(3); //1. beim Anlegen des DossierTemplates; 2. bei provideTestTemplate()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -162,7 +162,7 @@ public abstract class AbstractPersistenceServerServiceTest {
|
||||
@Autowired
|
||||
protected ApplicationConfigRepository applicationConfigRepository;
|
||||
@MockBean
|
||||
private RedactionClient redactionClient;
|
||||
protected RedactionClient redactionClient;
|
||||
@Autowired
|
||||
protected PrometheusMeterRegistry prometheusMeterRegistry;
|
||||
@MockBean
|
||||
@ -247,7 +247,7 @@ public abstract class AbstractPersistenceServerServiceTest {
|
||||
when(amqpAdmin.getQueueInfo(Mockito.any())).thenReturn(null);
|
||||
when(entityLogService.getEntityLog(Mockito.any(), Mockito.any())).thenReturn(new EntityLog(1, 1, Lists.newArrayList(), null, 0, 0, 0, 0));
|
||||
when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyBoolean())).thenReturn(new EntityLog(1, 1, Lists.newArrayList(), null, 0, 0, 0, 0));
|
||||
when(redactionClient.testRules(Mockito.any())).thenReturn(DroolsSyntaxValidation.builder().droolsSyntaxErrorMessages(Collections.emptyList()).build());
|
||||
when(redactionClient.testRules(Mockito.any())).thenReturn(DroolsSyntaxValidation.builder().droolsSyntaxErrorMessages(Collections.emptyList()).droolsSyntaxDeprecatedWarnings(Collections.emptyList()).build());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -25,4 +25,16 @@ public class RulesUploadRequestModel {
|
||||
@Schema(description = "The Rule file type of these rules", allowableValues = {"ENTITY", "COMPONENT"})
|
||||
private RuleFileType ruleFileType = RuleFileType.ENTITY;
|
||||
|
||||
@Schema(description = "The dry-run parameter if set to true the file is not saved (only the validation results are returned", defaultValue = "false")
|
||||
private boolean dryRun;
|
||||
|
||||
|
||||
public RulesUploadRequestModel(@NonNull String rules, @NonNull String dossierTemplateId, RuleFileType ruleFileType) {
|
||||
|
||||
this.rules = rules;
|
||||
this.dossierTemplateId = dossierTemplateId;
|
||||
this.ruleFileType = ruleFileType;
|
||||
this.dryRun = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user