Skip to content

Commit

Permalink
DSND-3113: Change delete operation order for pscs, add kind and delta…
Browse files Browse the repository at this point in the history
…_at logic (strict) (#157)

* DSND-3113: WIP - Adds kind property to the delete PSC delta

Requires changes to use the `kind` argument from the DELETE request header

* DSND-3113: WIP Implement Kind logic for delete deltas

* kind logic for upsert is very different from for delete.
* implemented kind logic coming from delta instead of being retrieved from mongo
* implemented kind and delta_at headers within controller method
* implemented delta_at check similar to filing history
* fixed all compilation errors

* DSND-3113: Implement chs-kafka-api call and fix any remaining test cases.

* add needed exclusions to pom for test functionality
* made kind variables more accurate across the project
* added logic for even if document deleted chs-kafka is still called
* added additional tests for kind and fixed any existing broken ones

* DSND-3113: Unused imports and wildcard imports fixed.

* DSND-3113: Address PR comments

* DSND-3113: Upgrade versions in Pom

* DSND-3113: Revert spring boot upgrade in the Pom

* DSND-3113: Upgrade sdk version in pom to enable header handlers for kind and delta_at

* DSND-3113: Address PR comments 2

* DSND-3113: Add additional iTest class for deltaAt conflict test case

* DSND-3113: Upgrade springboot versions appropriately

* DSND-3113: Address PR comment

* use handmade exception
* add unit testcase for deltaAt check

* DSND-3113: Add ExceptionHandlerConfig case and relevant testcases

* DSND-3113: Remove catch statement in the controller

* DSND-3113: Address PR comment

* some small test name changes

* DSND-3113: Address PR comment

* test name changes
* string concatenation

---------

Co-authored-by: johncookch <[email protected]>
  • Loading branch information
crowlandsCH and johncook-ch authored Dec 11, 2024
1 parent b807c82 commit 8b250dd
Show file tree
Hide file tree
Showing 19 changed files with 542 additions and 182 deletions.
18 changes: 12 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>uk.gov.companieshouse</groupId>
<artifactId>companies-house-parent</artifactId>
<version>2.1.6</version>
<version>2.1.10</version>
<relativePath />
</parent>
<artifactId>psc-data-api</artifactId>
Expand All @@ -16,17 +16,17 @@
<properties>
<java.version>21</java.version>
<start-class>uk.gov.companieshouse.pscdataapi.PscDataApiApplication</start-class>
<spring-boot-dependencies.version>3.3.1</spring-boot-dependencies.version>
<spring-boot-maven-plugin.version>3.3.1</spring-boot-maven-plugin.version>
<spring-boot-dependencies.version>3.3.6</spring-boot-dependencies.version>
<spring-boot-maven-plugin.version>3.3.6</spring-boot-maven-plugin.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven-surefire-plugin.version>3.3.0</maven-surefire-plugin.version>
<jib-maven-plugin.version>3.4.2</jib-maven-plugin.version>
<jacoco-maven-plugin.version>0.8.12</jacoco-maven-plugin.version>

<!-- Internal -->
<structured-logging.version>3.0.8</structured-logging.version>
<private-api-sdk-java.version>4.0.241</private-api-sdk-java.version>
<structured-logging.version>3.0.20</structured-logging.version>
<private-api-sdk-java.version>4.0.249</private-api-sdk-java.version>
<data-sync-api-sdk-java.version>1.0.6</data-sync-api-sdk-java.version>
<api-security-java.version>2.0.5</api-security-java.version>
<api-sdk-manager-java-library.version>3.0.5</api-sdk-manager-java-library.version>
Expand Down Expand Up @@ -71,7 +71,7 @@
<artifactId>log4j-to-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
Expand Down Expand Up @@ -132,6 +132,12 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.xmlunit</groupId>
<artifactId>xmlunit-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>uk.gov.companieshouse</groupId>
Expand Down
234 changes: 156 additions & 78 deletions src/itest/java/uk/gov/companieshouse/pscdataapi/steps/PscDataSteps.java

Large diffs are not rendered by default.

16 changes: 14 additions & 2 deletions src/itest/resources/features/delete_psc.feature
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ Feature: Delete PSC
| company_number |
| 34777772 |

Scenario Outline: Delete PSC unsuccessfully - PSC resource does not exist
Scenario Outline: Delete PSC unsuccessfully but chs-kafka-api invoked - PSC resource does not exist
Given a PSC does not exist for "<company_number>"
When a DELETE request is sent for "<company_number>"
Then I should receive 404 status code
Then the CHS Kafka API is invoked with a DELETE event
And I should receive 200 status code

Examples:
| company_number |
Expand All @@ -41,3 +42,14 @@ Feature: Delete PSC
Examples:
| company_number |
| 34777772 |

Scenario Outline: Delete PSC throws conflict exception if deltaAt is stale
Given Psc data api service is running
And a PSC "<data>" exists for "<company_number>" for Individual with "<existingDeltaAt>"
When a DELETE request is sent for "<company_number>" with a stale "<deltaAt>"
Then I should receive 409 status code
And the CHS Kafka API is not invoked with a DELETE event

Examples:
| data | company_number | existingDeltaAt | deltaAt |
| get_individual | 34777772 | 20231020084745378999 | 20230724093435661593 |
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import uk.gov.companieshouse.api.InternalApiClient;
Expand All @@ -19,6 +18,7 @@
import uk.gov.companieshouse.logging.Logger;
import uk.gov.companieshouse.pscdataapi.exceptions.SerDesException;
import uk.gov.companieshouse.pscdataapi.exceptions.ServiceUnavailableException;
import uk.gov.companieshouse.pscdataapi.models.PscDeleteRequest;
import uk.gov.companieshouse.pscdataapi.models.PscDocument;
import uk.gov.companieshouse.pscdataapi.transform.CompanyPscTransformer;
import uk.gov.companieshouse.pscdataapi.util.PscTransformationHelper;
Expand All @@ -44,7 +44,7 @@ public class ChsKafkaApiService {
private String resourceChangedUri;

public ChsKafkaApiService(InternalApiClient internalApiClient, Logger logger,
ObjectMapper objectMapper, CompanyPscTransformer companyPscTransformer) {
ObjectMapper objectMapper, CompanyPscTransformer companyPscTransformer) {
this.internalApiClient = internalApiClient;
this.logger = logger;
this.objectMapper = objectMapper;
Expand All @@ -62,7 +62,7 @@ public ChsKafkaApiService(InternalApiClient internalApiClient, Logger logger,

@StreamEvents
public ApiResponse<Void> invokeChsKafkaApi(String contextId, String companyNumber,
String notificationId, String kind) {
String notificationId, String kind) {
internalApiClient.setBasePath(chsKafkaApiUrl);
PrivateChangedResourcePost changedResourcePost = internalApiClient
.privateChangedResourceHandler().postChangedResource(resourceChangedUri,
Expand All @@ -74,28 +74,22 @@ public ApiResponse<Void> invokeChsKafkaApi(String contextId, String companyNumbe
/**
* Creates a ChangedResource object to send a delete request to the chs kafka api.
*
* @param contextId chs kafka id
* @param companyNumber company number of psc
* @param notificationId mongo id
* @return passes request to api response handling
*/
@StreamEvents
public ApiResponse<Void> invokeChsKafkaApiWithDeleteEvent(String contextId,
String companyNumber,
String notificationId,
String kind, PscDocument pscDocument) {
public ApiResponse<Void> invokeChsKafkaApiWithDeleteEvent(PscDeleteRequest deleteRequest, PscDocument pscDocument) {

internalApiClient.setBasePath(chsKafkaApiUrl);
PrivateChangedResourcePost changedResourcePost =
internalApiClient.privateChangedResourceHandler()
.postChangedResource(resourceChangedUri,
mapChangedResource(contextId, companyNumber,
notificationId, kind, true, pscDocument));
mapChangedResource(deleteRequest.contextId(), deleteRequest.companyNumber(),
deleteRequest.notificationId(), deleteRequest.kind(), true, pscDocument));
return handleApiCall(changedResourcePost);
}

private ChangedResource mapChangedResource(String contextId, String companyNumber,
String notificationId,
String kind, boolean isDelete, PscDocument pscDocument) {
private ChangedResource mapChangedResource(String contextId, String companyNumber, String notificationId,
String kind, boolean isDelete, PscDocument pscDocument) {
ChangedResourceEvent event = new ChangedResourceEvent();
ChangedResource changedResource = new ChangedResource();
event.setPublishedAt(PUBLISHED_AT_FORMAT.format(Instant.now()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.springframework.web.context.request.WebRequest;
import uk.gov.companieshouse.logging.Logger;
import uk.gov.companieshouse.pscdataapi.exceptions.BadRequestException;
import uk.gov.companieshouse.pscdataapi.exceptions.ConflictException;
import uk.gov.companieshouse.pscdataapi.exceptions.MethodNotAllowedException;
import uk.gov.companieshouse.pscdataapi.exceptions.SerDesException;
import uk.gov.companieshouse.pscdataapi.exceptions.ServiceUnavailableException;
Expand Down Expand Up @@ -133,4 +134,24 @@ public ResponseEntity<Object> handleBadRequestException(Exception ex, WebRequest
request.setAttribute(EXCEPTION_ATTRIBUTE, ex, 0);
return new ResponseEntity<>(responseBody, HttpStatus.BAD_REQUEST);
}


/**
* Conflict exception handler.
* Thrown when data is given in the wrong format.
*
* @param ex exception to handle.
* @param request request.
* @return error response to return.
*/
@ExceptionHandler(value = {ConflictException.class})
public ResponseEntity<Object> handleConflictException(Exception ex, WebRequest request) {
logger.error(String.format("Conflict, response code: %s", HttpStatus.CONFLICT), ex);

Map<String, Object> responseBody = new LinkedHashMap<>();
responseBody.put(TIMESTAMP, LocalDateTime.now());
responseBody.put(MESSAGE, "Conflict.");
request.setAttribute(EXCEPTION_ATTRIBUTE, ex, 0);
return new ResponseEntity<>(responseBody, HttpStatus.CONFLICT);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import uk.gov.companieshouse.pscdataapi.exceptions.ResourceNotFoundException;
import uk.gov.companieshouse.pscdataapi.exceptions.ServiceUnavailableException;
import uk.gov.companieshouse.pscdataapi.logging.DataMapHolder;
import uk.gov.companieshouse.pscdataapi.models.PscDeleteRequest;
import uk.gov.companieshouse.pscdataapi.service.CompanyPscService;


Expand Down Expand Up @@ -88,14 +89,21 @@ public ResponseEntity<Void> submitPscData(@RequestHeader("x-request-id") String
public ResponseEntity<Void> deletePscData(
@PathVariable("company_number") String companyNumber,
@PathVariable("notification_id") String notificationId,
@RequestHeader("x-request-id") String contextId) {
@RequestHeader("x-request-id") String contextId,
@RequestHeader("x-kind") String kind,
@RequestHeader("x-delta-at") String deltaAt) {
DataMapHolder.get()
.companyNumber(companyNumber)
.itemId(notificationId);
LOGGER.info(String.format("Deleting PSC data with company number %s", companyNumber),
DataMapHolder.getLogMap());
try {
pscService.deletePsc(companyNumber, notificationId, contextId);
pscService.deletePsc(PscDeleteRequest.builder()
.companyNumber(companyNumber)
.notificationId(notificationId)
.contextId(contextId).kind(kind)
.deltaAt(deltaAt)
.build());
LOGGER.info(String.format("Successfully deleted PSC with company number %s",
companyNumber), DataMapHolder.getLogMap());
return ResponseEntity.status(HttpStatus.OK).build();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package uk.gov.companieshouse.pscdataapi.controller;

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.dao.DataAccessException;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package uk.gov.companieshouse.pscdataapi.exceptions;

public class ConflictException extends RuntimeException {

public ConflictException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package uk.gov.companieshouse.pscdataapi.models;

public record PscDeleteRequest (String companyNumber, String notificationId, String contextId, String kind, String deltaAt) {

public static Builder builder() { return new Builder(); }

public static final class Builder {

private String companyNumber;
private String notificationId;
private String contextId;
private String kind;
private String deltaAt;

private Builder() {
}

public Builder companyNumber(String companyNumber) {
this.companyNumber = companyNumber;
return this;
}

public Builder notificationId(String notificationId) {
this.notificationId = notificationId;
return this;
}

public Builder contextId(String contextId) {
this.contextId = contextId;
return this;
}

public Builder kind(String kind) {
this.kind = kind;
return this;
}

public Builder deltaAt(String deltaAt) {
this.deltaAt = deltaAt;
return this;
}

public PscDeleteRequest build() {
return new PscDeleteRequest(companyNumber, notificationId, contextId, kind, deltaAt);
}
}
}
Loading

0 comments on commit 8b250dd

Please sign in to comment.