diff options
14 files changed, 356 insertions, 135 deletions
diff --git a/certService/OpenAPI.yaml b/certService/OpenAPI.yaml index 631a1fbc..cee5a402 100644 --- a/certService/OpenAPI.yaml +++ b/certService/OpenAPI.yaml @@ -1,92 +1,158 @@ openapi: 3.0.1 info: title: CertService Documentation - description: certification service API documentation - version: v1 + description: Certification service API documentation + version: 1.0.0 servers: - - url: 'http://localhost:8080' + - url: http://localhost:8080 description: Generated server url tags: - name: Actuator description: Monitor and interact externalDocs: description: Spring Boot Actuator Web API Documentation - url: 'https://docs.spring.io/spring-boot/docs/current/actuator-api/html/' + url: https://docs.spring.io/spring-boot/docs/current/actuator-api/html/ paths: - '/v1/certificate/{caName}': + /v1/certificate/{caName}: get: tags: - - certification-service - operationId: sign certificate + - CertificationService + summary: sign certificate + description: Web endpoint for requesting certificate signing. Used by system + components to gain certificate signed by CA. + operationId: signCertificate parameters: - name: caName in: path + description: Name of certification authority that will sign CSR. required: true schema: type: string - name: CSR in: header + description: Certificate signing request in form of PEM object encoded in + Base64 (with header and footer). required: true schema: type: string - name: PK in: header + description: Private key in form of PEM object encoded in Base64 (with header + and footer). required: true schema: type: string responses: - '200': - description: csr is signed + "200": + description: certificate successfully signed + content: + application/json; charset=utf-8: + schema: + $ref: '#/components/schemas/CertificationModel' + "500": + description: something went wrong during connecting to cmp client + content: + application/json; charset=utf-8: + schema: + $ref: '#/components/schemas/ErrorResponseModel' + "404": + description: CA not found for given name + content: + application/json; charset=utf-8: + schema: + $ref: '#/components/schemas/ErrorResponseModel' + "400": + description: given CSR or/and PK is incorrect + content: + application/json; charset=utf-8: + schema: + $ref: '#/components/schemas/ErrorResponseModel' + /ready: + get: + tags: + - CertificationService + summary: check is container is ready + description: Web endpoint for checking if service is ready to be used. + operationId: checkReady + responses: + "200": + description: configuration is loaded and service is ready to use content: application/json; charset=utf-8: schema: type: string - example: { - "certificateChain": [ - "-----BEGIN CERTIFICATE-----\nMIIDjDCCAnSgAwIBAgICEAIwDQYJKoZIhvcNAQELBQAwgYQxCzAJBgNVBAYTAlVT\nMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMRkw\nFwYDVQQKDBBMaW51eC1Gb3VuZGF0aW9uMQ0wCwYDVQQLDARPTkFQMR4wHAYDVQQD\nDBVpbnRlcm1lZGlhdGUub25hcC5vcmcwHhcNMjAwMjEyMDk1MTI2WhcNMjIxMTA4\nMDk1MTI2WjB7MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG\nA1UEBwwNU2FuLUZyYW5jaXNjbzEZMBcGA1UECgwQTGludXgtRm91bmRhdGlvbjEN\nMAsGA1UECwwET05BUDEVMBMGA1UEAwwMdmlkLm9uYXAub3JnMIIBIjANBgkqhkiG\n9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw+GIRzJzUOh0gtc+wzFJEdTnn+q5F10L0Yhr\nG1xKdjPieHIFGsoiXwcuCU8arNSqlz7ocx62KQRkcA8y6edlOAsYtdOEJvqEI9vc\neyTB/HYsbzw3URPGch4AmibrQkKU9QvGwouHtHn4R2Ft2Y0tfEqv9hxj9v4njq4A\nEiDLAFLl5FmVyCZu/MtKngSgu1smcaFKTYySPMxytgJZexoa/ALZyyE0gRhsvwHm\nNLGCPt1bmE/PEGZybsCqliyTO0S56ncD55The7+D/UDS4kE1Wg0svlWon/YsE6QW\nB3oeJDX7Kr8ebDTIAErevIAD7Sm4ee5se2zxYrsYlj0MzHZtvwIDAQABoxAwDjAM\nBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCvQ1pTvjON6vSlcJRKSY4r\n8q7L4/9ZaVXWJAjzEYJtPIqsgGiPWz0vGfgklowU6tZxp9zRZFXfMil+mPQSe+yo\nULrZSQ/z48YHPueE/BNO/nT4aaVBEhPLR5aVwC7uQVX8H+m1V1UGT8lk9vdI9rej\nCI9l524sLCpdE4dFXiWK2XHEZ0Vfylk221u3IYEogVVA+UMX7BFPSsOnI2vtYK/i\nlwZtlri8LtTusNe4oiTkYyq+RSyDhtAswg8ANgvfHolhCHoLFj6w1IkG88UCmbwN\nd7BoGMy06y5MJxyXEZG0vR7eNeLey0TIh+rAszAFPsIQvrOHW+HuA+WLQAj1mhnm\n-----END CERTIFICATE-----", - "-----BEGIN CERTIFICATE-----\nMIIDqTCCApGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwgZcxCzAJBgNVBAYTAlVT\nMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMRkw\nFwYDVQQKDBBMaW51eC1Gb3VuZGF0aW9uMQ0wCwYDVQQLDARPTkFQMREwDwYDVQQD\nDAhvbmFwLm9yZzEeMBwGCSqGSIb3DQEJARYPdGVzdGVyQG9uYXAub3JnMB4XDTIw\nMDIxMjA5NDAxMloXDTIyMTEwODA5NDAxMlowgYQxCzAJBgNVBAYTAlVTMRMwEQYD\nVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4tRnJhbmNpc2NvMRkwFwYDVQQK\nDBBMaW51eC1Gb3VuZGF0aW9uMQ0wCwYDVQQLDARPTkFQMR4wHAYDVQQDDBVpbnRl\ncm1lZGlhdGUub25hcC5vcmcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB\nAQC1oOYMZ6G+2DGDAizYnzdCNiogivlht1s4oqgem7fM1XFPxD2p31ATIibOdqr/\ngv1qemO9Q4r1xn6w1Ufq7T1K7PjnMzdSeTqZefurE2JM/HHx2QvW4TjMlz2ILgaD\nL1LN60kmMQSOi5VxKJpsrCQxbOsxhvefd212gny5AZMcjJe23kUd9OxUrtvpdLEv\nwI3vFEvT7oRUnEUg/XNz7qeg33vf1C39yMR+6O4s6oevgsEebVKjb+yOoS6zzGtz\n72wZjm07C54ZlO+4Uy+QAlMjRiU3mgWkKbkOy+4CvwehjhpTikdBs2DX39ZLGHhn\nL/0a2NYtGulp9XEqmTvRoI+PAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZI\nhvcNAQELBQADggEBADcitdJ6YswiV8jAD9GK0gf3+zqcGegt4kt+79JXlXYbb1sY\nq3o6prcB7nSUoClgF2xUPCslFGpM0Er9FCSFElQM/ru0l/KVmJS6kSpwEHvsYIH3\nq5anta+Pyk8JSQWAAw+qrind0uBQMnhR8Tn13tgV+Kjvg/xlH/nZIEdN5YtLB1cA\nbeVsZRyRfVL9DeZU8s/MZ5wC3kgcEp5A4m5lg7HyBxBdqhzFcDr6xiy6OGqW8Yep\nxrwfc8Fw8a/lOv4U+tBeGNKPQDYaL9hh+oM+qMkNXsHXDqdJsuEGJtU4i3Wcwzoc\nXGN5NWV//4bP+NFmwgcn7AYCdRvz04A8GU/0Cwg=\n-----END CERTIFICATE-----" - ], - "trustedCertificates": [ - "-----BEGIN CERTIFICATE-----\nMIIDtzCCAp8CFAwqQddh4/iyGfP8UZ3dpXlxfAN8MA0GCSqGSIb3DQEBCwUAMIGX\nMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2Fu\nLUZyYW5jaXNjbzEZMBcGA1UECgwQTGludXgtRm91bmRhdGlvbjENMAsGA1UECwwE\nT05BUDERMA8GA1UEAwwIb25hcC5vcmcxHjAcBgkqhkiG9w0BCQEWD3Rlc3RlckBv\nbmFwLm9yZzAeFw0yMDAyMTIwOTM0MjdaFw0yMTAyMTEwOTM0MjdaMIGXMQswCQYD\nVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuLUZyYW5j\naXNjbzEZMBcGA1UECgwQTGludXgtRm91bmRhdGlvbjENMAsGA1UECwwET05BUDER\nMA8GA1UEAwwIb25hcC5vcmcxHjAcBgkqhkiG9w0BCQEWD3Rlc3RlckBvbmFwLm9y\nZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMCFrnO7/eT6V+7XkPPd\neiL/6xXreuegvit/1/jTVjG+3AOVcmTn2WXwXXRcQLvkWQfJVPoltsY8E3FqFRti\n797XjY6cdQJFVDyzNU0+Fb4vJL9FK5wSvnS6EFjBEn3JvXRlENorDCs/mfjkjJoa\nDl74gXQEJYcg4nsTeNIj7cm3Q7VK3mZt1t7LSJJ+czxv69UJDuNJpmQ/2WOKyLZA\ngTtBJ+Hyol45/OLsrqwq1dAn9ZRWIFPvRt/XQYH9bI/6MtqSreRVUrdYCiTe/XpP\nB/OM6NEi2+p5QLi3Yi70CEbqP3HqUVbkzF+r7bwIb6M5/HxfqzLmGwLvD+6rYnUn\nBm8CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAhXoO65DXth2X/zFRNsCNpLwmDy7r\nPxT9ZAIZAzSxx3/aCYiuTrKP1JnqjkO+F2IbikrI4n6sKO49SKnRf9SWTFhd+5dX\nvxq5y7MaqxHAY9J7+Qzq33+COVFQnaF7ddel2NbyUVb2b9ZINNsaZkkPXui6DtQ7\n/Fb/1tmAGWd3hMp75G2thBSzs816JMKKa9WD+4VGATEs6OSll4sv2fOZEn+0mAD3\n9q9c+WtLGIudOwcHwzPb2njtNntQSCK/tVOqbY+vzhMY3JW+p9oSrLDSdGC+pAKK\nm/wB+2VPIYcsPMtIhHC4tgoSaiCqjXYptaOh4b8ye8CPBUCpX/AYYkN0Ow==\n-----END CERTIFICATE-----", - "-----BEGIN CERTIFICATE-----\nMIIDvzCCAqcCFF5DejiyfoNfPiiMmBXulniBewBGMA0GCSqGSIb3DQEBCwUAMIGb\nMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2Fu\nLUZyYW5jaXNjbzEZMBcGA1UECgwQTGludXgtRm91bmRhdGlvbjENMAsGA1UECwwE\nT05BUDEVMBMGA1UEAwwMbmV3Lm9uYXAub3JnMR4wHAYJKoZIhvcNAQkBFg90ZXN0\nZXJAb25hcC5vcmcwHhcNMjAwMjEyMDk1OTM3WhcNMjEwMjExMDk1OTM3WjCBmzEL\nMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbi1G\ncmFuY2lzY28xGTAXBgNVBAoMEExpbnV4LUZvdW5kYXRpb24xDTALBgNVBAsMBE9O\nQVAxFTATBgNVBAMMDG5ldy5vbmFwLm9yZzEeMBwGCSqGSIb3DQEJARYPdGVzdGVy\nQG9uYXAub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtF4FXeDV\nng/inC/bTACmZnLC9IiC7PyG/vVbMxxN1bvQLRAwC/Hbl3i9zD68Vs/jPPr/SDr9\n2rgItdDdUY1V30Y3PT06F11XdEaRb+t++1NX0rDf1AqPaBZgnBmB86s1wbqHdJTr\nwEImDZ5xMPfP3fiWy/9Yw/U7iRMIi1/oI0lWuHJV0bn908shuJ6dvInpRCoDnoTX\nYP/FiDSZCFVewQcq4TigB7kRqZrDcPZWbSlqHklDMXRwbCxAiFSziuX6TBwru9Rn\nHhIeXVSgMU1ZSSopVbJGtQ4zSsU1nvTK5Bhc2UHGcAOZy1xTN5D9EEbTqh7l+Wtx\ny8ojkEXvFG8lVwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAE+bUphwHit78LK8sb\nOMjt4DiEu32KeSJOpYgPLeBeAIynaNsa7sQrpuxerGNTmQWIcw6olXI0J+OOwkik\nII7elrYtd5G1uALxXWdamNsaY0Du34moVL1YjexJ7qQ4oBUxg2tuY8NAQGDK+23I\nnCA+ZwzdTJo73TYS6sx64d/YLWkX4nHGUoMlF+xUH34csDyhpuTSzQhC2quB5N8z\ntSFdpe4z2jqx07qo2EBFxi03EQ8Q0ex6l421QM2gbs7cZQ66K0DkpPcF2+iHZnyx\nxq1lnlsWHklElF2bhyXTn3fPp5wtan00P8IolKx7CAWb92QjkW6M0RvTW/xuwIzh\n0rTO\n-----END CERTIFICATE-----" - ] - } - '400': - description: incorrect/missing CSR and/or private key + "503": + description: configuration loading failed and service is unavailable content: application/json; charset=utf-8: schema: type: string - example: { - "errorMessage": "Wrong key (PK) format" - } - '500': - description: exception occurred on server side + /reload: + get: + tags: + - CertificationService + summary: reload service configuration from file + description: Web endpoint for performing configuration reload. Used to reload + configuration file from file. + operationId: reloadConfiguration + responses: + "200": + description: configuration has been successfully reloaded content: application/json; charset=utf-8: schema: type: string + "500": + description: something went wrong during configuration loading + content: + application/json; charset=utf-8: + schema: + $ref: '#/components/schemas/ErrorResponseModel' /actuator/health: get: tags: - Actuator - operationId: health check summary: Actuator web endpoint 'health' + operationId: handle_0 responses: - '200': - description: service is healthy + "200": + description: default response content: {} - /actuator/refresh: - post: + /actuator/health/**: + get: tags: - Actuator - operationId: refresh configuration - summary: Actuator web endpoint 'refresh' + summary: Actuator web endpoint 'health-path' + operationId: handle_1 responses: - '200': - description: configuration is successfully reloaded + "200": + description: default response content: {} - '500': - description: fail to reload configuration + /actuator: + get: + tags: + - Actuator + summary: Actuator root web endpoint + operationId: links_2 + responses: + "200": + description: default response content: {} -components: {} +components: + schemas: + ErrorResponseModel: + type: object + properties: + errorMessage: + type: string + CertificationModel: + type: object + properties: + certificateChain: + type: array + items: + type: string + trustedCertificates: + type: array + items: + type: string diff --git a/certService/src/main/java/org/onap/aaf/certservice/api/CertificationController.java b/certService/src/main/java/org/onap/aaf/certservice/api/CertificationController.java index abb6811b..fe941f58 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/api/CertificationController.java +++ b/certService/src/main/java/org/onap/aaf/certservice/api/CertificationController.java @@ -20,16 +20,18 @@ package org.onap.aaf.certservice.api; -import com.google.gson.Gson; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import org.onap.aaf.certservice.certification.CertificationModelFactory; -import org.onap.aaf.certservice.certification.CsrModelFactory; -import org.onap.aaf.certservice.certification.CsrModelFactory.StringBase64; -import org.onap.aaf.certservice.certification.configuration.Cmpv2ServerProvider; -import org.onap.aaf.certservice.certification.configuration.model.Cmpv2Server; import org.onap.aaf.certservice.certification.exception.Cmpv2ClientAdapterException; import org.onap.aaf.certservice.certification.exception.DecryptionException; +import org.onap.aaf.certservice.certification.exception.ErrorResponseModel; import org.onap.aaf.certservice.certification.model.CertificationModel; -import org.onap.aaf.certservice.certification.model.CsrModel; import org.onap.aaf.certservice.cmpv2client.exceptions.CmpClientException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,6 +45,7 @@ import org.springframework.web.bind.annotation.RestController; @RestController +@Tag(name = "CertificationService") public class CertificationController { private static final Logger LOGGER = LoggerFactory.getLogger(CertificationController.class); @@ -64,17 +67,32 @@ public class CertificationController { * @return JSON containing trusted certificates and certificate chain */ @GetMapping(value = "v1/certificate/{caName}", produces = "application/json; charset=utf-8") - public ResponseEntity<String> signCertificate( + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "certificate successfully signed"), + @ApiResponse(responseCode = "400", description = "given CSR or/and PK is incorrect", + content = @Content(schema = @Schema(implementation = ErrorResponseModel.class))), + @ApiResponse(responseCode = "404", description = "CA not found for given name", + content = @Content(schema = @Schema(implementation = ErrorResponseModel.class))), + @ApiResponse(responseCode = "500", description = "something went wrong during connecting to cmp client", + content = @Content(schema = @Schema(implementation = ErrorResponseModel.class))) + }) + @Operation( + summary = "sign certificate", + description = "Web endpoint for requesting certificate signing. Used by system components to gain certificate signed by CA.", + tags = { "CertificationService" }) + public ResponseEntity<CertificationModel> signCertificate( + @Parameter(description="Name of certification authority that will sign CSR.") @PathVariable String caName, + @Parameter(description="Certificate signing request in form of PEM object encoded in Base64 (with header and footer).") @RequestHeader("CSR") String encodedCsr, + @Parameter(description="Private key in form of PEM object encoded in Base64 (with header and footer).") @RequestHeader("PK") String encodedPrivateKey ) throws DecryptionException, CmpClientException, Cmpv2ClientAdapterException { caName = caName.replaceAll("[\n|\r|\t]", "_"); LOGGER.info("Received certificate signing request for CA named: {}", caName); CertificationModel certificationModel = certificationModelFactory .createCertificationModel(encodedCsr, encodedPrivateKey, caName); - return new ResponseEntity<>(new Gson().toJson(certificationModel), HttpStatus.OK); - + return new ResponseEntity<>(certificationModel, HttpStatus.OK); } } diff --git a/certService/src/main/java/org/onap/aaf/certservice/api/ReadinessController.java b/certService/src/main/java/org/onap/aaf/certservice/api/ReadinessController.java index e33bf512..288957ca 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/api/ReadinessController.java +++ b/certService/src/main/java/org/onap/aaf/certservice/api/ReadinessController.java @@ -20,6 +20,10 @@ package org.onap.aaf.certservice.api; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import org.onap.aaf.certservice.certification.configuration.CmpServersConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; @@ -28,6 +32,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController +@Tag(name = "CertificationService") public class ReadinessController { private final CmpServersConfig cmpServersConfig; @@ -37,7 +42,15 @@ public class ReadinessController { this.cmpServersConfig = cmpServersConfig; } - @GetMapping("/ready") + @GetMapping(value = "/ready", produces = "application/json; charset=utf-8") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "configuration is loaded and service is ready to use"), + @ApiResponse(responseCode = "503", description = "configuration loading failed and service is unavailable") + }) + @Operation( + summary = "check is container is ready", + description = "Web endpoint for checking if service is ready to be used.", + tags = { "CertificationService" }) public ResponseEntity<String> checkReady() { if (cmpServersConfig.isReady()) { return new ResponseEntity<>(HttpStatus.OK); diff --git a/certService/src/main/java/org/onap/aaf/certservice/api/ReloadConfigController.java b/certService/src/main/java/org/onap/aaf/certservice/api/ReloadConfigController.java index 5390a00c..b6673ce2 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/api/ReloadConfigController.java +++ b/certService/src/main/java/org/onap/aaf/certservice/api/ReloadConfigController.java @@ -20,18 +20,25 @@ package org.onap.aaf.certservice.api; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.tags.Tag; import org.onap.aaf.certservice.certification.configuration.CmpServersConfig; import org.onap.aaf.certservice.certification.configuration.CmpServersConfigLoadingException; +import org.onap.aaf.certservice.certification.exception.ErrorResponseModel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController +@Tag(name = "CertificationService") public class ReloadConfigController { private static final Logger LOGGER = LoggerFactory.getLogger(ReloadConfigController.class); @@ -43,16 +50,19 @@ public class ReloadConfigController { this.cmpServersConfig = cmpServersConfig; } - @GetMapping("/reload") + @GetMapping(value = "/reload", produces = "application/json; charset=utf-8") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "configuration has been successfully reloaded"), + @ApiResponse(responseCode = "500", description = "something went wrong during configuration loading", + content = @Content(schema = @Schema(implementation = ErrorResponseModel.class))) + }) + @Operation( + summary = "reload service configuration from file", + description = "Web endpoint for performing configuration reload. Used to reload configuration file from file.", + tags = { "CertificationService" }) public ResponseEntity<String> reloadConfiguration() throws CmpServersConfigLoadingException { cmpServersConfig.reloadConfiguration(); return new ResponseEntity<>(HttpStatus.OK); } - @ExceptionHandler(value = CmpServersConfigLoadingException.class) - public ResponseEntity<String> handle(CmpServersConfigLoadingException exception) { - LOGGER.error(exception.getMessage(), exception.getCause()); - return new ResponseEntity<>(exception.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); - } - } diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/CertificationExceptionController.java b/certService/src/main/java/org/onap/aaf/certservice/api/advice/CertificationExceptionAdvice.java index d649f147..f75e93c9 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/CertificationExceptionController.java +++ b/certService/src/main/java/org/onap/aaf/certservice/api/advice/CertificationExceptionAdvice.java @@ -18,9 +18,9 @@ * ============LICENSE_END========================================================= */ -package org.onap.aaf.certservice.certification; +package org.onap.aaf.certservice.api.advice; -import com.google.gson.Gson; +import org.onap.aaf.certservice.api.CertificationController; import org.onap.aaf.certservice.certification.exception.Cmpv2ClientAdapterException; import org.onap.aaf.certservice.certification.exception.Cmpv2ServerNotFoundException; import org.onap.aaf.certservice.certification.exception.CsrDecryptionException; @@ -31,16 +31,16 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; -@ControllerAdvice -public class CertificationExceptionController { +@RestControllerAdvice(assignableTypes = CertificationController.class) +public class CertificationExceptionAdvice { - private static final Logger LOGGER = LoggerFactory.getLogger(CertificationExceptionController.class); + private static final Logger LOGGER = LoggerFactory.getLogger(CertificationExceptionAdvice.class); @ExceptionHandler(value = CsrDecryptionException.class) - public ResponseEntity<String> handle(CsrDecryptionException exception) { + public ResponseEntity<ErrorResponseModel> handle(CsrDecryptionException exception) { LOGGER.error("Exception occurred during decoding certificate sign request:", exception); return getErrorResponseEntity( "Wrong certificate signing request (CSR) format", @@ -49,7 +49,7 @@ public class CertificationExceptionController { } @ExceptionHandler(value = KeyDecryptionException.class) - public ResponseEntity<String> handle(KeyDecryptionException exception) { + public ResponseEntity<ErrorResponseModel> handle(KeyDecryptionException exception) { LOGGER.error("Exception occurred during decoding key:", exception); return getErrorResponseEntity( "Wrong key (PK) format", @@ -58,7 +58,7 @@ public class CertificationExceptionController { } @ExceptionHandler(value = Cmpv2ServerNotFoundException.class) - public ResponseEntity<String> handle(Cmpv2ServerNotFoundException exception) { + public ResponseEntity<ErrorResponseModel> handle(Cmpv2ServerNotFoundException exception) { LOGGER.error("Exception occurred selecting CMPv2 server:", exception); return getErrorResponseEntity( "Certification authority not found for given CAName", @@ -66,8 +66,13 @@ public class CertificationExceptionController { ); } + @ExceptionHandler(value = RuntimeException.class) + public ResponseEntity<ErrorResponseModel> handle(RuntimeException exception) throws CmpClientException { + throw new CmpClientException("Runtime exception occurred calling cmp client business logic", exception); + } + @ExceptionHandler(value = CmpClientException.class) - public ResponseEntity<String> handle(CmpClientException exception) { + public ResponseEntity<ErrorResponseModel> handle(CmpClientException exception) { LOGGER.error("Exception occurred calling cmp client:", exception); return getErrorResponseEntity( "Exception occurred during call to cmp client", @@ -75,13 +80,8 @@ public class CertificationExceptionController { ); } - @ExceptionHandler(value = RuntimeException.class) - public ResponseEntity<String> handle(RuntimeException exception) throws CmpClientException { - throw new CmpClientException("Runtime exception occurred calling cmp client business logic", exception); - } - @ExceptionHandler(value = Cmpv2ClientAdapterException.class) - public ResponseEntity<String> handle(Cmpv2ClientAdapterException exception) { + public ResponseEntity<ErrorResponseModel> handle(Cmpv2ClientAdapterException exception) { LOGGER.error("Exception occurred parsing cmp client response:", exception); return getErrorResponseEntity( "Exception occurred parsing cmp client response", @@ -89,10 +89,10 @@ public class CertificationExceptionController { ); } - private ResponseEntity<String> getErrorResponseEntity(String errorMessage, HttpStatus status) { + private ResponseEntity<ErrorResponseModel> getErrorResponseEntity(String errorMessage, HttpStatus status) { ErrorResponseModel errorResponse = new ErrorResponseModel(errorMessage); return new ResponseEntity<>( - new Gson().toJson(errorResponse), + errorResponse, status ); } diff --git a/certService/src/main/java/org/onap/aaf/certservice/api/advice/ReloadConfigExceptionAdvice.java b/certService/src/main/java/org/onap/aaf/certservice/api/advice/ReloadConfigExceptionAdvice.java new file mode 100644 index 00000000..bf83ece2 --- /dev/null +++ b/certService/src/main/java/org/onap/aaf/certservice/api/advice/ReloadConfigExceptionAdvice.java @@ -0,0 +1,43 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.aaf.certservice.api.advice; + +import org.onap.aaf.certservice.api.ReloadConfigController; +import org.onap.aaf.certservice.certification.configuration.CmpServersConfigLoadingException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice(assignableTypes = ReloadConfigController.class) +public class ReloadConfigExceptionAdvice { + + private static final Logger LOGGER = LoggerFactory.getLogger(ReloadConfigExceptionAdvice.class); + + @ExceptionHandler(value = CmpServersConfigLoadingException.class) + public ResponseEntity<String> handle(CmpServersConfigLoadingException exception) { + LOGGER.error(exception.getMessage(), exception.getCause()); + return new ResponseEntity<>(exception.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); + } + +} diff --git a/certService/src/main/java/org/onap/aaf/certservice/api/configuration/OpenApiConfig.java b/certService/src/main/java/org/onap/aaf/certservice/api/configuration/OpenApiConfig.java new file mode 100644 index 00000000..18327048 --- /dev/null +++ b/certService/src/main/java/org/onap/aaf/certservice/api/configuration/OpenApiConfig.java @@ -0,0 +1,44 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.aaf.certservice.api.configuration; + +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Info; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class OpenApiConfig { + + @Bean + public OpenAPI customOpenAPI() { + return new OpenAPI() + .components(new Components()) + .info( + new Info() + .title("CertService Documentation") + .description("Certification service API documentation") + .version("1.0.0") + ); + } + +} diff --git a/certService/src/main/java/org/onap/aaf/certservice/certification/exception/Cmpv2ServerNotFoundException.java b/certService/src/main/java/org/onap/aaf/certservice/certification/exception/Cmpv2ServerNotFoundException.java index 95d4cd69..35acb0cd 100644 --- a/certService/src/main/java/org/onap/aaf/certservice/certification/exception/Cmpv2ServerNotFoundException.java +++ b/certService/src/main/java/org/onap/aaf/certservice/certification/exception/Cmpv2ServerNotFoundException.java @@ -20,9 +20,7 @@ package org.onap.aaf.certservice.certification.exception; -import org.webjars.NotFoundException; - -public class Cmpv2ServerNotFoundException extends NotFoundException { +public class Cmpv2ServerNotFoundException extends RuntimeException { public Cmpv2ServerNotFoundException(String message) { super(message); } diff --git a/certService/src/main/resources/application.properties b/certService/src/main/resources/application.properties index aac9b96f..9ccdd326 100644 --- a/certService/src/main/resources/application.properties +++ b/certService/src/main/resources/application.properties @@ -1,13 +1,11 @@ # Actuator configuration -springdoc.show-actuator=true - management.endpoints.enabled-by-default=true management.endpoint.configprops.enabled=true management.endpoints.web.exposure.include=health - # Swagger configuration +springdoc.show-actuator=true springdoc.swagger-ui.path=/docs # AAF CertService app specific configuration -app.config.path=/etc/onap/aaf/certservice
\ No newline at end of file +app.config.path=/etc/onap/aaf/certservice diff --git a/certService/src/test/java/org/onap/aaf/certservice/api/CertificationControllerTest.java b/certService/src/test/java/org/onap/aaf/certservice/api/CertificationControllerTest.java index 802b2ea0..8ebac689 100644 --- a/certService/src/test/java/org/onap/aaf/certservice/api/CertificationControllerTest.java +++ b/certService/src/test/java/org/onap/aaf/certservice/api/CertificationControllerTest.java @@ -25,7 +25,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.when; -import com.google.gson.Gson; import java.util.Arrays; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -75,14 +74,12 @@ class CertificationControllerTest { .thenReturn(testCertificationModel); // When - ResponseEntity<String> testResponse = + ResponseEntity<CertificationModel> responseCertificationModel = certificationController.signCertificate(TEST_CA_NAME, TEST_ENCODED_CSR, TEST_ENCODED_PK); - CertificationModel responseCertificationModel = new Gson().fromJson(testResponse.getBody(), CertificationModel.class); - // Then - assertEquals(HttpStatus.OK, testResponse.getStatusCode()); - assertThat(responseCertificationModel + assertEquals(HttpStatus.OK, responseCertificationModel.getStatusCode()); + assertThat(responseCertificationModel.getBody() ).isEqualToComparingFieldByField(testCertificationModel); } diff --git a/certService/src/test/java/org/onap/aaf/certservice/api/ReloadConfigControllerTest.java b/certService/src/test/java/org/onap/aaf/certservice/api/ReloadConfigControllerTest.java index 17db24b8..5e0e355c 100644 --- a/certService/src/test/java/org/onap/aaf/certservice/api/ReloadConfigControllerTest.java +++ b/certService/src/test/java/org/onap/aaf/certservice/api/ReloadConfigControllerTest.java @@ -21,7 +21,6 @@ package org.onap.aaf.certservice.api; import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.Mockito.doThrow; @@ -47,12 +46,12 @@ public class ReloadConfigControllerTest { public CmpServersConfig cmpServersConfig; @BeforeEach - public void setUp() { + void setUp() { this.reloadConfigController = new ReloadConfigController(cmpServersConfig); } @Test - public void shouldReturnStatusOkWhenSuccessfullyReloaded() throws CmpServersConfigLoadingException { + void shouldReturnStatusOkWhenSuccessfullyReloaded() throws CmpServersConfigLoadingException { // When ResponseEntity<String> response = reloadConfigController.reloadConfiguration(); @@ -61,7 +60,7 @@ public class ReloadConfigControllerTest { } @Test - public void shouldRethrowSameErrorWhenFailedToReload() throws CmpServersConfigLoadingException { + void shouldRethrowSameErrorWhenFailedToReload() throws CmpServersConfigLoadingException { // Given doThrow(new CmpServersConfigLoadingException(ERROR_MESSAGE)).when(cmpServersConfig).reloadConfiguration(); @@ -74,16 +73,5 @@ public class ReloadConfigControllerTest { Assertions.assertThat(exception.getMessage()).isEqualTo(ERROR_MESSAGE); } - @Test - void shouldReturnErrorStatusAndMessageWhenExceptionOccurred() { - // Given - CmpServersConfigLoadingException exception = new CmpServersConfigLoadingException(ERROR_MESSAGE); - - // When - ResponseEntity<String> response = reloadConfigController.handle(exception); - // Then - assertEquals(ERROR_MESSAGE, response.getBody()); - assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); - } } diff --git a/certService/src/test/java/org/onap/aaf/certservice/certification/CertificationExceptionControllerTest.java b/certService/src/test/java/org/onap/aaf/certservice/api/advice/CertificationExceptionAdviceTest.java index 10a818e4..f3c4ec7f 100644 --- a/certService/src/test/java/org/onap/aaf/certservice/certification/CertificationExceptionControllerTest.java +++ b/certService/src/test/java/org/onap/aaf/certservice/api/advice/CertificationExceptionAdviceTest.java @@ -18,7 +18,7 @@ * ============LICENSE_END========================================================= */ -package org.onap.aaf.certservice.certification; +package org.onap.aaf.certservice.api.advice; import com.google.gson.Gson; import org.junit.jupiter.api.BeforeEach; @@ -35,14 +35,14 @@ import org.springframework.http.ResponseEntity; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; -class CertificationExceptionControllerTest { +class CertificationExceptionAdviceTest { - private CertificationExceptionController certificationExceptionController; + private CertificationExceptionAdvice certificationExceptionAdvice; @BeforeEach void setUp() { - certificationExceptionController = - new CertificationExceptionController(); + certificationExceptionAdvice = + new CertificationExceptionAdvice(); } @Test @@ -52,13 +52,11 @@ class CertificationExceptionControllerTest { CsrDecryptionException csrDecryptionException = new CsrDecryptionException("test csr exception"); // When - ResponseEntity<String> responseEntity = certificationExceptionController.handle(csrDecryptionException); - - ErrorResponseModel response = new Gson().fromJson(responseEntity.getBody(), ErrorResponseModel.class); + ResponseEntity<ErrorResponseModel> response = certificationExceptionAdvice.handle(csrDecryptionException); // Then - assertEquals(HttpStatus.BAD_REQUEST, responseEntity.getStatusCode()); - assertEquals(expectedMessage, response.getErrorMessage()); + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + assertEquals(expectedMessage, response.getBody().getErrorMessage()); } @Test @@ -68,13 +66,11 @@ class CertificationExceptionControllerTest { KeyDecryptionException csrDecryptionException = new KeyDecryptionException("test pk exception"); // When - ResponseEntity<String> responseEntity = certificationExceptionController.handle(csrDecryptionException); - - ErrorResponseModel response = new Gson().fromJson(responseEntity.getBody(), ErrorResponseModel.class); + ResponseEntity<ErrorResponseModel> response = certificationExceptionAdvice.handle(csrDecryptionException); // Then - assertEquals(HttpStatus.BAD_REQUEST, responseEntity.getStatusCode()); - assertEquals(expectedMessage, response.getErrorMessage()); + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + assertEquals(expectedMessage, response.getBody().getErrorMessage()); } @Test @@ -84,13 +80,11 @@ class CertificationExceptionControllerTest { Cmpv2ServerNotFoundException csrDecryptionException = new Cmpv2ServerNotFoundException("test Ca exception"); // When - ResponseEntity<String> responseEntity = certificationExceptionController.handle(csrDecryptionException); - - ErrorResponseModel response = new Gson().fromJson(responseEntity.getBody(), ErrorResponseModel.class); + ResponseEntity<ErrorResponseModel> response = certificationExceptionAdvice.handle(csrDecryptionException); // Then - assertEquals(HttpStatus.NOT_FOUND, responseEntity.getStatusCode()); - assertEquals(expectedMessage, response.getErrorMessage()); + assertEquals(HttpStatus.NOT_FOUND, response.getStatusCode()); + assertEquals(expectedMessage, response.getBody().getErrorMessage()); } @Test @@ -100,13 +94,11 @@ class CertificationExceptionControllerTest { CmpClientException cmpClientException = new CmpClientException("Calling CMPv2 client failed"); // When - ResponseEntity<String> responseEntity = certificationExceptionController.handle(cmpClientException); - - ErrorResponseModel response = new Gson().fromJson(responseEntity.getBody(), ErrorResponseModel.class); + ResponseEntity<ErrorResponseModel> response = certificationExceptionAdvice.handle(cmpClientException); // Then - assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); - assertEquals(expectedMessage, response.getErrorMessage()); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + assertEquals(expectedMessage, response.getBody().getErrorMessage()); } @Test @@ -116,13 +108,11 @@ class CertificationExceptionControllerTest { Cmpv2ClientAdapterException cmpv2ClientAdapterException = new Cmpv2ClientAdapterException(new Throwable()); // When - ResponseEntity<String> responseEntity = certificationExceptionController.handle(cmpv2ClientAdapterException); - - ErrorResponseModel response = new Gson().fromJson(responseEntity.getBody(), ErrorResponseModel.class); + ResponseEntity<ErrorResponseModel> response = certificationExceptionAdvice.handle(cmpv2ClientAdapterException); // Then - assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, responseEntity.getStatusCode()); - assertEquals(expectedMessage, response.getErrorMessage()); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + assertEquals(expectedMessage, response.getBody().getErrorMessage()); } @Test @@ -134,7 +124,7 @@ class CertificationExceptionControllerTest { // When Exception exception = assertThrows( CmpClientException.class, () -> - certificationExceptionController.handle(runtimeException) + certificationExceptionAdvice.handle(runtimeException) ); // Then diff --git a/certService/src/test/java/org/onap/aaf/certservice/api/advice/ReloadConfigExceptionAdviceTest.java b/certService/src/test/java/org/onap/aaf/certservice/api/advice/ReloadConfigExceptionAdviceTest.java new file mode 100644 index 00000000..9abecec9 --- /dev/null +++ b/certService/src/test/java/org/onap/aaf/certservice/api/advice/ReloadConfigExceptionAdviceTest.java @@ -0,0 +1,56 @@ +/* + * ============LICENSE_START======================================================= + * PROJECT + * ================================================================================ + * Copyright (C) 2020 Nokia. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.aaf.certservice.api.advice; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.onap.aaf.certservice.certification.configuration.CmpServersConfigLoadingException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ReloadConfigExceptionAdviceTest { + + private static final String ERROR_MESSAGE = "Exception occurred during CMP Servers configuration loading"; + + private ReloadConfigExceptionAdvice reloadConfigExceptionAdvice; + + @BeforeEach + void setUp() { + reloadConfigExceptionAdvice = + new ReloadConfigExceptionAdvice(); + } + + @Test + void shouldReturnErrorStatusAndMessageWhenExceptionOccurred() { + // Given + CmpServersConfigLoadingException exception = new CmpServersConfigLoadingException(ERROR_MESSAGE); + + // When + ResponseEntity<String> response = reloadConfigExceptionAdvice.handle(exception); + + // Then + assertEquals(ERROR_MESSAGE, response.getBody()); + assertEquals(HttpStatus.INTERNAL_SERVER_ERROR, response.getStatusCode()); + } + +} @@ -35,7 +35,7 @@ <stagingNexusPath>/content/repositories/staging/</stagingNexusPath> <sitePath>/content/sites/site/org/onap/aaf/cert-service/${project.artifactId}/${project.version}</sitePath> <java.version>11</java.version> - <springdoc-openapi-maven-plugin.apiDocsUrl>http://localhost:8080/v3/api-docs</springdoc-openapi-maven-plugin.apiDocsUrl> + <springdoc-openapi-maven-plugin.apiDocsUrl>http://localhost:8080/v3/api-docs.yaml</springdoc-openapi-maven-plugin.apiDocsUrl> <!-- Dependencies --> <assertj-core.version>3.15.0</assertj-core.version> @@ -94,7 +94,7 @@ </executions> <configuration> <apiDocsUrl>${springdoc-openapi-maven-plugin.apiDocsUrl}</apiDocsUrl> - <outputFileName>api-docs.json</outputFileName> + <outputFileName>api-docs.yaml</outputFileName> <outputDir>${project.build.directory}</outputDir> </configuration> </plugin> |