Skip to content

Commit 9925ac3

Browse files
authored
Merge pull request #172 from companieshouse/feature/add-verfication-state-to-full-record
Add Verification State data to the Individual Full Record
2 parents bc81e73 + 7d44e7f commit 9925ac3

File tree

10 files changed

+342
-12
lines changed

10 files changed

+342
-12
lines changed

pom.xml

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,20 @@
1919
<spring-boot-maven-plugin.version>3.4.1</spring-boot-maven-plugin.version>
2020
<maven.compiler.source>${java.version}</maven.compiler.source>
2121
<maven.compiler.target>${java.version}</maven.compiler.target>
22+
<maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>
2223
<maven-surefire-plugin.version>3.5.2</maven-surefire-plugin.version>
2324
<maven-failsafe-plugin.version>3.5.2</maven-failsafe-plugin.version>
2425
<maven-resources-plugin.version>3.3.1</maven-resources-plugin.version>
2526
<maven-build-helper-plugin.version>3.6.0</maven-build-helper-plugin.version>
2627
<jib-maven-plugin.version>3.4.4</jib-maven-plugin.version>
2728
<jacoco-maven-plugin.version>0.8.12</jacoco-maven-plugin.version>
2829
<commons.io.version>2.18.0</commons.io.version>
30+
<org.mapstruct.version>1.6.3</org.mapstruct.version>
2931

3032
<!-- Internal -->
3133
<structured-logging.version>3.0.20</structured-logging.version>
32-
<private-api-sdk-java.version>4.0.258</private-api-sdk-java.version>
33-
<api-sdk-java.version>6.0.31</api-sdk-java.version>
34+
<private-api-sdk-java.version>4.0.269</private-api-sdk-java.version>
35+
<api-sdk-java.version>6.0.33</api-sdk-java.version>
3436
<api-security-java.version>2.0.5</api-security-java.version>
3537

3638
<!-- tests -->
@@ -174,6 +176,11 @@
174176
<version>${commons.io.version}</version>
175177
<scope>test</scope>
176178
</dependency>
179+
<dependency>
180+
<groupId>org.mapstruct</groupId>
181+
<artifactId>mapstruct</artifactId>
182+
<version>${org.mapstruct.version}</version>
183+
</dependency>
177184
</dependencies>
178185

179186
<build>
@@ -193,13 +200,41 @@
193200
</execution>
194201
</executions>
195202
</plugin>
203+
<plugin>
204+
<groupId>org.apache.maven.plugins</groupId>
205+
<artifactId>maven-dependency-plugin</artifactId>
206+
<executions>
207+
<execution>
208+
<goals>
209+
<goal>properties</goal>
210+
</goals>
211+
</execution>
212+
</executions>
213+
</plugin>
214+
<plugin>
215+
<groupId>org.apache.maven.plugins</groupId>
216+
<artifactId>maven-compiler-plugin</artifactId>
217+
<version>${maven-compiler-plugin.version}</version>
218+
<configuration>
219+
<source>${java.version}</source>
220+
<target>${java.version}</target>
221+
<annotationProcessorPaths>
222+
<path>
223+
<groupId>org.mapstruct</groupId>
224+
<artifactId>mapstruct-processor</artifactId>
225+
<version>${org.mapstruct.version}</version>
226+
</path>
227+
</annotationProcessorPaths>
228+
</configuration>
229+
</plugin>
196230
<plugin>
197231
<groupId>org.apache.maven.plugins</groupId>
198232
<artifactId>maven-surefire-plugin</artifactId>
199233
<version>${maven-surefire-plugin.version}</version>
200234
<configuration>
201235
<argLine>-Dfile.encoding=UTF-8</argLine>
202236
<argLine>${surefireArgLine}</argLine>
237+
<argLine>@{argLine} -javaagent:${org.mockito:mockito-core:jar}</argLine>
203238
<skipTests>${skip.unit.tests}</skipTests>
204239
</configuration>
205240
</plugin>

src/main/java/uk/gov/companieshouse/pscdataapi/config/ApplicationConfig.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,18 @@ public class ApplicationConfig {
3535
private final String kafkaApiUrl;
3636
private final String metricsApiUrl;
3737
private final String exemptionsApiUrl;
38+
private final String verificationStateApiUrl;
3839

3940
public ApplicationConfig(@Value("${api.key}") String apiKey,
40-
@Value("${kafka.api.url}") String kafkaApiUrl,
41-
@Value("${metrics.api.url}") String metricsApiUrl,
42-
@Value("${exemptions.api.url}") String exemptionsApiUrl) {
41+
@Value("${kafka.api.url}") String kafkaApiUrl,
42+
@Value("${metrics.api.url}") String metricsApiUrl,
43+
@Value("${exemptions.api.url}") String exemptionsApiUrl,
44+
@Value("${verification-state.api.url}") final String verificationStateApiUrl) {
4345
this.apiKey = apiKey;
4446
this.kafkaApiUrl = kafkaApiUrl;
4547
this.metricsApiUrl = metricsApiUrl;
4648
this.exemptionsApiUrl = exemptionsApiUrl;
49+
this.verificationStateApiUrl = verificationStateApiUrl;
4750
}
4851

4952
/*
@@ -76,6 +79,15 @@ public Supplier<InternalApiClient> exemptionsApiClientSupplier() {
7679
return () -> buildClient(exemptionsApiUrl);
7780
}
7881

82+
@Bean
83+
public Supplier<InternalApiClient> verificationStateApiClientSupplier() {
84+
return () -> {
85+
final var internalApiClient = buildClient(verificationStateApiUrl);
86+
internalApiClient.setInternalBasePath(verificationStateApiUrl);
87+
return internalApiClient;
88+
};
89+
}
90+
7991
@Bean
8092
@Primary
8193
public ObjectMapper objectMapper() {
@@ -108,4 +120,4 @@ private InternalApiClient buildClient(final String url) {
108120

109121
return internalApiClient;
110122
}
111-
}
123+
}

src/main/java/uk/gov/companieshouse/pscdataapi/config/FeatureFlags.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@ public class FeatureFlags {
88

99
private final boolean streamHookDisabled;
1010
private final boolean individualPscFullRecordGetEnabled;
11+
private final boolean individualPscFullRecordAddVerificationStateEnabled;
1112

1213
public FeatureFlags(@Value("${feature.seeding_collection_enabled}") final boolean streamHookDisabled,
13-
@Value("${feature.psc_individual_full_record_get}") final boolean individualPscFullRecordGetEnabled) {
14+
@Value("${feature.psc_individual_full_record_get}") final boolean individualPscFullRecordGetEnabled,
15+
@Value("${feature.psc_individual_full_record_add_verification_state}") final boolean individualPscFullRecordAddVerificationStateEnabled) {
1416
this.streamHookDisabled = streamHookDisabled;
1517
this.individualPscFullRecordGetEnabled = individualPscFullRecordGetEnabled;
18+
this.individualPscFullRecordAddVerificationStateEnabled = individualPscFullRecordAddVerificationStateEnabled;
1619
}
1720

1821
public boolean isStreamHookDisabled() {
@@ -22,4 +25,8 @@ public boolean isStreamHookDisabled() {
2225
public boolean isIndividualPscFullRecordGetEnabled() {
2326
return individualPscFullRecordGetEnabled;
2427
}
28+
29+
public boolean isIndividualPscFullRecordAddVerificationStateEnabled() {
30+
return individualPscFullRecordAddVerificationStateEnabled;
31+
}
2532
}

src/main/java/uk/gov/companieshouse/pscdataapi/service/CompanyPscService.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.util.Collections;
1111
import java.util.List;
1212
import java.util.Optional;
13+
1314
import org.springframework.http.HttpStatus;
1415
import org.springframework.stereotype.Service;
1516
import uk.gov.companieshouse.api.exemptions.CompanyExemptions;
@@ -30,6 +31,7 @@
3031
import uk.gov.companieshouse.api.psc.SuperSecureBeneficialOwner;
3132
import uk.gov.companieshouse.logging.Logger;
3233
import uk.gov.companieshouse.pscdataapi.api.ChsKafkaApiService;
34+
import uk.gov.companieshouse.pscdataapi.config.FeatureFlags;
3335
import uk.gov.companieshouse.pscdataapi.exceptions.BadRequestException;
3436
import uk.gov.companieshouse.pscdataapi.exceptions.ConflictException;
3537
import uk.gov.companieshouse.pscdataapi.exceptions.ResourceNotFoundException;
@@ -42,6 +44,7 @@
4244
import uk.gov.companieshouse.pscdataapi.models.PscDocument;
4345
import uk.gov.companieshouse.pscdataapi.repository.CompanyPscRepository;
4446
import uk.gov.companieshouse.pscdataapi.transform.CompanyPscTransformer;
47+
import uk.gov.companieshouse.pscdataapi.transform.VerificationStateMapper;
4548

4649
@Service
4750
public class CompanyPscService {
@@ -55,24 +58,33 @@ public class CompanyPscService {
5558
DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSSSSS");
5659

5760
private final Logger logger;
61+
private final FeatureFlags featureFlags;
5862
private final CompanyPscTransformer transformer;
5963
private final CompanyPscRepository repository;
6064
private final ChsKafkaApiService chsKafkaApiService;
6165
private final CompanyExemptionsApiService companyExemptionsApiService;
6266
private final CompanyMetricsApiService companyMetricsApiService;
67+
private final VerificationStateApiService verificationStateApiService;
68+
private final VerificationStateMapper verificationStateMapper;
6369

6470
public CompanyPscService(Logger logger,
71+
FeatureFlags featureFlags,
6572
CompanyPscTransformer transformer,
6673
CompanyPscRepository repository,
6774
ChsKafkaApiService chsKafkaApiService,
6875
CompanyExemptionsApiService companyExemptionsApiService,
69-
CompanyMetricsApiService companyMetricsApiService) {
76+
CompanyMetricsApiService companyMetricsApiService,
77+
VerificationStateApiService verificationStateApiService,
78+
VerificationStateMapper verificationStateMapper) {
7079
this.logger = logger;
80+
this.featureFlags = featureFlags;
7181
this.transformer = transformer;
7282
this.repository = repository;
7383
this.chsKafkaApiService = chsKafkaApiService;
7484
this.companyExemptionsApiService = companyExemptionsApiService;
7585
this.companyMetricsApiService = companyMetricsApiService;
86+
this.verificationStateApiService = verificationStateApiService;
87+
this.verificationStateMapper = verificationStateMapper;
7688
}
7789

7890
/**
@@ -197,7 +209,14 @@ public IndividualFullRecord getIndividualFullRecord(final String companyNumber,
197209
throw new ResourceNotFoundException(HttpStatus.NOT_FOUND,
198210
"Failed to transform PSCDocument to Individual Full Record");
199211
}
212+
213+
if (featureFlags.isIndividualPscFullRecordAddVerificationStateEnabled()) {
214+
verificationStateApiService.getPscVerificationState(individualFullRecord.getInternalId())
215+
.map(verificationStateMapper::mapToVerificationState)
216+
.ifPresent(individualFullRecord::setVerificationState);
217+
}
200218
return individualFullRecord;
219+
201220
} else {
202221
throw new ResourceNotFoundException(HttpStatus.NOT_FOUND,
203222
"Individual PSC document not found with id " + notificationId);
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package uk.gov.companieshouse.pscdataapi.service;
2+
3+
import static uk.gov.companieshouse.pscdataapi.PscDataApiApplication.APPLICATION_NAME_SPACE;
4+
5+
import java.util.Optional;
6+
import java.util.function.Supplier;
7+
import org.springframework.beans.factory.annotation.Qualifier;
8+
import org.springframework.stereotype.Component;
9+
import uk.gov.companieshouse.api.InternalApiClient;
10+
import uk.gov.companieshouse.api.error.ApiErrorResponseException;
11+
import uk.gov.companieshouse.api.handler.exception.URIValidationException;
12+
import uk.gov.companieshouse.api.model.ApiResponse;
13+
import uk.gov.companieshouse.api.model.psc.PscVerificationStateApi;
14+
import uk.gov.companieshouse.api.model.psc.VerificationStateCriteriaApi;
15+
import uk.gov.companieshouse.logging.Logger;
16+
import uk.gov.companieshouse.logging.LoggerFactory;
17+
import uk.gov.companieshouse.pscdataapi.exceptions.BadGatewayException;
18+
import uk.gov.companieshouse.pscdataapi.logging.DataMapHolder;
19+
20+
@Component
21+
public class VerificationStateApiService {
22+
23+
private static final Logger LOGGER = LoggerFactory.getLogger(APPLICATION_NAME_SPACE);
24+
25+
private final Supplier<InternalApiClient> verificationStateApiClientSupplier;
26+
27+
public VerificationStateApiService(
28+
@Qualifier("verificationStateApiClientSupplier") Supplier<InternalApiClient> verificationStateApiClientSupplier) {
29+
this.verificationStateApiClientSupplier = verificationStateApiClientSupplier;
30+
}
31+
32+
public Optional<PscVerificationStateApi> getPscVerificationState(final Long applicationId) {
33+
ApiResponse<PscVerificationStateApi> response = null;
34+
35+
try {
36+
response = verificationStateApiClientSupplier.get()
37+
.privatePscResourceHandler()
38+
.getPscVerificationState(
39+
"/corporate-body-appointments/persons-of-significant-control/verification-state",
40+
new VerificationStateCriteriaApi(applicationId))
41+
.execute();
42+
} catch (ApiErrorResponseException ex) {
43+
final int statusCode = ex.getStatusCode();
44+
LOGGER.info("PSC Verification State API POST failed with status code [%s]".formatted(statusCode),
45+
DataMapHolder.getLogMap());
46+
if (statusCode != 404) {
47+
throw new BadGatewayException("PSC Verification State API POST API endpoint", ex);
48+
}
49+
} catch (URIValidationException ex) {
50+
LOGGER.info("URI validation error when calling PSC Verification State API POST API", DataMapHolder.getLogMap());
51+
throw new BadGatewayException("URI validation error when calling PSC Verification State API POST API", ex);
52+
}
53+
54+
return Optional.ofNullable(response).map(ApiResponse::getData);
55+
}
56+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package uk.gov.companieshouse.pscdataapi.transform;
2+
3+
import org.mapstruct.Mapper;
4+
import uk.gov.companieshouse.api.model.psc.PscVerificationStateApi;
5+
import uk.gov.companieshouse.api.model.psc.VerificationState;
6+
7+
@Mapper(componentModel = "spring")
8+
public interface VerificationStateMapper {
9+
10+
VerificationState mapToVerificationState(PscVerificationStateApi pscVerificationStateApi);
11+
12+
}

src/main/resources/application.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ api.key=${CHS_API_KEY:chsApiKey}
99
kafka.api.url=${CHS_KAFKA_API_URL:http://localhost:8888}
1010
metrics.api.url=${API_LOCAL_URL:http://localhost:8888}
1111
exemptions.api.url=${API_LOCAL_URL:http://localhost:8888}
12+
verification-state.api.url=${API_LOCAL_URL:http://localhost:8888}
1213

1314
spring.data.mongodb.uri=${MONGODB_URL:mongodb://mongo:27017}
1415
spring.data.mongodb.name=company_pscs
@@ -21,5 +22,6 @@ spring.data.jackson.default-property-inclusion=NON_NULL
2122

2223
feature.seeding_collection_enabled=${SEEDING_COLLECTION_ENABLED:false}
2324
feature.psc_individual_full_record_get=${FEATURE_FLAG_PSC_INDIVIDUAL_FULL_RECORD_GET_081124:false}
25+
feature.psc_individual_full_record_add_verification_state=${FEATURE_FLAG_PSC_INDIVIDUAL_FULL_RECORD_ADD_VERIFICATION_STATE_180225:false}
2426

2527
server.port=${PORT:8081}

src/test/java/uk/gov/companieshouse/pscdataapi/controller/CompanyPscFullRecordGetControllerTest.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
99
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
1010

11+
import java.time.LocalDate;
1112
import java.util.Arrays;
13+
1214
import org.junit.jupiter.api.DisplayName;
1315
import org.junit.jupiter.api.Test;
1416
import org.springframework.beans.factory.annotation.Autowired;
@@ -19,6 +21,8 @@
1921
import org.springframework.test.web.servlet.MockMvc;
2022
import uk.gov.companieshouse.api.model.common.Address;
2123
import uk.gov.companieshouse.api.model.psc.IndividualFullRecord;
24+
import uk.gov.companieshouse.api.model.psc.VerificationState;
25+
import uk.gov.companieshouse.api.model.psc.VerificationStatus;
2226
import uk.gov.companieshouse.api.psc.DateOfBirth;
2327
import uk.gov.companieshouse.api.psc.ItemLinkTypes;
2428
import uk.gov.companieshouse.api.psc.NameElements;
@@ -93,7 +97,12 @@ void getIndividualPSC() throws Exception {
9397
"premises": "Cottage"
9498
},
9599
"residential_address_same_as_service_address": false,
96-
"internal_id" : 123456789
100+
"internal_id" : 123456789,
101+
"verification_state": {
102+
"verification_status": "VERIFIED",
103+
"verification_start_date": "2025-01-10",
104+
"verification_statement_due_date": "2025-02-05"
105+
}
97106
}
98107
""";
99108

@@ -146,7 +155,8 @@ private static IndividualFullRecord createFullRecord() {
146155
.naturesOfControl(Arrays.asList("nature of my control"))
147156
.dateOfBirth(new DateOfBirth().day(1).month(2).year(2000))
148157
.internalId(123456789L)
149-
.links(Arrays.asList(new ItemLinkTypes().self("/company/123/persons-with-significant-control/456")));
158+
.links(Arrays.asList(new ItemLinkTypes().self("/company/123/persons-with-significant-control/456")))
159+
.verificationState(new VerificationState(VerificationStatus.VERIFIED, LocalDate.of(2025, 1, 10), LocalDate.of(2025, 2, 5)));
150160
}
151161

152162
}

0 commit comments

Comments
 (0)