From 7584de13e9fcf43d0736485e2bb957076c77810b Mon Sep 17 00:00:00 2001 From: dhananjay12 Date: Fri, 10 Sep 2021 07:05:01 +0200 Subject: [PATCH 01/11] Upload specs to Boat bay server --- boat-maven-plugin/pom.xml | 107 ++++ .../java/com/backbase/oss/boat/RadioMojo.java | 167 +++++++ .../main/resources/boat-maven-plugin-api.yaml | 44 ++ .../main/resources/schemas/definitions.yaml | 458 ++++++++++++++++++ .../com/backbase/oss/boat/RadioMojoTests.java | 200 ++++++++ 5 files changed, 976 insertions(+) create mode 100644 boat-maven-plugin/src/main/java/com/backbase/oss/boat/RadioMojo.java create mode 100644 boat-maven-plugin/src/main/resources/boat-maven-plugin-api.yaml create mode 100644 boat-maven-plugin/src/main/resources/schemas/definitions.yaml create mode 100644 boat-maven-plugin/src/test/java/com/backbase/oss/boat/RadioMojoTests.java diff --git a/boat-maven-plugin/pom.xml b/boat-maven-plugin/pom.xml index d0b163cf6..13e91185f 100644 --- a/boat-maven-plugin/pom.xml +++ b/boat-maven-plugin/pom.xml @@ -25,6 +25,11 @@ reuseReports ${project.basedir}/target/jacoco-it.exec + 10.11 + 3.8.0 + 2.9.10 + 8.0.0 + 1.5.24 @@ -136,6 +141,81 @@ test + + io.swagger + swagger-annotations + ${swagger-annotations-version} + + + + + com.google.code.findbugs + jsr305 + 3.0.2 + + + + + io.github.openfeign + feign-core + ${feign-version} + + + io.github.openfeign + feign-jackson + ${feign-version} + + + io.github.openfeign + feign-slf4j + ${feign-version} + + + io.github.openfeign.form + feign-form + ${feign-form-version} + + + io.github.openfeign + feign-okhttp + ${feign-version} + + + + + com.fasterxml.jackson.core + jackson-core + + + com.fasterxml.jackson.core + jackson-annotations + + + com.fasterxml.jackson.core + jackson-databind + + + org.openapitools + jackson-databind-nullable + + + com.github.joschi.jackson + jackson-datatype-threetenbp + ${jackson-threetenbp-version} + + + com.github.scribejava + scribejava-core + ${scribejava-version} + + + + + com.squareup.okhttp3 + mockwebserver + 4.9.1 + test + @@ -251,6 +331,33 @@ + + org.openapitools + openapi-generator-maven-plugin + 5.0.0 + + + + generate + + + ${project.basedir}/src/main/resources/boat-maven-plugin-api.yaml + java + false + false + false + false + + src/gen/java/main + com.backbase.oss.boat.bay.client.model + com.backbase.oss.boat.bay.client.api + feign + java8-localdatetime + + + + + diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/RadioMojo.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/RadioMojo.java new file mode 100644 index 000000000..be7f3b87c --- /dev/null +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/RadioMojo.java @@ -0,0 +1,167 @@ +package com.backbase.oss.boat; + +import com.backbase.oss.boat.bay.client.ApiClient; +import com.backbase.oss.boat.bay.client.api.BoatMavenPluginApi; +import com.backbase.oss.boat.bay.client.model.BoatLintReport; +import com.backbase.oss.boat.bay.client.model.UploadRequestBody; +import com.backbase.oss.boat.bay.client.model.UploadSpec; +import com.backbase.oss.boat.loader.OpenAPILoader; +import com.backbase.oss.boat.loader.OpenAPILoaderException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationConfig; +import feign.auth.BasicAuthRequestInterceptor; +import io.swagger.v3.oas.models.OpenAPI; +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import lombok.Data; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; + +@Mojo(name = "radio", requiresDependencyResolution = ResolutionScope.RUNTIME, threadSafe = true) +@Slf4j +public class RadioMojo extends AbstractMojo { + + @Parameter(property = "groupId", defaultValue = "${project.groupId}", required = true) + String groupId; + + @Parameter(property = "artifactId", defaultValue = "${project.artifactId}", required = true) + String artifactId; + + @Parameter(property = "version", defaultValue = "${project.version}", required = true) + String version; + + @Parameter(property = "basePath", required = true) + String basePath; + + @Parameter(property = "portalKey", required = true) + String portalKey; + + @Parameter(property = "sourceKey", required = true) + String sourceKey; + + @Parameter(property = "username", required = false) + String username; + + @Parameter(property = "password", required = false) + String password; + + @Parameter(property = "specs") + SpecConfig[] specs; + + @Parameter(name = "radioOutput", defaultValue = "${project.build.directory}/target/boat-radio-report") + File radioOutput; + + @Override + public void execute() throws MojoExecutionException, MojoFailureException { + + BasicAuthRequestInterceptor basicAuthRequestInterceptor = null; + + ObjectMapper objectMapper = new ObjectMapper(); + + if(username != null && !username.isEmpty() && password != null && !password.isEmpty()){ + basicAuthRequestInterceptor = new BasicAuthRequestInterceptor(username, password); + }else{ + getLog().warn("No Authentication set"); + } + + List allSpecs = Arrays.stream(specs).map(this::mapToUploadSpec).collect(Collectors.toList()); + + ApiClient apiClient = new ApiClient().setBasePath(basePath); + if(basicAuthRequestInterceptor != null){ + apiClient.addAuthorization("Basic Auth", basicAuthRequestInterceptor); + } + + BoatMavenPluginApi api = apiClient.buildClient(BoatMavenPluginApi.class); + + UploadRequestBody uploadRequestBody = new UploadRequestBody(); + uploadRequestBody.setGroupId(groupId); + uploadRequestBody.setArtifactId(artifactId); + uploadRequestBody.setVersion(version); + uploadRequestBody.setSpecs(allSpecs); + + List reports = api.uploadSpec(portalKey,sourceKey,uploadRequestBody); + + try { + objectMapper.writerWithDefaultPrettyPrinter().writeValue(new File(getOutput(), "radioOutput.json"),reports); + } catch (IOException e) { + throw new MojoFailureException("Failed to write output", e); + } + + } + + private UploadSpec mapToUploadSpec(SpecConfig spec) { + + OpenAPI openApi = null; + String contents = null; + File file = spec.getInputSpec(); + try { + contents = IOUtils.toString(spec.getInputSpec().toURI(), Charset.defaultCharset()); + openApi = OpenAPILoader.parse(contents); + } catch ( IOException e) { + String msg = "Invalid File Path: " + file.getName(); + getLog().error(msg); + throw new RuntimeException(msg, e); + } catch (OpenAPILoaderException e) { + String msg = "Invalid Open Api file: " + file.getName(); + getLog().error(msg); + throw new RuntimeException(msg, e); + } + + String key = spec.getKey(); + if (key == null || key.isEmpty()) { + key = file.getName().substring(0, file.getName().lastIndexOf("-")); + } + + String name = spec.getName(); + if (name == null || name.isEmpty()) { + name = file.getName(); + } + + UploadSpec uploadSpec = new UploadSpec(); + uploadSpec.setFileName(file.getName()); + uploadSpec.setKey(key); + uploadSpec.setName(name); + uploadSpec.setOpenApi(contents); + + + return uploadSpec; + + } + + @SneakyThrows + private File getOutput() { + if (radioOutput == null) { + radioOutput = new File("./target/boat-radio-report"); + } + if(!radioOutput.exists()){ + radioOutput.mkdir(); + } + return radioOutput; + } + + +} + +@Data +class SpecConfig { + + private String key; + + private String name; + + private File inputSpec; + +} diff --git a/boat-maven-plugin/src/main/resources/boat-maven-plugin-api.yaml b/boat-maven-plugin/src/main/resources/boat-maven-plugin-api.yaml new file mode 100644 index 000000000..f0cdcbd0a --- /dev/null +++ b/boat-maven-plugin/src/main/resources/boat-maven-plugin-api.yaml @@ -0,0 +1,44 @@ +openapi: 3.0.0 +info: + title: Boat Bay Upload Server + description: Endpoints for uploading Specs to boat bay + license: + name: Backbase + version: 1.0.0 +servers: +- url: http://localhost:8080/ +tags: +- name: boat-maven-plugin + description: Endpoints used by the Boat Maven Plugin +paths: + /api/boat/portals/{portalKey}/boat-maven-plugin/{sourceKey}/upload: + post: + tags: + - boat-maven-plugin + summary: upload and lint specs + operationId: uploadSpec + parameters: + - $ref: 'schemas/definitions.yaml#/components/parameters/PortalKey' + - name: sourceKey + in: path + description: source identifier + required: true + style: simple + explode: false + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: 'schemas/definitions.yaml#/components/schemas/UploadRequestBody' + required: true + responses: + "200": + description: list of lint reports for specs + content: + application/json: + schema: + type: array + items: + $ref: 'schemas/definitions.yaml#/components/schemas/BoatLintReport' diff --git a/boat-maven-plugin/src/main/resources/schemas/definitions.yaml b/boat-maven-plugin/src/main/resources/schemas/definitions.yaml new file mode 100644 index 000000000..d09915508 --- /dev/null +++ b/boat-maven-plugin/src/main/resources/schemas/definitions.yaml @@ -0,0 +1,458 @@ +openapi: 3.0.3 +info: + title: Shared Components BOAT BAY + version: 1.0.0 +paths: {} +components: + schemas: + BoatPortal: + type: object + properties: + id: + type: number + key: + type: string + name: + type: string + content: + type: string + createdOn: + type: string + format: date-time + createdBy: + type: string + numberOfServices: + type: integer + numberOfCapabilities: + type: integer + productDescription: + type: string + lastLintReport: + $ref: '#/components/schemas/BoatLintReport' + statistics: + $ref: '#/components/schemas/BoatStatistics' + required: + - id + - key + - name + BoatProduct: + type: object + properties: + portalKey: + type: string + portalName: + type: string + id: + type: number + key: + type: string + name: + type: string + content: + type: string + createdOn: + type: string + format: date-time + createdBy: + type: string + lastLintReport: + $ref: '#/components/schemas/BoatLintReport' + statistics: + $ref: '#/components/schemas/BoatStatistics' + jiraProjectId: + type: string + required: + - portalKey + - portalName + - id + - key + - name + BoatCapability: + type: object + properties: + id: + type: number + key: + type: string + name: + type: string + content: + type: string + createdOn: + type: string + format: date-time + createdBy: + type: string + services: + type: array + items: + $ref: '#/components/schemas/BoatService' + lastLintReport: + $ref: '#/components/schemas/BoatLintReport' + statistics: + $ref: '#/components/schemas/BoatStatistics' + required: + - id + - key + - name + BoatService: + type: object + properties: + id: + type: number + key: + type: string + name: + type: string + description: + type: string + icon: + type: string + color: + type: string + createdOn: + type: string + format: date-time + createdBy: + type: string + statistics: + $ref: '#/components/schemas/BoatStatistics' + capability: + $ref: '#/components/schemas/BoatCapability' + required: + - id + - key + - name + - capability + BoatSpec: + type: object + properties: + id: + type: number + key: + type: string + name: + type: string + title: + type: string + description: + type: string + icon: + type: string + version: + type: string + grade: + type: string + createdOn: + type: string + format: date-time + createdBy: + type: string + statistics: + $ref: '#/components/schemas/BoatStatistics' + backwardsCompatible: + type: boolean + changes: + $ref: '#/components/schemas/Changes' + capability: + $ref: '#/components/schemas/BoatCapability' + serviceDefinition: + $ref: '#/components/schemas/BoatService' + openApi: + type: string + required: + - id + - key + - name + - version + - capability + - serviceDefinition + BoatLintReport: + type: object + properties: + id: + type: number + spec: + $ref: '#/components/schemas/BoatSpec' + name: + type: string + passed: + type: boolean + lintedOn: + type: string + format: date-time + openApi: + type: string + version: + type: string + grade: + type: string + violations: + type: array + items: + $ref: '#/components/schemas/BoatViolation' + required: + - id + - sec + - name + - passed + - lintedOn + - openApi + - version + - grade + - spec + - violations + BoatLintRule: + type: object + properties: + id: + type: number + ruleId: + type: string + enabled: + type: boolean + title: + type: string + ruleSet: + type: string + severity: + $ref: '#/components/schemas/Severity' + url: + type: string + format: uri + required: + - id + - ruleId + - enabled + - title + - ruleSet + - severity + - url + BoatProductRelease: + type: object + properties: + id: + type: number + key: + type: string + name: + type: string + version: + type: string + releaseDate: + type: string + format: date-time + required: + - id + - key + - name + - version + - releaseDate + BoatTag: + type: object + properties: + name: + type: string + description: + type: string + hide: + type: boolean + color: + type: string + numberOfOccurrences: + type: integer + required: + - name + Resource: + type: array + items: + type: string + format: byte + BoatStatistics: + type: object + properties: + updatedOn: + type: string + format: date-time + mustViolationsCount: + type: integer + format: int64 + shouldViolationsCount: + type: integer + format: int64 + mayViolationsCount: + type: integer + format: int64 + hintViolationsCount: + type: integer + format: int64 + required: + - updatedOn + - mustViolationsCount + - shouldViolationsCount + - mayViolationsCount + - hintViolationsCount + Changes: + type: string + enum: + - INVALID_VERSION + - NOT_APPLICABLE + - ERROR_COMPARING + - UNCHANGED + - COMPATIBLE + - BREAKING + BoatViolation: + type: object + properties: + rule: + $ref: '#/components/schemas/BoatLintRule' + description: + type: string + severity: + $ref: '#/components/schemas/Severity' + lines: + $ref: '#/components/schemas/IntRange' + pointer: + type: string + required: + - rule + - description + - lines + - pointer + - severity + Severity: + type: string + enum: + - MUST + - SHOULD + - MAY + - HINT + UploadRequestBody: + type: object + properties: + specs: + type: array + items: + $ref: '#/components/schemas/UploadSpec' + groupId: + type: string + artifactId: + type: string + version: + type: string + required: + - specs + - artifactId + - groupId + - version + UploadSpec: + type: object + properties: + fileName: + type: string + openApi: + type: string + key: + type: string + name: + type: string + required: + - fileName + - openApi + - name + IntRange: + type: object + properties: + start: + type: integer + endInclusive: + type: integer + required: + - start + - endInclusive + parameters: + PortalKey: + name: portalKey + in: path + description: Portal Identifier + required: true + schema: + type: string + ProductKey: + name: productKey + in: path + description: Product Identifier + required: true + schema: + type: string + CapabilityKey: + name: capabilityKey + in: path + description: Capability Identifier + required: true + schema: + type: string + ServiceKey: + name: serviceKey + in: path + description: Service Identifier + required: true + schema: + type: string + SpecKey: + name: specKey + in: path + description: Spec Identifier + required: true + schema: + type: string + ReleaseKey: + name: releaseKey + in: path + description: Product Release Identifier + required: true + schema: + type: string + SpecId: + name: specId + in: path + description: Unique Spec Identifier + required: true + schema: + type: number + Version: + name: version + in: path + description: Spec Version + required: true + schema: + type: string + Page: + name: page + in: query + required: true + schema: + type: integer + Size: + name: size + in: query + required: true + schema: + type: integer + Sort: + name: sort + in: query + required: true + schema: + type: array + items: + type: string + headers: + X-Total-Count: + description: "Total amount of items" + schema: + type: integer + Link: + description: "Link" + schema: + type: string diff --git a/boat-maven-plugin/src/test/java/com/backbase/oss/boat/RadioMojoTests.java b/boat-maven-plugin/src/test/java/com/backbase/oss/boat/RadioMojoTests.java new file mode 100644 index 000000000..8ef8a8d53 --- /dev/null +++ b/boat-maven-plugin/src/test/java/com/backbase/oss/boat/RadioMojoTests.java @@ -0,0 +1,200 @@ +package com.backbase.oss.boat; + +import com.backbase.oss.boat.bay.client.model.BoatLintReport; +import com.backbase.oss.boat.bay.client.model.UploadRequestBody; +import com.backbase.oss.boat.bay.client.model.UploadSpec; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.File; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import okhttp3.mockwebserver.Dispatcher; +import okhttp3.mockwebserver.MockResponse; +import okhttp3.mockwebserver.MockWebServer; +import okhttp3.mockwebserver.RecordedRequest; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +@Slf4j +class RadioMojoTests { + + static MockWebServer mockBackEnd; + + ObjectMapper objectMapper = new ObjectMapper(); + + @BeforeAll + @SneakyThrows + static void setUp() { + mockBackEnd = new MockWebServer(); + mockBackEnd.start(); + } + + @Test + @SneakyThrows + void test() { + + final String portalKey = "example"; + final String sourceKey = "pet-store-bom"; + final String specKey = "spec-key"; + final String specValue = "spec-name"; + final String groupId = "com.backbase.boat.samples"; + final String artifactId = "pet-store-bom"; + final String version = "2021.09"; + final String fileName = "one-client-api-v1.yaml"; + + final BigDecimal reportId = BigDecimal.valueOf(10); + final String reportGrade = "A"; + + SpecConfig specConfig = new SpecConfig(); + specConfig.setKey(specKey); + specConfig.setName(specValue); + specConfig.setInputSpec(getFile("/bundler/folder/" + fileName)); + + RadioMojo mojo = new RadioMojo(); + mojo.groupId = groupId; + mojo.artifactId = artifactId; + mojo.version = version; + mojo.portalKey = portalKey; + mojo.sourceKey = sourceKey; + mojo.specs = new SpecConfig[]{specConfig}; + mojo.basePath = String.format("http://localhost:%s", mockBackEnd.getPort()); + + final Dispatcher dispatcher = new Dispatcher() { + @SneakyThrows + @Override + public MockResponse dispatch(RecordedRequest request) { + switch (request.getPath()) { + case "/api/boat/portals/" + portalKey + "/boat-maven-plugin/" + sourceKey + "/upload": + + UploadRequestBody requestBody = objectMapper.readValue(request.getBody().readUtf8(), UploadRequestBody.class); + UploadSpec uploadSpec = requestBody.getSpecs().get(0); + + if (requestBody.getGroupId().equals(groupId) && + requestBody.getArtifactId().equals(artifactId) && + requestBody.getVersion().equals(version) && + uploadSpec.getKey().equals(specKey) && + uploadSpec.getName().equals(specValue) && + uploadSpec.getFileName().equals(fileName) && + uploadSpec.getOpenApi().length() > 0 + ) { + log.info(uploadSpec.getOpenApi()); + BoatLintReport boatLintReport = new BoatLintReport(); + boatLintReport.setId(reportId); + boatLintReport.setGrade(reportGrade); + List result = new ArrayList<>(); + result.add(boatLintReport); + return new MockResponse().setResponseCode(200).setBody(objectMapper.writeValueAsString(result)); + } else { + return new MockResponse().setResponseCode(400); + } + } + return new MockResponse().setResponseCode(404); + } + }; + + mockBackEnd.setDispatcher(dispatcher); + + mojo.execute(); + + File output = new File(mojo.radioOutput, "radioOutput.json"); + + assertTrue(output.exists()); + + List result = Arrays.asList(objectMapper.readValue(output, BoatLintReport[].class)); + + assertTrue(result.size() == 1); + assertTrue(result.get(0).getId().equals(reportId)); + assertTrue(result.get(0).getGrade().equals(reportGrade)); + + } + + + @Test + @SneakyThrows + void test_Empty_SpecKeyAndName() { + + final String portalKey = "example"; + final String sourceKey = "pet-store-bom"; + final String groupId = "com.backbase.boat.samples"; + final String artifactId = "pet-store-bom"; + final String version = "2021.09"; + final String fileName = "one-client-api-v2.yaml"; + + final BigDecimal reportId = BigDecimal.valueOf(20); + final String reportGrade = "B"; + + SpecConfig specConfig = new SpecConfig(); + specConfig.setInputSpec(getFile("/bundler/folder/" + fileName)); + + RadioMojo mojo = new RadioMojo(); + mojo.groupId = groupId; + mojo.artifactId = artifactId; + mojo.version = version; + mojo.portalKey = portalKey; + mojo.sourceKey = sourceKey; + mojo.specs = new SpecConfig[]{specConfig}; + mojo.basePath = String.format("http://localhost:%s", mockBackEnd.getPort()); + + final Dispatcher dispatcher = new Dispatcher() { + @SneakyThrows + @Override + public MockResponse dispatch(RecordedRequest request) { + switch (request.getPath()) { + case "/api/boat/portals/" + portalKey + "/boat-maven-plugin/" + sourceKey + "/upload": + + UploadRequestBody requestBody = objectMapper.readValue(request.getBody().readUtf8(), UploadRequestBody.class); + UploadSpec uploadSpec = requestBody.getSpecs().get(0); + + String expectedDefaultKey = fileName.substring(0, fileName.lastIndexOf("-")); + String expectedDefaultName = fileName; + + if (requestBody.getGroupId().equals(groupId) && + requestBody.getArtifactId().equals(artifactId) && + requestBody.getVersion().equals(version) && + uploadSpec.getKey().equals(expectedDefaultKey) && + uploadSpec.getName().equals(expectedDefaultName) && + uploadSpec.getFileName().equals(fileName) && + uploadSpec.getOpenApi().length() > 0 + ) { + log.info(uploadSpec.getOpenApi()); + BoatLintReport boatLintReport = new BoatLintReport(); + boatLintReport.setId(reportId); + boatLintReport.setGrade(reportGrade); + List result = new ArrayList<>(); + result.add(boatLintReport); + return new MockResponse().setResponseCode(200).setBody(objectMapper.writeValueAsString(result)); + } else { + return new MockResponse().setResponseCode(400); + } + } + return new MockResponse().setResponseCode(404); + } + }; + + mockBackEnd.setDispatcher(dispatcher); + + mojo.execute(); + + File output = new File(mojo.radioOutput, "radioOutput.json"); + + assertTrue(output.exists()); + + List result = Arrays.asList(objectMapper.readValue(output, BoatLintReport[].class)); + + assertTrue(result.size() == 1); + assertTrue(result.get(0).getId().equals(reportId)); + assertTrue(result.get(0).getGrade().equals(reportGrade)); + + } + + + private File getFile(String fileName) { + return new File(getClass().getResource(fileName).getFile()); + } + +} \ No newline at end of file From 9ac9bd096b17efbb9c7485d7b72741654eaff536 Mon Sep 17 00:00:00 2001 From: dhananjay12 Date: Fri, 10 Sep 2021 07:22:30 +0200 Subject: [PATCH 02/11] Upload specs to Boat bay server --- .../java/com/backbase/oss/boat/RadioMojo.java | 24 ++++++++------ .../com/backbase/oss/boat/RadioMojoTests.java | 32 +++++++++---------- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/RadioMojo.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/RadioMojo.java index be7f3b87c..29826abae 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/RadioMojo.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/RadioMojo.java @@ -19,6 +19,8 @@ import java.util.List; import java.util.stream.Collectors; import lombok.Data; +import lombok.Getter; +import lombok.Setter; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; @@ -32,37 +34,39 @@ @Mojo(name = "radio", requiresDependencyResolution = ResolutionScope.RUNTIME, threadSafe = true) @Slf4j +@Getter +@Setter public class RadioMojo extends AbstractMojo { @Parameter(property = "groupId", defaultValue = "${project.groupId}", required = true) - String groupId; + private String groupId; @Parameter(property = "artifactId", defaultValue = "${project.artifactId}", required = true) - String artifactId; + private String artifactId; @Parameter(property = "version", defaultValue = "${project.version}", required = true) - String version; + private String version; @Parameter(property = "basePath", required = true) - String basePath; + private String basePath; @Parameter(property = "portalKey", required = true) - String portalKey; + private String portalKey; @Parameter(property = "sourceKey", required = true) - String sourceKey; + private String sourceKey; @Parameter(property = "username", required = false) - String username; + private String username; @Parameter(property = "password", required = false) - String password; + private String password; @Parameter(property = "specs") - SpecConfig[] specs; + private SpecConfig[] specs; @Parameter(name = "radioOutput", defaultValue = "${project.build.directory}/target/boat-radio-report") - File radioOutput; + private File radioOutput; @Override public void execute() throws MojoExecutionException, MojoFailureException { diff --git a/boat-maven-plugin/src/test/java/com/backbase/oss/boat/RadioMojoTests.java b/boat-maven-plugin/src/test/java/com/backbase/oss/boat/RadioMojoTests.java index 8ef8a8d53..ba6e155f2 100644 --- a/boat-maven-plugin/src/test/java/com/backbase/oss/boat/RadioMojoTests.java +++ b/boat-maven-plugin/src/test/java/com/backbase/oss/boat/RadioMojoTests.java @@ -56,13 +56,13 @@ void test() { specConfig.setInputSpec(getFile("/bundler/folder/" + fileName)); RadioMojo mojo = new RadioMojo(); - mojo.groupId = groupId; - mojo.artifactId = artifactId; - mojo.version = version; - mojo.portalKey = portalKey; - mojo.sourceKey = sourceKey; - mojo.specs = new SpecConfig[]{specConfig}; - mojo.basePath = String.format("http://localhost:%s", mockBackEnd.getPort()); + mojo.setGroupId(groupId); + mojo.setArtifactId(artifactId); + mojo.setVersion(version); + mojo.setPortalKey(portalKey); + mojo.setSourceKey(sourceKey); + mojo.setSpecs(new SpecConfig[]{specConfig}); + mojo.setBasePath(String.format("http://localhost:%s", mockBackEnd.getPort())); final Dispatcher dispatcher = new Dispatcher() { @SneakyThrows @@ -101,7 +101,7 @@ public MockResponse dispatch(RecordedRequest request) { mojo.execute(); - File output = new File(mojo.radioOutput, "radioOutput.json"); + File output = new File(mojo.getRadioOutput(), "radioOutput.json"); assertTrue(output.exists()); @@ -132,13 +132,13 @@ void test_Empty_SpecKeyAndName() { specConfig.setInputSpec(getFile("/bundler/folder/" + fileName)); RadioMojo mojo = new RadioMojo(); - mojo.groupId = groupId; - mojo.artifactId = artifactId; - mojo.version = version; - mojo.portalKey = portalKey; - mojo.sourceKey = sourceKey; - mojo.specs = new SpecConfig[]{specConfig}; - mojo.basePath = String.format("http://localhost:%s", mockBackEnd.getPort()); + mojo.setGroupId(groupId); + mojo.setArtifactId(artifactId); + mojo.setVersion(version); + mojo.setPortalKey(portalKey); + mojo.setSourceKey(sourceKey); + mojo.setSpecs(new SpecConfig[]{specConfig}); + mojo.setBasePath(String.format("http://localhost:%s", mockBackEnd.getPort())); final Dispatcher dispatcher = new Dispatcher() { @SneakyThrows @@ -180,7 +180,7 @@ public MockResponse dispatch(RecordedRequest request) { mojo.execute(); - File output = new File(mojo.radioOutput, "radioOutput.json"); + File output = new File(mojo.getRadioOutput(), "radioOutput.json"); assertTrue(output.exists()); From f1399cf0a076de816be5237baa479230f120dc08 Mon Sep 17 00:00:00 2001 From: dhananjay12 Date: Mon, 13 Sep 2021 01:14:55 +0200 Subject: [PATCH 03/11] Upload mojo --- boat-maven-plugin/README.md | 89 +++++++++++++++++++ boat-maven-plugin/pom.xml | 1 + .../oss/boat/{ => radio}/RadioMojo.java | 83 ++++++++--------- .../backbase/oss/boat/radio/SpecConfig.java | 36 ++++++++ .../oss/boat/{ => radio}/RadioMojoTests.java | 20 ++--- 5 files changed, 175 insertions(+), 54 deletions(-) rename boat-maven-plugin/src/main/java/com/backbase/oss/boat/{ => radio}/RadioMojo.java (82%) create mode 100644 boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/SpecConfig.java rename boat-maven-plugin/src/test/java/com/backbase/oss/boat/{ => radio}/RadioMojoTests.java (93%) diff --git a/boat-maven-plugin/README.md b/boat-maven-plugin/README.md index 0e340c274..017071278 100644 --- a/boat-maven-plugin/README.md +++ b/boat-maven-plugin/README.md @@ -255,6 +255,95 @@ Usage Or hook up to your build process by adding ```executions``` configuration. +## boat:radio + +Upload specs (one of more) to Boat-Bay. + +Available parameters: + + artifactId (Default: ${project.artifactId}) + User property: artifactId + Project ArtifactId in Boat-Bay. Defaults to ${project.artifactId} + + boatBayUrl + Required: true + User property: boatBayUrl + Boat-Bay domain. eg. https://boatbay.mycompany.eu + + groupId (Default: ${project.groupId}) + User property: groupId + Project GroupId in Boat-Bay. Defaults to ${project.groupId} + + password + User property: password + Defines the password of the username which can access the Boat-Bay upload + API. Required if boat-bay APIs are protected. + + portalKey + Required: true + User property: portalKey + Project portal Identifier in Boat-Bay. + + radioOutput (Default: + ${project.build.directory}/target/boat-radio-report) + Output directory for boat-radio report. + + sourceKey + Required: true + User property: sourceKey + Project source identifier in Boat-Bay. + + specs + Required: true + User property: specs + Array of spec to be uploaded. Spec fields: + + key : Spec Key in Boat-Bay. Defaults to filename.lastIndexOf('-'). For + example - By default my-service-api-v3.1.4.yaml would be evaluated to + my-service-api + + name : Spec Name in Boat-Bay. Defaults to filename. + + inputSpec : Location of the OpenAPI spec, as URL or local file glob + pattern. If the input is a local file, the value of this property is + considered a glob pattern that must resolve to a unique file. The glob + pattern allows to express the input specification in a version neutral + way. For instance, if the actual file is my-service-api-v3.1.4.yaml the + expression could be my-service-api-v*.yaml. + + username + User property: username + Defines the username which can access Boat-Bay upload API. Required if + boat-bay APIs are protected. + + version (Default: ${project.version}) + User property: version + Project Version in Boat-Bay. Defaults to ${project.version} + +Configuration example: + +```$xml + + upload-specs + install + + radio + + + pet-store-bom + example + https://boatbay.backbase.eu + admin + admin + + + ${project.build.directory}/spec/bundled/pet-store-client-api-*.yaml + + + + +``` + ## boat:transform Apply transformers to an existing specification. diff --git a/boat-maven-plugin/pom.xml b/boat-maven-plugin/pom.xml index 9e95c86ab..7c909034c 100644 --- a/boat-maven-plugin/pom.xml +++ b/boat-maven-plugin/pom.xml @@ -359,6 +359,7 @@ com.backbase.oss.boat.bay.client.api feign java8-localdatetime + @lombok.AllArgsConstructor @lombok.Builder @lombok.NoArgsConstructor diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/RadioMojo.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java similarity index 82% rename from boat-maven-plugin/src/main/java/com/backbase/oss/boat/RadioMojo.java rename to boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java index 48b2526f1..b2be5d973 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/RadioMojo.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java @@ -1,5 +1,6 @@ -package com.backbase.oss.boat; +package com.backbase.oss.boat.radio; +import com.backbase.oss.boat.Utils; import com.backbase.oss.boat.bay.client.ApiClient; import com.backbase.oss.boat.bay.client.api.BoatMavenPluginApi; import com.backbase.oss.boat.bay.client.model.BoatLintReport; @@ -15,7 +16,6 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; -import lombok.Data; import lombok.Getter; import lombok.Setter; import lombok.SneakyThrows; @@ -31,7 +31,7 @@ import static java.lang.String.format; /** - * Uploads specs (one of more) to Boat-Bay. + * Upload specs (one of more) to Boat-Bay. */ @Mojo(name = "radio", requiresDependencyResolution = ResolutionScope.RUNTIME, threadSafe = true) @Slf4j @@ -42,26 +42,26 @@ public class RadioMojo extends AbstractMojo { /** * Project GroupId in Boat-Bay. Defaults to {@code ${project.groupId}} */ - @Parameter(property = "groupId", defaultValue = "${project.groupId}", required = true) + @Parameter(property = "groupId", defaultValue = "${project.groupId}") private String groupId; /** * Project ArtifactId in Boat-Bay. Defaults to {@code ${project.artifactId}} */ - @Parameter(property = "artifactId", defaultValue = "${project.artifactId}", required = true) + @Parameter(property = "artifactId", defaultValue = "${project.artifactId}") private String artifactId; /** * Project Version in Boat-Bay. Defaults to {@code ${project.version}} */ - @Parameter(property = "version", defaultValue = "${project.version}", required = true) + @Parameter(property = "version", defaultValue = "${project.version}") private String version; /** * Boat-Bay domain. eg. https://boatbay.mycompany.eu */ - @Parameter(property = "basePath", required = true) - private String basePath; + @Parameter(property = "boatBayUrl", required = true) + private String boatBayUrl; /** * Project portal Identifier in Boat-Bay. @@ -78,25 +78,46 @@ public class RadioMojo extends AbstractMojo { /** * Defines the username which can access Boat-Bay upload API. Required if boat-bay APIs are protected. */ - @Parameter(property = "username", required = false) + @Parameter(property = "username") private String username; /** * Defines the password of the username which can access the Boat-Bay upload API. Required if boat-bay APIs are protected. */ - @Parameter(property = "password", required = false) + @Parameter(property = "password") private String password; /** - * Array of specs to be uploaded. + *

+ * Array of spec to be uploaded. Spec fields: + *

+ *

+ * {@code key} : + * Spec Key in Boat-Bay. Defaults to {@code filename.lastIndexOf("-")}. + * For example - By default {@code my-service-api-v3.1.4.yaml} would be evaluated to {@code my-service-api} + *

+ *

+ * {@code name} : + * Spec Name in Boat-Bay. Defaults to filename. + *

+ *

+ * {@code inputSpec} : + * Location of the OpenAPI spec, as URL or local file glob pattern. + * If the input is a local file, the value of this property is considered a glob pattern that must + * resolve to a unique file. + * The glob pattern allows to express the input specification in a version neutral way. For + * instance, if the actual file is {@code my-service-api-v3.1.4.yaml} the expression could be + * {@code my-service-api-v*.yaml}. + *

+ * */ - @Parameter(property = "specs") + @Parameter(property = "specs", required = true) private SpecConfig[] specs; /** * Output directory for boat-radio report. */ - @Parameter(name = "radioOutput", defaultValue = "${project.build.directory}/target/boat-radio-report") + @Parameter(name = "radioOutput", defaultValue = "${project.build.directory}/target/boat-radio-report" ) private File radioOutput; @Override @@ -119,7 +140,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { allSpecs.add(mapToUploadSpec(spec)); } - ApiClient apiClient = new ApiClient().setBasePath(basePath); + ApiClient apiClient = new ApiClient().setBasePath(boatBayUrl); if (basicAuthRequestInterceptor != null) { apiClient.addAuthorization("Basic Auth", basicAuthRequestInterceptor); } @@ -137,7 +158,10 @@ public void execute() throws MojoExecutionException, MojoFailureException { try { File outputFile = new File(getOutput(), "radioOutput.json"); objectMapper.writerWithDefaultPrettyPrinter().writeValue(outputFile, reports); - getLog().info("UPLOAD TO BOAT-BAY SUCCESSFUL, check the report: " + outputFile.getCanonicalPath()); + reports.forEach(report -> { + getLog().info(format("Changes to spec %s is %s", report.getSpec().getKey(), report.getSpec().getChanges())); + }); + getLog().info("UPLOAD TO BOAT-BAY SUCCESSFUL, check the full report: " + outputFile.getCanonicalPath()); } catch (IOException e) { throw new MojoFailureException("Failed to write output", e); } @@ -231,32 +255,3 @@ private File getOutput() { } -@Data -class SpecConfig { - - /** - * Spec Key in Boat-Bay. Defaults to {@code inputSpecFile.getName().lastIndexOf("-")}. - * For example - By default {@code my-service-api-v3.1.4.yaml} would be evaluated to {@code my-service-api} - */ - private String key; - - /** - * Spec Name in Boat-Bay. Defaults to filename. - */ - private String name; - - /** - * Location of the OpenAPI spec, as URL or local file glob pattern. - *

- * If the input is a local file, the value of this property is considered a glob pattern that must - * resolve to a unique file. - *

- *

- * The glob pattern allows to express the input specification in a version neutral way. For - * instance, if the actual file is {@code my-service-api-v3.1.4.yaml} the expression could be - * {@code my-service-api-v*.yaml}. - *

- */ - private String inputSpec; - -} diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/SpecConfig.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/SpecConfig.java new file mode 100644 index 000000000..fdf490548 --- /dev/null +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/SpecConfig.java @@ -0,0 +1,36 @@ +package com.backbase.oss.boat.radio; + +import lombok.Data; + +@Data +/** + * Spec to be uploaded. + */ +public class SpecConfig { + + /** + * Spec Key in Boat-Bay. Defaults to {@code inputSpecFile.getName().lastIndexOf("-")}. + * For example - By default {@code my-service-api-v3.1.4.yaml} would be evaluated to {@code my-service-api} + */ + private String key; + + /** + * Spec Name in Boat-Bay. Defaults to filename. + */ + private String name; + + /** + * Location of the OpenAPI spec, as URL or local file glob pattern. + *

+ * If the input is a local file, the value of this property is considered a glob pattern that must + * resolve to a unique file. + *

+ *

+ * The glob pattern allows to express the input specification in a version neutral way. For + * instance, if the actual file is {@code my-service-api-v3.1.4.yaml} the expression could be + * {@code my-service-api-v*.yaml}. + *

+ */ + private String inputSpec; + +} diff --git a/boat-maven-plugin/src/test/java/com/backbase/oss/boat/RadioMojoTests.java b/boat-maven-plugin/src/test/java/com/backbase/oss/boat/radio/RadioMojoTests.java similarity index 93% rename from boat-maven-plugin/src/test/java/com/backbase/oss/boat/RadioMojoTests.java rename to boat-maven-plugin/src/test/java/com/backbase/oss/boat/radio/RadioMojoTests.java index a2e4d1b13..297a9aea1 100644 --- a/boat-maven-plugin/src/test/java/com/backbase/oss/boat/RadioMojoTests.java +++ b/boat-maven-plugin/src/test/java/com/backbase/oss/boat/radio/RadioMojoTests.java @@ -1,8 +1,6 @@ -package com.backbase.oss.boat; +package com.backbase.oss.boat.radio; -import com.backbase.oss.boat.bay.client.model.BoatLintReport; -import com.backbase.oss.boat.bay.client.model.UploadRequestBody; -import com.backbase.oss.boat.bay.client.model.UploadSpec; +import com.backbase.oss.boat.bay.client.model.*; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.File; import java.math.BigDecimal; @@ -38,7 +36,7 @@ static void setUp() { @Test @SneakyThrows - void test_valid_inputs() { + void test_all_valid_inputs() { final String portalKey = "example"; final String sourceKey = "pet-store-bom"; @@ -65,7 +63,7 @@ void test_valid_inputs() { mojo.setPortalKey(portalKey); mojo.setSourceKey(sourceKey); mojo.setSpecs(new SpecConfig[]{specConfig}); - mojo.setBasePath(String.format("http://localhost:%s", mockBackEnd.getPort())); + mojo.setBoatBayUrl(String.format("http://localhost:%s", mockBackEnd.getPort())); final Dispatcher dispatcher = new Dispatcher() { @SneakyThrows @@ -89,6 +87,7 @@ public MockResponse dispatch(RecordedRequest request) { BoatLintReport boatLintReport = new BoatLintReport(); boatLintReport.setId(reportId); boatLintReport.setGrade(reportGrade); + boatLintReport.setSpec(BoatSpec.builder().key(specKey).changes(Changes.COMPATIBLE).build()); List result = new ArrayList<>(); result.add(boatLintReport); return new MockResponse().setResponseCode(200).setBody(objectMapper.writeValueAsString(result)); @@ -142,7 +141,7 @@ void test_empty_specKeyAndName() { mojo.setPortalKey(portalKey); mojo.setSourceKey(sourceKey); mojo.setSpecs(new SpecConfig[]{specConfig}); - mojo.setBasePath(String.format("http://localhost:%s", mockBackEnd.getPort())); + mojo.setBoatBayUrl(String.format("http://localhost:%s", mockBackEnd.getPort())); final Dispatcher dispatcher = new Dispatcher() { @SneakyThrows @@ -168,6 +167,7 @@ public MockResponse dispatch(RecordedRequest request) { BoatLintReport boatLintReport = new BoatLintReport(); boatLintReport.setId(reportId); boatLintReport.setGrade(reportGrade); + boatLintReport.setSpec(BoatSpec.builder().key(expectedDefaultKey).changes(Changes.COMPATIBLE).build()); List result = new ArrayList<>(); result.add(boatLintReport); return new MockResponse().setResponseCode(200).setBody(objectMapper.writeValueAsString(result)); @@ -215,7 +215,7 @@ void test_multiple_file_found_error() { mojo.setPortalKey(portalKey); mojo.setSourceKey(sourceKey); mojo.setSpecs(new SpecConfig[]{specConfig}); - mojo.setBasePath(String.format("http://localhost:%s", mockBackEnd.getPort())); + mojo.setBoatBayUrl(String.format("http://localhost:%s", mockBackEnd.getPort())); final Dispatcher dispatcher = new Dispatcher() { @SneakyThrows @@ -256,7 +256,7 @@ void test_no_file_found_error() { mojo.setPortalKey(portalKey); mojo.setSourceKey(sourceKey); mojo.setSpecs(new SpecConfig[]{specConfig}); - mojo.setBasePath(String.format("http://localhost:%s", mockBackEnd.getPort())); + mojo.setBoatBayUrl(String.format("http://localhost:%s", mockBackEnd.getPort())); final Dispatcher dispatcher = new Dispatcher() { @SneakyThrows @@ -297,7 +297,7 @@ void test_invalid_parent_folder() { mojo.setPortalKey(portalKey); mojo.setSourceKey(sourceKey); mojo.setSpecs(new SpecConfig[]{specConfig}); - mojo.setBasePath(String.format("http://localhost:%s", mockBackEnd.getPort())); + mojo.setBoatBayUrl(String.format("http://localhost:%s", mockBackEnd.getPort())); final Dispatcher dispatcher = new Dispatcher() { @SneakyThrows From 0ff42367ecd54718f3bb11b44261b956c4ce9cea Mon Sep 17 00:00:00 2001 From: dhananjay12 Date: Mon, 13 Sep 2021 01:31:38 +0200 Subject: [PATCH 04/11] Updated minor version --- README.md | 3 +++ boat-engine/pom.xml | 2 +- boat-maven-plugin/pom.xml | 2 +- boat-quay/boat-quay-lint/pom.xml | 2 +- boat-quay/boat-quay-rules/pom.xml | 2 +- boat-quay/pom.xml | 2 +- boat-scaffold/pom.xml | 4 ++-- boat-terminal/pom.xml | 2 +- boat-trail-resources/pom.xml | 2 +- pom.xml | 2 +- tests/pom.xml | 2 +- 11 files changed, 14 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 96b9e4b33..896c95ad1 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,9 @@ The project is very much Work In Progress and will be published on maven central # Release Notes BOAT is still under development and subject to change. +## 0.15.0 +* *Maven Plugin* + * Added new goal `boat:radio`; see the description in the [plugin documentation](boat-maven-plugin/README.md#boatradio). ## 0.14.12 * *Boat Scaffold* * References to /examples/foo now are also dereferenced diff --git a/boat-engine/pom.xml b/boat-engine/pom.xml index 1690befbb..80a6b02f8 100644 --- a/boat-engine/pom.xml +++ b/boat-engine/pom.xml @@ -5,7 +5,7 @@ com.backbase.oss backbase-openapi-tools - 0.14.12-SNAPSHOT + 0.15.0-SNAPSHOT boat-engine jar diff --git a/boat-maven-plugin/pom.xml b/boat-maven-plugin/pom.xml index 7c909034c..8a941bb39 100644 --- a/boat-maven-plugin/pom.xml +++ b/boat-maven-plugin/pom.xml @@ -5,7 +5,7 @@ com.backbase.oss backbase-openapi-tools - 0.14.12-SNAPSHOT + 0.15.0-SNAPSHOT boat-maven-plugin diff --git a/boat-quay/boat-quay-lint/pom.xml b/boat-quay/boat-quay-lint/pom.xml index 798656d93..71eb784f4 100644 --- a/boat-quay/boat-quay-lint/pom.xml +++ b/boat-quay/boat-quay-lint/pom.xml @@ -5,7 +5,7 @@ com.backbase.oss boat-quay - 0.14.12-SNAPSHOT + 0.15.0-SNAPSHOT boat-quay-lint jar diff --git a/boat-quay/boat-quay-rules/pom.xml b/boat-quay/boat-quay-rules/pom.xml index f71a324f5..6aa1b391e 100644 --- a/boat-quay/boat-quay-rules/pom.xml +++ b/boat-quay/boat-quay-rules/pom.xml @@ -5,7 +5,7 @@ com.backbase.oss boat-quay - 0.14.12-SNAPSHOT + 0.15.0-SNAPSHOT boat-quay-rules jar diff --git a/boat-quay/pom.xml b/boat-quay/pom.xml index 0a1b2cdb4..b11807155 100644 --- a/boat-quay/pom.xml +++ b/boat-quay/pom.xml @@ -5,7 +5,7 @@ com.backbase.oss backbase-openapi-tools - 0.14.12-SNAPSHOT + 0.15.0-SNAPSHOT diff --git a/boat-scaffold/pom.xml b/boat-scaffold/pom.xml index 73e680496..746f5b2b8 100644 --- a/boat-scaffold/pom.xml +++ b/boat-scaffold/pom.xml @@ -5,7 +5,7 @@ com.backbase.oss backbase-openapi-tools - 0.14.12-SNAPSHOT + 0.15.0-SNAPSHOT boat-scaffold @@ -86,7 +86,7 @@ com.backbase.oss boat-trail-resources - 0.14.12-SNAPSHOT + 0.15.0-SNAPSHOT test diff --git a/boat-terminal/pom.xml b/boat-terminal/pom.xml index 52bb81ee5..6d02ee95c 100644 --- a/boat-terminal/pom.xml +++ b/boat-terminal/pom.xml @@ -5,7 +5,7 @@ com.backbase.oss backbase-openapi-tools - 0.14.12-SNAPSHOT + 0.15.0-SNAPSHOT boat-terminal diff --git a/boat-trail-resources/pom.xml b/boat-trail-resources/pom.xml index ed053c419..7adb6cfcf 100644 --- a/boat-trail-resources/pom.xml +++ b/boat-trail-resources/pom.xml @@ -5,7 +5,7 @@ com.backbase.oss backbase-openapi-tools - 0.14.12-SNAPSHOT + 0.15.0-SNAPSHOT boat-trail-resources diff --git a/pom.xml b/pom.xml index 7869ee27f..2a52649dc 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ com.backbase.oss backbase-openapi-tools - 0.14.12-SNAPSHOT + 0.15.0-SNAPSHOT pom Backbase Open Api Tools will help you converting RAML to OpenAPI plus many more diff --git a/tests/pom.xml b/tests/pom.xml index 13d04f625..2486df527 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -5,7 +5,7 @@ com.backbase.oss backbase-openapi-tools - 0.14.12-SNAPSHOT + 0.15.0-SNAPSHOT tests From 0dcbf4ac659f9a722e26d40e20aa01106f92da6b Mon Sep 17 00:00:00 2001 From: dhananjay12 Date: Mon, 13 Sep 2021 01:57:57 +0200 Subject: [PATCH 05/11] Added more tests --- .../backbase/oss/boat/radio/RadioMojo.java | 4 +- .../oss/boat/radio/RadioMojoTests.java | 125 ++++++++++++++++-- 2 files changed, 115 insertions(+), 14 deletions(-) diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java index b2be5d973..6aa2cb53b 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java @@ -170,7 +170,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { private UploadSpec mapToUploadSpec(SpecConfig spec) throws MojoExecutionException { - //Validate is the spec file path is valid and unique. + //Validate if the spec file path is valid and unique. File inputSpecFile = new File(spec.getInputSpec()); File inputParent = inputSpecFile.getParentFile(); @@ -204,7 +204,7 @@ private UploadSpec mapToUploadSpec(SpecConfig spec) throws MojoExecutionExceptio throw new MojoExecutionException(message); } - //Validate is the spec file is valid open-api spec + //Validate if the spec file is valid open-api spec String contents; try { contents = IOUtils.toString(inputSpecFile.toURI(), Charset.defaultCharset()); diff --git a/boat-maven-plugin/src/test/java/com/backbase/oss/boat/radio/RadioMojoTests.java b/boat-maven-plugin/src/test/java/com/backbase/oss/boat/radio/RadioMojoTests.java index 297a9aea1..e495ca695 100644 --- a/boat-maven-plugin/src/test/java/com/backbase/oss/boat/radio/RadioMojoTests.java +++ b/boat-maven-plugin/src/test/java/com/backbase/oss/boat/radio/RadioMojoTests.java @@ -2,6 +2,7 @@ import com.backbase.oss.boat.bay.client.model.*; import com.fasterxml.jackson.databind.ObjectMapper; +import feign.auth.BasicAuthRequestInterceptor; import java.io.File; import java.math.BigDecimal; import java.util.ArrayList; @@ -14,6 +15,7 @@ import okhttp3.mockwebserver.MockWebServer; import okhttp3.mockwebserver.RecordedRequest; import org.apache.maven.plugin.MojoExecutionException; +import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -84,12 +86,7 @@ public MockResponse dispatch(RecordedRequest request) { uploadSpec.getOpenApi().length() > 0 ) { log.info(uploadSpec.getOpenApi()); - BoatLintReport boatLintReport = new BoatLintReport(); - boatLintReport.setId(reportId); - boatLintReport.setGrade(reportGrade); - boatLintReport.setSpec(BoatSpec.builder().key(specKey).changes(Changes.COMPATIBLE).build()); - List result = new ArrayList<>(); - result.add(boatLintReport); + List result = getSampleBoatLintReports(specKey, reportId, reportGrade); return new MockResponse().setResponseCode(200).setBody(objectMapper.writeValueAsString(result)); } else { return new MockResponse().setResponseCode(400); @@ -164,12 +161,7 @@ public MockResponse dispatch(RecordedRequest request) { uploadSpec.getOpenApi().length() > 0 ) { log.info(uploadSpec.getOpenApi()); - BoatLintReport boatLintReport = new BoatLintReport(); - boatLintReport.setId(reportId); - boatLintReport.setGrade(reportGrade); - boatLintReport.setSpec(BoatSpec.builder().key(expectedDefaultKey).changes(Changes.COMPATIBLE).build()); - List result = new ArrayList<>(); - result.add(boatLintReport); + List result = getSampleBoatLintReports(expectedDefaultKey, reportId, reportGrade); return new MockResponse().setResponseCode(200).setBody(objectMapper.writeValueAsString(result)); } else { return new MockResponse().setResponseCode(400); @@ -277,6 +269,47 @@ public MockResponse dispatch(RecordedRequest request) { } + @Test + void test_invalid_open_api_file() { + + final String portalKey = "example"; + final String sourceKey = "pet-store-bom"; + final String groupId = "com.backbase.boat.samples"; + final String artifactId = "pet-store-bom"; + final String version = "2021.09"; + final String invalidFile = "logback.xml"; + + SpecConfig specConfig = new SpecConfig(); + specConfig.setInputSpec(getFile("/" + invalidFile)); + + RadioMojo mojo = new RadioMojo(); + mojo.setGroupId(groupId); + mojo.setArtifactId(artifactId); + mojo.setVersion(version); + mojo.setPortalKey(portalKey); + mojo.setSourceKey(sourceKey); + mojo.setSpecs(new SpecConfig[]{specConfig}); + mojo.setBoatBayUrl(String.format("http://localhost:%s", mockBackEnd.getPort())); + + final Dispatcher dispatcher = new Dispatcher() { + @SneakyThrows + @Override + public MockResponse dispatch(RecordedRequest request) { + switch (request.getPath()) { + case "/api/boat/portals/" + portalKey + "/boat-maven-plugin/" + sourceKey + "/upload": + + return new MockResponse().setResponseCode(200); + } + return new MockResponse().setResponseCode(404); + } + }; + + mockBackEnd.setDispatcher(dispatcher); + + assertThrows(MojoExecutionException.class, () -> mojo.execute()); + + } + @Test void test_invalid_parent_folder() { @@ -320,9 +353,77 @@ public MockResponse dispatch(RecordedRequest request) { } + @SneakyThrows + @Test + void test_auth() { + + final String portalKey = "example"; + final String sourceKey = "pet-store-bom"; + final String specKey = "spec-key"; + final String groupId = "com.backbase.boat.samples"; + final String artifactId = "pet-store-bom"; + final String version = "2021.09"; + final String validName = "one-client-api-v1.yaml"; + final String username = "admin"; + final String password = "admin"; + final BigDecimal reportId = BigDecimal.valueOf(10); + final String reportGrade = "A"; + + SpecConfig specConfig = new SpecConfig(); + specConfig.setInputSpec(getFile("/bundler/folder/" + validName)); + + RadioMojo mojo = new RadioMojo(); + mojo.setGroupId(groupId); + mojo.setArtifactId(artifactId); + mojo.setVersion(version); + mojo.setPortalKey(portalKey); + mojo.setSourceKey(sourceKey); + mojo.setUsername(username); + mojo.setPassword(password); + mojo.setSpecs(new SpecConfig[]{specConfig}); + mojo.setBoatBayUrl(String.format("http://localhost:%s", mockBackEnd.getPort())); + + final Dispatcher dispatcher = new Dispatcher() { + @SneakyThrows + @Override + public MockResponse dispatch(RecordedRequest request) { + switch (request.getPath()) { + case "/api/boat/portals/" + portalKey + "/boat-maven-plugin/" + sourceKey + "/upload": + + if(request.getHeader("Authorization")!=null && request.getHeader("Authorization").length()>0){ + List result = getSampleBoatLintReports(specKey, reportId, reportGrade); + return new MockResponse().setResponseCode(200).setBody(objectMapper.writeValueAsString(result)); + } + return new MockResponse().setResponseCode(401); + } + return new MockResponse().setResponseCode(404); + } + }; + + mockBackEnd.setDispatcher(dispatcher); + + mojo.execute(); + + File output = new File(mojo.getRadioOutput(), "radioOutput.json"); + + assertTrue(output.exists()); + + } + private String getFile(String glob) { return (new File("src/test/resources").getAbsolutePath() + glob); } + @NotNull + private List getSampleBoatLintReports(String expectedDefaultKey, BigDecimal reportId, String reportGrade) { + BoatLintReport boatLintReport = new BoatLintReport(); + boatLintReport.setId(reportId); + boatLintReport.setGrade(reportGrade); + boatLintReport.setSpec(BoatSpec.builder().key(expectedDefaultKey).changes(Changes.COMPATIBLE).build()); + List result = new ArrayList<>(); + result.add(boatLintReport); + return result; + } + } \ No newline at end of file From 8f30ff45ebf0330721da255a1e947c717782f3df Mon Sep 17 00:00:00 2001 From: dhananjay12 Date: Mon, 13 Sep 2021 02:03:48 +0200 Subject: [PATCH 06/11] sonar --- .../com/backbase/oss/boat/radio/RadioMojo.java | 4 +--- .../backbase/oss/boat/radio/RadioMojoTests.java | 16 ++++++++-------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java index 6aa2cb53b..e7e228717 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java @@ -158,9 +158,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { try { File outputFile = new File(getOutput(), "radioOutput.json"); objectMapper.writerWithDefaultPrettyPrinter().writeValue(outputFile, reports); - reports.forEach(report -> { - getLog().info(format("Changes to spec %s is %s", report.getSpec().getKey(), report.getSpec().getChanges())); - }); + reports.forEach(report -> getLog().info(format("Changes to spec %s is %s", report.getSpec().getKey(), report.getSpec().getChanges()))); getLog().info("UPLOAD TO BOAT-BAY SUCCESSFUL, check the full report: " + outputFile.getCanonicalPath()); } catch (IOException e) { throw new MojoFailureException("Failed to write output", e); diff --git a/boat-maven-plugin/src/test/java/com/backbase/oss/boat/radio/RadioMojoTests.java b/boat-maven-plugin/src/test/java/com/backbase/oss/boat/radio/RadioMojoTests.java index e495ca695..3d99ad7a7 100644 --- a/boat-maven-plugin/src/test/java/com/backbase/oss/boat/radio/RadioMojoTests.java +++ b/boat-maven-plugin/src/test/java/com/backbase/oss/boat/radio/RadioMojoTests.java @@ -19,8 +19,8 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; @Slf4j class RadioMojoTests { @@ -106,9 +106,9 @@ public MockResponse dispatch(RecordedRequest request) { List result = Arrays.asList(objectMapper.readValue(output, BoatLintReport[].class)); - assertTrue(result.size() == 1); - assertTrue(result.get(0).getId().equals(reportId)); - assertTrue(result.get(0).getGrade().equals(reportGrade)); + assertEquals(1, result.size()); + assertEquals(reportId, result.get(0).getId()); + assertEquals(reportGrade, result.get(0).getGrade()); } @@ -181,9 +181,9 @@ public MockResponse dispatch(RecordedRequest request) { List result = Arrays.asList(objectMapper.readValue(output, BoatLintReport[].class)); - assertTrue(result.size() == 1); - assertTrue(result.get(0).getId().equals(reportId)); - assertTrue(result.get(0).getGrade().equals(reportGrade)); + assertEquals(1, result.size()); + assertEquals(reportId, result.get(0).getId()); + assertEquals(reportGrade, result.get(0).getGrade()); } From afd0d3bf1cf42782d48f0efa6922b2c88b824a63 Mon Sep 17 00:00:00 2001 From: dhananjay12 Date: Mon, 13 Sep 2021 15:38:35 +0200 Subject: [PATCH 07/11] added build failure properties --- boat-maven-plugin/README.md | 2 +- .../src/main/java/com/backbase/oss/boat/radio/RadioMojo.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/boat-maven-plugin/README.md b/boat-maven-plugin/README.md index a573322e8..792b169f5 100644 --- a/boat-maven-plugin/README.md +++ b/boat-maven-plugin/README.md @@ -275,7 +275,7 @@ Available parameters: Fail the build for breaking changes in specs failOnLintViolation - User property: failOnBreakingChange + User property: failOnLintViolation Fail the build if the spec has lint violation (mustViolationsCount > 0) groupId (Default: ${project.groupId}) diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java index 265c90d63..8612e9e93 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java @@ -73,7 +73,7 @@ public class RadioMojo extends AbstractMojo { /** * Fail the build if the spec has lint violation (mustViolationsCount > 0) */ - @Parameter(property = "failOnBreakingChange") + @Parameter(property = "failOnLintViolation") private boolean failOnLintViolation; /** From e90029d039023d3407e4d6c5c19064a55dd9f69b Mon Sep 17 00:00:00 2001 From: dhananjay12 Date: Mon, 13 Sep 2021 15:41:28 +0200 Subject: [PATCH 08/11] added build failure properties --- boat-maven-plugin/README.md | 5 +++-- .../src/main/java/com/backbase/oss/boat/radio/RadioMojo.java | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/boat-maven-plugin/README.md b/boat-maven-plugin/README.md index 792b169f5..5cf4d6d59 100644 --- a/boat-maven-plugin/README.md +++ b/boat-maven-plugin/README.md @@ -270,14 +270,15 @@ Available parameters: User property: boatBayUrl Boat-Bay domain. eg. https://boatbay.mycompany.eu - failOnBreakingChange + failOnBreakingChange (Default: false) User property: failOnBreakingChange Fail the build for breaking changes in specs - failOnLintViolation + failOnLintViolation (Default: false) User property: failOnLintViolation Fail the build if the spec has lint violation (mustViolationsCount > 0) + groupId (Default: ${project.groupId}) User property: groupId Project GroupId in Boat-Bay. Defaults to ${project.groupId} diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java index 8612e9e93..5ae36bfd3 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java @@ -67,13 +67,13 @@ public class RadioMojo extends AbstractMojo { /** * Fail the build for breaking changes in specs */ - @Parameter(property = "failOnBreakingChange") + @Parameter(property = "failOnBreakingChange", defaultValue="false") private boolean failOnBreakingChange; /** * Fail the build if the spec has lint violation (mustViolationsCount > 0) */ - @Parameter(property = "failOnLintViolation") + @Parameter(property = "failOnLintViolation", defaultValue="false") private boolean failOnLintViolation; /** From db0b13dc61918c5de60847723e372d1747a7b715 Mon Sep 17 00:00:00 2001 From: dhananjay12 Date: Mon, 13 Sep 2021 17:14:07 +0200 Subject: [PATCH 09/11] Severity check --- boat-maven-plugin/README.md | 2 +- .../com/backbase/oss/boat/radio/RadioMojo.java | 11 ++++------- .../backbase/oss/boat/radio/RadioMojoTests.java | 16 ++++++++-------- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/boat-maven-plugin/README.md b/boat-maven-plugin/README.md index 5cf4d6d59..9842102fe 100644 --- a/boat-maven-plugin/README.md +++ b/boat-maven-plugin/README.md @@ -276,7 +276,7 @@ Available parameters: failOnLintViolation (Default: false) User property: failOnLintViolation - Fail the build if the spec has lint violation (mustViolationsCount > 0) + Fail the build if the spec has lint violation (Violation with Severity.MUST) groupId (Default: ${project.groupId}) diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java index 5ae36bfd3..1fb56f7fd 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java @@ -3,10 +3,7 @@ import com.backbase.oss.boat.Utils; import com.backbase.oss.boat.bay.client.ApiClient; import com.backbase.oss.boat.bay.client.api.BoatMavenPluginApi; -import com.backbase.oss.boat.bay.client.model.BoatLintReport; -import com.backbase.oss.boat.bay.client.model.Changes; -import com.backbase.oss.boat.bay.client.model.UploadRequestBody; -import com.backbase.oss.boat.bay.client.model.UploadSpec; +import com.backbase.oss.boat.bay.client.model.*; import com.backbase.oss.boat.loader.OpenAPILoader; import com.backbase.oss.boat.loader.OpenAPILoaderException; import com.fasterxml.jackson.databind.ObjectMapper; @@ -71,7 +68,7 @@ public class RadioMojo extends AbstractMojo { private boolean failOnBreakingChange; /** - * Fail the build if the spec has lint violation (mustViolationsCount > 0) + * Fail the build if the spec has lint violation (Violation with Severity.MUST) */ @Parameter(property = "failOnLintViolation", defaultValue="false") private boolean failOnLintViolation; @@ -174,7 +171,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { reports.forEach(report -> { getLog().info(format("Spec %s summary :", report.getSpec().getKey())); getLog().info(format("Changes are %s ", report.getSpec().getChanges())); - getLog().info(report.getSpec().getStatistics().toString()); + getLog().info("Number of Violations:"+report.getViolations().size()); }); // Log link to reports getLog().info("UPLOAD TO BOAT-BAY SUCCESSFUL, check the full report: " + outputFile.getCanonicalPath()); @@ -184,7 +181,7 @@ public void execute() throws MojoExecutionException, MojoFailureException { throw new MojoFailureException("Specs have Breaking Changes. Check full report."); } boolean doesSpecsHaveMustViolations = reports.stream() - .anyMatch(report -> report.getSpec().getStatistics().getMustViolationsCount() > 0); + .anyMatch(report -> report.getViolations().stream().anyMatch(violation -> violation.getSeverity().equals(Severity.MUST))); if(doesSpecsHaveMustViolations && failOnLintViolation){ throw new MojoFailureException("Specs have Must Violations. Check full report."); } diff --git a/boat-maven-plugin/src/test/java/com/backbase/oss/boat/radio/RadioMojoTests.java b/boat-maven-plugin/src/test/java/com/backbase/oss/boat/radio/RadioMojoTests.java index 2094bbf34..8ccffade0 100644 --- a/boat-maven-plugin/src/test/java/com/backbase/oss/boat/radio/RadioMojoTests.java +++ b/boat-maven-plugin/src/test/java/com/backbase/oss/boat/radio/RadioMojoTests.java @@ -87,7 +87,7 @@ public MockResponse dispatch(RecordedRequest request) { uploadSpec.getOpenApi().length() > 0 ) { log.info(uploadSpec.getOpenApi()); - List result = getSampleBoatLintReports(specKey, reportId, reportGrade,Changes.COMPATIBLE,0); + List result = getSampleBoatLintReports(specKey, reportId, reportGrade,Changes.COMPATIBLE,Severity.HINT); return new MockResponse().setResponseCode(200).setBody(objectMapper.writeValueAsString(result)); } else { return new MockResponse().setResponseCode(400); @@ -162,7 +162,7 @@ public MockResponse dispatch(RecordedRequest request) { uploadSpec.getOpenApi().length() > 0 ) { log.info(uploadSpec.getOpenApi()); - List result = getSampleBoatLintReports(expectedDefaultKey, reportId, reportGrade,Changes.COMPATIBLE,0); + List result = getSampleBoatLintReports(expectedDefaultKey, reportId, reportGrade,Changes.COMPATIBLE,Severity.HINT); return new MockResponse().setResponseCode(200).setBody(objectMapper.writeValueAsString(result)); } else { return new MockResponse().setResponseCode(400); @@ -392,7 +392,7 @@ public MockResponse dispatch(RecordedRequest request) { case "/api/boat/portals/" + portalKey + "/boat-maven-plugin/" + sourceKey + "/upload": if(request.getHeader("Authorization")!=null && request.getHeader("Authorization").length()>0){ - List result = getSampleBoatLintReports(specKey, reportId, reportGrade,Changes.COMPATIBLE,0); + List result = getSampleBoatLintReports(specKey, reportId, reportGrade,Changes.COMPATIBLE,Severity.HINT); return new MockResponse().setResponseCode(200).setBody(objectMapper.writeValueAsString(result)); } return new MockResponse().setResponseCode(401); @@ -443,7 +443,7 @@ void test_build_fail_on_breaking_changes() { public MockResponse dispatch(RecordedRequest request) { switch (request.getPath()) { case "/api/boat/portals/" + portalKey + "/boat-maven-plugin/" + sourceKey + "/upload": - List result = getSampleBoatLintReports(specKey, reportId, reportGrade,Changes.BREAKING,0); + List result = getSampleBoatLintReports(specKey, reportId, reportGrade,Changes.BREAKING,Severity.HINT); return new MockResponse().setResponseCode(200).setBody(objectMapper.writeValueAsString(result)); } return new MockResponse().setResponseCode(404); @@ -497,7 +497,7 @@ void test_build_fail_on_must_violation() { public MockResponse dispatch(RecordedRequest request) { switch (request.getPath()) { case "/api/boat/portals/" + portalKey + "/boat-maven-plugin/" + sourceKey + "/upload": - List result = getSampleBoatLintReports(specKey, reportId, reportGrade,Changes.BREAKING,2); + List result = getSampleBoatLintReports(specKey, reportId, reportGrade,Changes.COMPATIBLE,Severity.MUST); return new MockResponse().setResponseCode(200).setBody(objectMapper.writeValueAsString(result)); } return new MockResponse().setResponseCode(404); @@ -526,12 +526,12 @@ private String getFile(String glob) { @NotNull private List getSampleBoatLintReports(String expectedDefaultKey, BigDecimal reportId, String reportGrade, - Changes typeOfChange, long numberOfMustViolation) { + Changes typeOfChange, Severity sampleSeverityInResponse) { BoatLintReport boatLintReport = new BoatLintReport(); boatLintReport.setId(reportId); boatLintReport.setGrade(reportGrade); - boatLintReport.setSpec(BoatSpec.builder().key(expectedDefaultKey).changes(typeOfChange) - .statistics(BoatStatistics.builder().mustViolationsCount(numberOfMustViolation).build()).build()); + boatLintReport.violations(List.of(BoatViolation.builder().severity(sampleSeverityInResponse).build())); + boatLintReport.setSpec(BoatSpec.builder().key(expectedDefaultKey).changes(typeOfChange).build()); List result = new ArrayList<>(); result.add(boatLintReport); return result; From dba408397578312f11ce0d641b4a15b9cb4ec04f Mon Sep 17 00:00:00 2001 From: dhananjay12 Date: Mon, 13 Sep 2021 17:18:05 +0200 Subject: [PATCH 10/11] Severity check --- .../com/backbase/oss/boat/radio/RadioMojo.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java index 1fb56f7fd..81fd3e234 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java @@ -175,14 +175,19 @@ public void execute() throws MojoExecutionException, MojoFailureException { }); // Log link to reports getLog().info("UPLOAD TO BOAT-BAY SUCCESSFUL, check the full report: " + outputFile.getCanonicalPath()); - boolean doesSpecsHaveBreakingChanges = reports.stream() - .anyMatch(report -> report.getSpec().getChanges().equals(Changes.BREAKING)); - if(doesSpecsHaveBreakingChanges && failOnBreakingChange){ + + if(failOnBreakingChange){ + boolean doesSpecsHaveBreakingChanges = reports.stream() + .anyMatch(report -> report.getSpec().getChanges().equals(Changes.BREAKING)); + if(doesSpecsHaveBreakingChanges) throw new MojoFailureException("Specs have Breaking Changes. Check full report."); } - boolean doesSpecsHaveMustViolations = reports.stream() - .anyMatch(report -> report.getViolations().stream().anyMatch(violation -> violation.getSeverity().equals(Severity.MUST))); - if(doesSpecsHaveMustViolations && failOnLintViolation){ + + if(failOnLintViolation){ + boolean doesSpecsHaveMustViolations = reports.stream() + .anyMatch(report -> report.getViolations().stream() + .anyMatch(violation -> violation.getSeverity().equals(Severity.MUST))); + if(doesSpecsHaveMustViolations) throw new MojoFailureException("Specs have Must Violations. Check full report."); } } catch (IOException e) { From b443f38d6274b66a7bd49eefd236f840d977737f Mon Sep 17 00:00:00 2001 From: dhananjay12 Date: Tue, 14 Sep 2021 09:44:38 +0200 Subject: [PATCH 11/11] boat bay server check --- .../backbase/oss/boat/radio/RadioMojo.java | 85 ++++++++++--------- .../oss/boat/radio/RadioMojoTests.java | 56 ++++++++++++ 2 files changed, 103 insertions(+), 38 deletions(-) diff --git a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java index 81fd3e234..3ec98cea8 100644 --- a/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java +++ b/boat-maven-plugin/src/main/java/com/backbase/oss/boat/radio/RadioMojo.java @@ -73,6 +73,12 @@ public class RadioMojo extends AbstractMojo { @Parameter(property = "failOnLintViolation", defaultValue="false") private boolean failOnLintViolation; + /** + * Fail the build if boatbay server returns an error + */ + @Parameter(property = "failOnBoatBayErrorResponse", defaultValue="true") + private boolean failOnBoatBayErrorResponse =true; + /** * Project portal Identifier in Boat-Bay. */ @@ -156,42 +162,49 @@ public void execute() throws MojoExecutionException, MojoFailureException { BoatMavenPluginApi api = apiClient.buildClient(BoatMavenPluginApi.class); - UploadRequestBody uploadRequestBody = new UploadRequestBody(); - uploadRequestBody.setGroupId(groupId); - uploadRequestBody.setArtifactId(artifactId); - uploadRequestBody.setVersion(version); - uploadRequestBody.setSpecs(allSpecs); - - List reports = api.uploadSpec(portalKey, sourceKey, uploadRequestBody); + UploadRequestBody uploadRequestBody = UploadRequestBody.builder() + .groupId(groupId).artifactId(artifactId).version(version).specs(allSpecs).build(); + List reports =null; try { - File outputFile = new File(getOutput(), "radioOutput.json"); - objectMapper.writerWithDefaultPrettyPrinter().writeValue(outputFile, reports); - // Log summary of report - reports.forEach(report -> { - getLog().info(format("Spec %s summary :", report.getSpec().getKey())); - getLog().info(format("Changes are %s ", report.getSpec().getChanges())); - getLog().info("Number of Violations:"+report.getViolations().size()); - }); - // Log link to reports - getLog().info("UPLOAD TO BOAT-BAY SUCCESSFUL, check the full report: " + outputFile.getCanonicalPath()); - - if(failOnBreakingChange){ - boolean doesSpecsHaveBreakingChanges = reports.stream() - .anyMatch(report -> report.getSpec().getChanges().equals(Changes.BREAKING)); - if(doesSpecsHaveBreakingChanges) - throw new MojoFailureException("Specs have Breaking Changes. Check full report."); - } + reports = api.uploadSpec(portalKey, sourceKey, uploadRequestBody); + }catch (Exception e){ + getLog().error("BoatBay error :: " + e.getMessage()); + if(failOnBoatBayErrorResponse) + throw new MojoFailureException("BoatBay error", e); + } - if(failOnLintViolation){ - boolean doesSpecsHaveMustViolations = reports.stream() - .anyMatch(report -> report.getViolations().stream() - .anyMatch(violation -> violation.getSeverity().equals(Severity.MUST))); - if(doesSpecsHaveMustViolations) - throw new MojoFailureException("Specs have Must Violations. Check full report."); + // Process Result + if(reports!=null) { + try { + File outputFile = new File(getOutput(), "radioOutput.json"); + objectMapper.writerWithDefaultPrettyPrinter().writeValue(outputFile, reports); + // Log summary of report + reports.forEach(report -> { + getLog().info(format("Spec %s summary :", report.getSpec().getKey())); + getLog().info(format("Changes are %s ", report.getSpec().getChanges())); + getLog().info("Number of Violations:" + report.getViolations().size()); + }); + // Log link to reports + getLog().info("UPLOAD TO BOAT-BAY SUCCESSFUL, check the full report: " + outputFile.getCanonicalPath()); + + if (failOnBreakingChange) { + boolean doesSpecsHaveBreakingChanges = reports.stream() + .anyMatch(report -> report.getSpec().getChanges().equals(Changes.BREAKING)); + if (doesSpecsHaveBreakingChanges) + throw new MojoFailureException("Specs have Breaking Changes. Check full report."); + } + + if (failOnLintViolation) { + boolean doesSpecsHaveMustViolations = reports.stream() + .anyMatch(report -> report.getViolations().stream() + .anyMatch(violation -> violation.getSeverity().equals(Severity.MUST))); + if (doesSpecsHaveMustViolations) + throw new MojoFailureException("Specs have Must Violations. Check full report."); + } + } catch (IOException e) { + throw new MojoFailureException("Failed to write output", e); } - } catch (IOException e) { - throw new MojoFailureException("Failed to write output", e); } } @@ -258,12 +271,8 @@ private UploadSpec mapToUploadSpec(SpecConfig spec) throws MojoExecutionExceptio } //Validation Complete. Prepare UploadSpec. - UploadSpec uploadSpec = new UploadSpec(); - uploadSpec.setFileName(inputSpecFile.getName()); - uploadSpec.setKey(key); - uploadSpec.setName(name); - uploadSpec.setOpenApi(contents); - + UploadSpec uploadSpec = UploadSpec.builder() + .fileName(inputSpecFile.getName()).key(key).name(name).openApi(contents).build(); return uploadSpec; diff --git a/boat-maven-plugin/src/test/java/com/backbase/oss/boat/radio/RadioMojoTests.java b/boat-maven-plugin/src/test/java/com/backbase/oss/boat/radio/RadioMojoTests.java index 8ccffade0..ba1f95291 100644 --- a/boat-maven-plugin/src/test/java/com/backbase/oss/boat/radio/RadioMojoTests.java +++ b/boat-maven-plugin/src/test/java/com/backbase/oss/boat/radio/RadioMojoTests.java @@ -519,6 +519,62 @@ public MockResponse dispatch(RecordedRequest request) { } + @SneakyThrows + @Test + void test_when_boat_bay_is_unavailable() { + + final String portalKey = "example"; + final String sourceKey = "pet-store-bom"; + final String groupId = "com.backbase.boat.samples"; + final String artifactId = "pet-store-bom"; + final String specKey = "spec-key"; + final String version = "2021.09"; + final BigDecimal reportId = BigDecimal.valueOf(10); + final String reportGrade = "A"; + final String validName = "one-client-api-v1.yaml"; + + SpecConfig specConfig = new SpecConfig(); + specConfig.setInputSpec(getFile("/bundler/folder/" + validName)); + + RadioMojo mojo = new RadioMojo(); + mojo.setGroupId(groupId); + mojo.setArtifactId(artifactId); + mojo.setVersion(version); + mojo.setPortalKey(portalKey); + mojo.setSourceKey(sourceKey); + mojo.setSpecs(new SpecConfig[]{specConfig}); + //Set invalid domain + mojo.setBoatBayUrl(String.format("http://invalid-domain:%s", mockBackEnd.getPort())); + + final Dispatcher dispatcher = new Dispatcher() { + @SneakyThrows + @Override + public MockResponse dispatch(RecordedRequest request) { + switch (request.getPath()) { + case "/api/boat/portals/" + portalKey + "/boat-maven-plugin/" + sourceKey + "/upload": + return new MockResponse().setResponseCode(200); + } + return new MockResponse().setResponseCode(404); + } + }; + + mockBackEnd.setDispatcher(dispatcher); + + + // Build will fail, when failOnBoatBayErrorResponse is true (Defualt) + Exception exception = assertThrows(MojoFailureException.class, () -> mojo.execute()); + assertTrue(exception.getMessage().startsWith("BoatBay error")); + + // Build will not fail if failOnBoatBayErrorResponse is false + mojo.setFailOnBoatBayErrorResponse(false); + //No Exception is thrown + assertDoesNotThrow(() -> mojo.execute()); + File output = new File(mojo.getRadioOutput(), "radioOutput.json"); + //But No output file present + assertTrue(!output.exists()); + + } + private String getFile(String glob) { return (new File("src/test/resources").getAbsolutePath() + glob);