Skip to content

Commit

Permalink
Merge pull request #14 from companieshouse/idva6-388-put-status-v2
Browse files Browse the repository at this point in the history
Idva6 388 put status v2
  • Loading branch information
kkonuganti-ch authored Jan 17, 2024
2 parents 1ff1b6b + 9e8cb8d commit 265fe92
Show file tree
Hide file tree
Showing 29 changed files with 1,607 additions and 44 deletions.
9 changes: 7 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,16 @@ build:
cp ./target/$(artifact_name)-$(version).jar ./$(artifact_name).jar

.PHONY: test
test: test-unit
test: clean
mvn verify

.PHONY: test-unit
test-unit: clean
mvn test
mvn test -DexcludedGroups="integration-test"

.PHONY: test-integration
test-integration: clean
mvn test -Dgroups="integration-test"

.PHONY: package
package:
Expand Down
78 changes: 48 additions & 30 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@
<maven-surefire-plugin.version>3.2.2</maven-surefire-plugin.version>
<structured-logging.version>3.0.1</structured-logging.version>
<common-web-java.version>3.0.0</common-web-java.version>
<log4j.version>2.20.0</log4j.version>
<dependency-check-plugin.version>8.4.3</dependency-check-plugin.version>
<sonar-maven-plugin.version>3.10.0.2594</sonar-maven-plugin.version>
<jacoco-maven-plugin.version>0.8.10</jacoco-maven-plugin.version>
<encryption-java-library.version>2.0.3</encryption-java-library.version>
<rest-service-common-library-version>2.0.1</rest-service-common-library-version>
<rest-service-common-library-version>2.0.2</rest-service-common-library-version>
<private-api-sdk-java.version>4.0.30</private-api-sdk-java.version>
<api-sdk-manager-java-library.version>3.0.5</api-sdk-manager-java-library.version>
<api-security-java-version>2.0.3</api-security-java-version>
</properties>
<profiles>
<profile>
Expand All @@ -36,13 +38,6 @@
</profiles>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-bom</artifactId>
<version>${log4j.version}</version>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
Expand All @@ -61,6 +56,10 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>uk.gov.companieshouse</groupId>
<artifactId>structured-logging</artifactId>
Expand All @@ -72,31 +71,15 @@
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>uk.gov.companieshouse</groupId>
<artifactId>encryption-java-library</artifactId>
<version>${encryption-java-library.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20231013</version>
<artifactId>rest-service-common-library</artifactId>
<version>${rest-service-common-library-version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>uk.gov.companieshouse</groupId>
<artifactId>rest-service-common-library</artifactId>
<version>${rest-service-common-library-version}</version>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

<!-- Test dependencies -->
Expand All @@ -117,6 +100,36 @@
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-testcontainers</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mongodb</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>uk.gov.companieshouse</groupId>
<artifactId>private-api-sdk-java</artifactId>
<version>${private-api-sdk-java.version}</version>
</dependency>
<dependency>
<groupId>uk.gov.companieshouse</groupId>
<artifactId>api-sdk-manager-java-library</artifactId>
<version>${api-sdk-manager-java-library.version}</version>
</dependency>
<dependency>
<groupId>uk.gov.companieshouse</groupId>
<artifactId>api-security-java</artifactId>
<version>${api-security-java-version}</version>
</dependency>
</dependencies>

<build>
Expand Down Expand Up @@ -147,7 +160,12 @@
<artifactId>jib-maven-plugin</artifactId>
<version>3.4.0</version>
<configuration>
<from><image>amazoncorretto:21</image></from>
<from>
<image>416670754337.dkr.ecr.eu-west-2.amazonaws.com/ci-corretto-build-21</image>
</from>
<to>
<image>416670754337.dkr.ecr.eu-west-2.amazonaws.com/accounts-association-api</image>
</to>
<container>
<expandClasspathDependencies>true</expandClasspathDependencies>
</container>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package uk.gov.companieshouse.accounts.association;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class AccountsAssociationServiceApplication {

public static final String APPLICATION_NAME_SPACE = "accounts-association-api";
@Value("${spring.application.name}")
public static String applicationNameSpace;

public static void main(String[] args) {
SpringApplication.run(AccountsAssociationServiceApplication.class, args);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package uk.gov.companieshouse.accounts.association.configuration;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.NonNull;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
Expand All @@ -11,8 +9,12 @@
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

@Autowired
private LoggingInterceptor loggingInterceptor;

private final LoggingInterceptor loggingInterceptor;

public InterceptorConfig(LoggingInterceptor loggingInterceptor) {
this.loggingInterceptor = loggingInterceptor;
}

/**
* Setup the interceptors to run against endpoints when the endpoints are called
Expand All @@ -27,6 +29,7 @@ public void addInterceptors(@NonNull InterceptorRegistry registry) {

/**
* Interceptor that logs all calls to endpoints
*
* @param registry The spring interceptor registry
*/
private void addLoggingInterceptor(InterceptorRegistry registry) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package uk.gov.companieshouse.accounts.association.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.auditing.DateTimeProvider;
import org.springframework.data.mongodb.config.EnableMongoAuditing;
import org.springframework.data.mongodb.core.mapping.event.ValidatingMongoEventListener;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;

import java.time.LocalDateTime;
import java.util.Optional;

@Configuration
@EnableMongoRepositories("uk.gov.companieshouse.accounts.association.repositories")
@EnableMongoAuditing(dateTimeProviderRef = "mongodbDatetimeProvider")
public class MongoConfig {

@Bean
public ValidatingMongoEventListener validatingMongoEventListener(
final LocalValidatorFactoryBean factory) {
return new ValidatingMongoEventListener(factory);
}

@Bean(name = "mongodbDatetimeProvider")
public DateTimeProvider dateTimeProvider() {
return () -> Optional.of(LocalDateTime.now());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package uk.gov.companieshouse.accounts.association.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import uk.gov.companieshouse.accounts.association.AccountsAssociationServiceApplication;
import uk.gov.companieshouse.accounts.association.exceptions.BadRequestRuntimeException;
import uk.gov.companieshouse.accounts.association.exceptions.NotFoundRuntimeException;
import uk.gov.companieshouse.accounts.association.utils.CamelCaseSnakeCase;
import uk.gov.companieshouse.logging.Logger;
import uk.gov.companieshouse.logging.LoggerFactory;
import uk.gov.companieshouse.service.rest.err.Err;
import uk.gov.companieshouse.service.rest.err.Errors;

@org.springframework.web.bind.annotation.ControllerAdvice
public class ControllerAdvice extends ResponseEntityExceptionHandler {

private static final Logger LOG = LoggerFactory.getLogger(AccountsAssociationServiceApplication.applicationNameSpace);
public static final String X_REQUEST_ID = "X-Request-Id";

private String getJsonStringFromErrors(String requestId, Errors errors) {

ObjectMapper objectMapper = new ObjectMapper();
try {
return objectMapper.writeValueAsString(errors);
}
catch (IOException e) {
LOG.errorContext(requestId, String.format("Fail to parse Errors object to JSON %s", e.getMessage()), e, null);
return "";
}
}

@ExceptionHandler(NotFoundRuntimeException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
@ResponseBody
public Errors onNotFoundRuntimeException(NotFoundRuntimeException e, HttpServletRequest r) {
String requestId = r.getHeader(X_REQUEST_ID);

Map<String, Object> contextMap = new HashMap<>();
contextMap.put("url", r.getRequestURL().toString());
contextMap.put("query-parameters", r.getQueryString() != null ? "?" + r.getQueryString() : "");

LOG.errorContext(requestId, e.getMessage(), null, contextMap);

Errors errors = new Errors();
errors.addError(Err.invalidBodyBuilderWithLocation(e.getFieldLocation()).withError(e.getMessage()).build());
return errors;
}

@ExceptionHandler(BadRequestRuntimeException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public Errors onBadRequestRuntimeException(BadRequestRuntimeException e, HttpServletRequest request) {
String requestId = request.getHeader(X_REQUEST_ID);

Map<String, Object> contextMap = new HashMap<>();
contextMap.put("url", request.getRequestURL().toString());
contextMap.put("query-parameters", request.getQueryString() != null ? "?" + request.getQueryString() : "");

LOG.errorContext(requestId, e.getMessage(), null, contextMap);

Errors errors = new Errors();
errors.addError(Err.invalidBodyBuilderWithLocation("accounts_association_api").withError(e.getMessage()).build());
return errors;
}

@ExceptionHandler(ConstraintViolationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
@ResponseBody
public Errors onConstraintViolationException( ConstraintViolationException exception, HttpServletRequest request) {

Errors errors = new Errors();
for (ConstraintViolation<?> constraintViolation : exception.getConstraintViolations()) {
final var location = CamelCaseSnakeCase.toSnakeCase(constraintViolation.getPropertyPath().toString());
var errorMessage = getConstraintViolationExceptionErrorMessage( location );
errors.addError(Err.invalidBodyBuilderWithLocation(location).withError(errorMessage).build());
}

String requestId = request.getHeader(X_REQUEST_ID);
String errorsJsonString = getJsonStringFromErrors(requestId, errors);
LOG.errorContext(requestId, String.format("Validation Failed with [%s]", errorsJsonString), exception, null );

return errors;
}

private String getConstraintViolationExceptionErrorMessage(String location) {
return switch (location) {
case "update_association_status_for_user_and_company.arg0" -> "Please check the request and try again.";
case "update_association_status_for_user_and_company.arg1" -> "Please check the request and try again.";
default -> "One of the inputs is incorrectly formatted";
};
}

@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public void onException(Exception e, HttpServletRequest r) {
String requestId = r.getHeader(X_REQUEST_ID);
String msg = r.getRequestURL() + (r.getQueryString()!=null ? "?"+r.getQueryString() : "") + ". " + e.getMessage();
LOG.errorContext(requestId, msg, e, null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package uk.gov.companieshouse.accounts.association.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/associations")
public class HealthCheckController {

@GetMapping("/healthcheck")
public ResponseEntity<String> checking() {
return ResponseEntity.ok().body("OK");
}
}
Loading

0 comments on commit 265fe92

Please sign in to comment.