Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 62 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<properties>
<java.version>21</java.version>
<maven-build-helper-plugin.version>3.2.0</maven-build-helper-plugin.version>
<spring-boot-dependencies.version>4.0.6</spring-boot-dependencies.version>
<spring-boot-dependencies.version>4.0.7</spring-boot-dependencies.version>

<!-- tests -->
<maven-surefire-plugin.version>3.5.3</maven-surefire-plugin.version>
Expand All @@ -28,10 +28,11 @@
<skip.unit.tests>false</skip.unit.tests>
<maven-resources-plugin.version>3.3.1</maven-resources-plugin.version>
<docker-java-api.version>3.7.1</docker-java-api.version>
<spring-web.version>7.0.7</spring-web.version>
<spring-web.version>7.0.8</spring-web.version>
<commons-lang3.version>3.19.0</commons-lang3.version>
<tomcat-embed-core.version>11.0.22</tomcat-embed-core.version>
<tomcat-embed-core.version>11.0.24</tomcat-embed-core.version>
<junit-jupiter.version>5.14.1</junit-jupiter.version>
<opentelemetry-semconv.version>1.42.0</opentelemetry-semconv.version>

<!-- Internal -->
<structured-logging.version>3.0.57</structured-logging.version>
Expand Down Expand Up @@ -61,6 +62,7 @@
<log4j-api.version>2.26.0</log4j-api.version>
<guava.version>32.0.1-android</guava.version>
<grpc-context.version>1.81.0</grpc-context.version>
<jackson-core.version>3.1.4</jackson-core.version>
</properties>

<dependencyManagement>
Expand Down Expand Up @@ -143,6 +145,19 @@
<version>${grpc-context.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>tools.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson-core.version}</version>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>io.opentelemetry.semconv</groupId>
<artifactId>opentelemetry-semconv</artifactId>
<version>${opentelemetry-semconv.version}</version>
</dependency>

</dependencies>
</dependencyManagement>

Expand Down Expand Up @@ -187,6 +202,10 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
Expand Down Expand Up @@ -220,23 +239,63 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>uk.gov.companieshouse</groupId>
<artifactId>api-helper-java</artifactId>
<version>${api-helper-java-library.version}</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</exclusion>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.docker-java</groupId>
<artifactId>docker-java-api</artifactId>
<version>${docker-java-api.version}</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>tools.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import tools.jackson.databind.ObjectMapper;

import uk.gov.companieshouse.api.exception.InternalServiceException;

@ReadingConverter
public class ReadConverter<T> implements Converter<Document, T> {
Expand All @@ -22,10 +20,6 @@ public ReadConverter(ObjectMapper objectMapper, Class<T> objectClass) {

@Override
public T convert(Document source) {
try {
return this.objectMapper.readValue(source.toJson(), objectClass);
} catch (JsonProcessingException e) {
throw new InternalServiceException("failed to read and convert Document to JSON", e);
}
return this.objectMapper.readValue(source.toJson(), objectClass);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package uk.gov.companieshouse.api.converter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import tools.jackson.databind.ObjectMapper;
import com.mongodb.BasicDBObject;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.WritingConverter;
Expand All @@ -21,10 +20,6 @@ public WriteConverter(ObjectMapper objectMapper) {
*/
@Override
public BasicDBObject convert(S source) {
try {
return BasicDBObject.parse(objectMapper.writeValueAsString(source));
} catch (JsonProcessingException e) {
throw new IllegalArgumentException(e);
}
return BasicDBObject.parse(objectMapper.writeValueAsString(source));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,9 @@ public void setKind(TransactionKind kind) {

@Override
public boolean equals(Object obj) {
if (!(obj instanceof TransactionKindResult)) {
if (!(obj instanceof TransactionKindResult cmp)) {
return false;
}
TransactionKindResult cmp = (TransactionKindResult) obj;

final boolean sameKind = (this.kind == null && cmp.kind == null) ||
(this.kind != null && this.kind.equals(cmp.kind));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,49 @@
package uk.gov.companieshouse.api.serialization;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import tools.jackson.core.JsonParser;
import tools.jackson.databind.DeserializationContext;
import tools.jackson.databind.ValueDeserializer;
import tools.jackson.databind.JsonNode;
import java.time.ZoneOffset;
import uk.gov.companieshouse.api.exception.BadRequestException;

import java.time.Instant;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class LocalDateDeserializer extends JsonDeserializer<LocalDate> {
public class LocalDateDeserializer extends ValueDeserializer<LocalDate> {
@Override
public LocalDate deserialize(JsonParser jsonParser, DeserializationContext
deserializationContext) {
public LocalDate deserialize(JsonParser jsonParser,
DeserializationContext deserializationContext) {
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'");
JsonNode dateNode;
try {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter
.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'");
JsonNode jsonNode = jsonParser.readValueAsTree();
JsonNode dateNode = jsonNode.get("$date");
dateNode = ((JsonNode) jsonParser.readValueAsTree()).get("$date");
} catch (Exception e) {
throw new BadRequestException("Deserialization failed.", e);
}

return dateNode.textValue() != null ?
LocalDate.parse(dateNode.textValue(), dateTimeFormatter) :
Instant.ofEpochMilli(dateNode.get("$numberLong").asLong())
.atZone(ZoneOffset.UTC).toLocalDate();
if (dateNode == null || dateNode.isNull()) {
throw new BadRequestException("$date field is missing or null");
}

} catch (Exception exception) {
throw new BadRequestException("Deserialization failed.", exception);
if (dateNode.isString()) {
try {
return LocalDate.parse(dateNode.stringValue(), fmt);
} catch (Exception e) {
throw new BadRequestException("Deserialization failed.", e);
}
}
}

}
if (dateNode.isObject() && dateNode.has("$numberLong")) {
try {
return Instant.ofEpochMilli(Long.parseLong(dateNode.get("$numberLong").stringValue()))
.atZone(ZoneOffset.UTC)
.toLocalDate();
} catch (Exception e) {
throw new BadRequestException("Deserialization failed.", e);
}
}

throw new BadRequestException("Unrecognized $date format");
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
package uk.gov.companieshouse.api.serialization;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import tools.jackson.databind.ValueSerializer;
import tools.jackson.databind.SerializationContext;
import tools.jackson.core.JsonGenerator;

import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class LocalDateSerializer extends JsonSerializer<LocalDate> {

public class LocalDateSerializer extends ValueSerializer<LocalDate> {
@Override
public void serialize(LocalDate localDate, JsonGenerator jsonGenerator,
SerializerProvider serializerProvider) throws IOException {
if (localDate == null) {
jsonGenerator.writeNull();
public void serialize(LocalDate value, JsonGenerator gen, SerializationContext ctxt) {
if (value == null) {
gen.writeNull();
} else {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
String format = localDate.atStartOfDay().format(dtf);
jsonGenerator.writeRawValue("ISODate(\"" + format + "\")");
String format = value.atStartOfDay().format(dtf);
gen.writeRawValue("ISODate(\"" + format + "\")");
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package uk.gov.companieshouse.api.converter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import tools.jackson.core.JacksonException;
import org.bson.Document;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import uk.gov.companieshouse.api.exception.InternalServiceException;
import tools.jackson.databind.ObjectMapper;
import uk.gov.companieshouse.api.psc.Statement;
import uk.gov.companieshouse.api.utils.TestHelper;

Expand All @@ -35,19 +34,19 @@ void correctlyConvertsDocumentToStatementObject(){
}

@Test
void testConvertThrowsInternalServiceExceptionOnJsonError() throws Exception {
void testConvertThrowsInternalServiceExceptionOnJsonError() {
// GIVEN
ObjectMapper objectMapper = mock(ObjectMapper.class);
Document source = new Document();
when(objectMapper.readValue(anyString(), ArgumentMatchers.<Class<Object>>any()))
.thenThrow(new JsonProcessingException("Error") {});
.thenThrow(new JacksonException("Error") {});

// WHEN
ReadConverter<Statement> converter = new ReadConverter<>(objectMapper, Statement.class);

// THEN
Exception ex = Assertions.assertThrows(InternalServiceException.class, () -> converter.convert(source));
Assertions.assertEquals("failed to read and convert Document to JSON", ex.getMessage());
Exception ex = Assertions.assertThrows(JacksonException.class, () -> converter.convert(source));
Assertions.assertEquals("Error", ex.getMessage());

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import com.fasterxml.jackson.databind.ObjectMapper;
import tools.jackson.databind.ObjectMapper;
import com.mongodb.BasicDBObject;

import uk.gov.companieshouse.api.psc.Statement;
Expand Down
Loading