Skip to content

Commit 825ebb5

Browse files
authored
Merge pull request #5 from companieshouse/PCI-655-checkout-collection
Pci 655 checkout collection
2 parents 654c13a + d3c9d4e commit 825ebb5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1670
-74
lines changed

pom.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,22 @@
2424
<mockito-junit-jupiter-version>2.18.0</mockito-junit-jupiter-version>
2525
<hamcrest-all-version>1.3</hamcrest-all-version>
2626
<start-class>uk.gov.companieshouse.orders.api.OrdersApiApplication</start-class>
27+
<private-api-sdk-java.version>2.0.20</private-api-sdk-java.version>
28+
<api-sdk-manager-java-library.version>1.0.2</api-sdk-manager-java-library.version>
29+
<api-sdk-java.version>4.1.48</api-sdk-java.version>
2730
</properties>
2831

2932
<dependencies>
33+
<dependency>
34+
<groupId>uk.gov.companieshouse</groupId>
35+
<artifactId>private-api-sdk-java</artifactId>
36+
<version>${private-api-sdk-java.version}</version>
37+
</dependency>
38+
<dependency>
39+
<groupId>uk.gov.companieshouse</groupId>
40+
<artifactId>api-sdk-java</artifactId>
41+
<version>${api-sdk-java.version}</version>
42+
</dependency>
3043
<dependency>
3144
<groupId>org.springframework.boot</groupId>
3245
<artifactId>spring-boot-starter-data-mongodb</artifactId>
@@ -97,6 +110,11 @@
97110
<artifactId>de.flapdoodle.embed.mongo</artifactId>
98111
<scope>test</scope>
99112
</dependency>
113+
<dependency>
114+
<groupId>uk.gov.companieshouse</groupId>
115+
<artifactId>api-sdk-manager-java-library</artifactId>
116+
<version>${api-sdk-manager-java-library.version}</version>
117+
</dependency>
100118
</dependencies>
101119

102120
<build>

routes.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ app_name: orders.api.ch.gov.uk
22
group: api
33
weight: 991
44
routes:
5-
1: ^/basket/items
5+
1: ^/basket/*
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package uk.gov.companieshouse.orders.api.client;
2+
3+
import org.springframework.stereotype.Component;
4+
import uk.gov.companieshouse.api.InternalApiClient;
5+
import uk.gov.companieshouse.sdk.manager.ApiSdkManager;
6+
7+
@Component
8+
public class ApiClient {
9+
10+
public InternalApiClient getInternalApiClient() {
11+
return ApiSdkManager.getPrivateSDK();
12+
}
13+
14+
}

src/main/java/uk/gov/companieshouse/orders/api/config/MongoConfig.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,19 @@
22

33
import org.springframework.context.annotation.Bean;
44
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.core.convert.converter.ConverterFactory;
56
import org.springframework.data.mongodb.MongoDbFactory;
67
import org.springframework.data.mongodb.core.convert.DbRefResolver;
78
import org.springframework.data.mongodb.core.convert.DefaultDbRefResolver;
89
import org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper;
910
import org.springframework.data.mongodb.core.convert.MappingMongoConverter;
11+
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
1012
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
13+
import uk.gov.companieshouse.orders.api.converter.EnumToStringConverterFactory;
14+
import uk.gov.companieshouse.orders.api.converter.StringToEnumConverterFactory;
15+
16+
import java.util.ArrayList;
17+
import java.util.List;
1118

1219
@Configuration
1320
public class MongoConfig {
@@ -28,6 +35,11 @@ public MappingMongoConverter mappingMongoConverter(final MongoDbFactory factory,
2835
// Don't save _class to mongo
2936
mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
3037

38+
final List<ConverterFactory<?, ?>> converters = new ArrayList<>();
39+
converters.add(new StringToEnumConverterFactory());
40+
converters.add(new EnumToStringConverterFactory());
41+
mappingConverter.setCustomConversions(new MongoCustomConversions(converters));
42+
3143
return mappingConverter;
3244
}
3345
}

src/main/java/uk/gov/companieshouse/orders/api/controller/BasketController.java

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,35 @@
22

33
import org.springframework.http.HttpStatus;
44
import org.springframework.http.ResponseEntity;
5-
import org.springframework.web.bind.annotation.*;
5+
import org.springframework.web.bind.annotation.PostMapping;
6+
import org.springframework.web.bind.annotation.RequestBody;
7+
import org.springframework.web.bind.annotation.RequestHeader;
8+
import org.springframework.web.bind.annotation.RestController;
9+
import uk.gov.companieshouse.logging.Logger;
10+
import uk.gov.companieshouse.logging.LoggerFactory;
611
import uk.gov.companieshouse.orders.api.dto.AddToBasketRequestDTO;
712
import uk.gov.companieshouse.orders.api.dto.AddToBasketResponseDTO;
13+
import uk.gov.companieshouse.orders.api.exception.ConflictException;
814
import uk.gov.companieshouse.orders.api.mapper.BasketMapper;
15+
import uk.gov.companieshouse.orders.api.model.ApiError;
916
import uk.gov.companieshouse.orders.api.model.Basket;
10-
11-
import uk.gov.companieshouse.logging.Logger;
12-
import uk.gov.companieshouse.logging.LoggerFactory;
17+
import uk.gov.companieshouse.orders.api.model.Checkout;
18+
import uk.gov.companieshouse.orders.api.model.Item;
19+
import uk.gov.companieshouse.orders.api.service.ApiClientService;
1320
import uk.gov.companieshouse.orders.api.service.BasketService;
21+
import uk.gov.companieshouse.orders.api.service.CheckoutService;
1422
import uk.gov.companieshouse.orders.api.util.EricHeaderHelper;
23+
import uk.gov.companieshouse.orders.api.validator.CheckoutBasketValidator;
1524

1625
import javax.servlet.http.HttpServletRequest;
1726
import javax.validation.Valid;
1827
import java.util.HashMap;
28+
import java.util.List;
1929
import java.util.Map;
2030
import java.util.Optional;
2131

32+
import static org.springframework.http.HttpStatus.BAD_REQUEST;
33+
import static org.springframework.http.HttpStatus.CONFLICT;
2234
import static uk.gov.companieshouse.orders.api.OrdersApiApplication.APPLICATION_NAMESPACE;
2335

2436
@RestController
@@ -30,10 +42,20 @@ public class BasketController {
3042

3143
private final BasketMapper mapper;
3244
private final BasketService basketService;
45+
private final CheckoutService checkoutService;
46+
private final CheckoutBasketValidator checkoutBasketValidator;
47+
private final ApiClientService apiClientService;
3348

34-
public BasketController(final BasketMapper mapper, final BasketService basketService){
49+
public BasketController(final BasketMapper mapper,
50+
final BasketService basketService,
51+
final CheckoutService checkoutService,
52+
final CheckoutBasketValidator checkoutBasketValidator,
53+
final ApiClientService apiClientService){
3554
this.mapper = mapper;
3655
this.basketService = basketService;
56+
this.checkoutService = checkoutService;
57+
this.checkoutBasketValidator = checkoutBasketValidator;
58+
this.apiClientService = apiClientService;
3759
}
3860

3961
@PostMapping("${uk.gov.companieshouse.orders.api.basket.items}")
@@ -60,6 +82,35 @@ public ResponseEntity<AddToBasketResponseDTO> addItemToBasket(final @Valid @Requ
6082
return ResponseEntity.status(HttpStatus.OK).body(addToBasketResponseDTO);
6183
}
6284

85+
@PostMapping("${uk.gov.companieshouse.orders.api.basket.checkout}")
86+
public ResponseEntity<?> checkoutBasket(HttpServletRequest request,
87+
final @RequestHeader(REQUEST_ID_HEADER_NAME) String requestId) {
88+
trace("Entering checkoutBasket", requestId);
89+
90+
final Basket retrievedBasket = basketService.getBasketById(EricHeaderHelper.getIdentity(request))
91+
.orElseThrow(ConflictException::new);
92+
93+
final List<String> errors = checkoutBasketValidator.getValidationErrors(retrievedBasket);
94+
if (!errors.isEmpty()) {
95+
return ResponseEntity.status(CONFLICT).body(new ApiError(CONFLICT, errors));
96+
}
97+
98+
Item item;
99+
String itemUri = null;
100+
try {
101+
itemUri = retrievedBasket.getData().getItems().get(0).getItemUri();
102+
item = apiClientService.getItem(itemUri);
103+
} catch (Exception exception) {
104+
LOGGER.error("Failed to get item "+itemUri, exception);
105+
return ResponseEntity.status(BAD_REQUEST).body(new ApiError(BAD_REQUEST, "Failed to retrieve item"));
106+
}
107+
108+
Checkout checkout = checkoutService.createCheckout(item);
109+
trace("Successfully created checkout with id "+checkout.getId(), requestId);
110+
111+
return ResponseEntity.status(HttpStatus.OK).body(null);
112+
}
113+
63114
/**
64115
* Utility method that logs each message with the request ID for log tracing/analysis.
65116
* @param message the message to log
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package uk.gov.companieshouse.orders.api.converter;
2+
3+
import org.springframework.core.convert.converter.Converter;
4+
import org.springframework.core.convert.converter.ConverterFactory;
5+
import org.springframework.data.convert.WritingConverter;
6+
7+
import static uk.gov.companieshouse.orders.api.converter.EnumValueNameConverter.convertEnumValueNameToJson;
8+
9+
@WritingConverter
10+
public final class EnumToStringConverterFactory implements ConverterFactory<Enum, String> {
11+
12+
@Override
13+
public <T extends String> Converter<Enum, T> getConverter(Class<T> targetType) {
14+
return new EnumToStringConverter(targetType);
15+
}
16+
17+
private final class EnumToStringConverter<T extends Enum> implements Converter<T, String> {
18+
19+
private Class<T> enumType;
20+
21+
public EnumToStringConverter(Class<T> enumType) {
22+
this.enumType = enumType;
23+
}
24+
25+
public String convert(T source) {
26+
return convertEnumValueNameToJson(source);
27+
}
28+
}
29+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package uk.gov.companieshouse.orders.api.converter;
2+
3+
public class EnumValueNameConverter {
4+
5+
private EnumValueNameConverter() { }
6+
7+
public static String convertEnumValueJsonToName(final String enumValueJson) {
8+
return enumValueJson.toUpperCase().replace("-", "_");
9+
}
10+
11+
public static String convertEnumValueNameToJson(final Enum value) {
12+
return value.name().toLowerCase().replace("_", "-");
13+
}
14+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package uk.gov.companieshouse.orders.api.converter;
2+
3+
import org.springframework.core.convert.converter.Converter;
4+
import org.springframework.core.convert.converter.ConverterFactory;
5+
import org.springframework.data.convert.ReadingConverter;
6+
7+
@ReadingConverter
8+
public final class StringToEnumConverterFactory implements ConverterFactory<String, Enum> {
9+
10+
public <T extends Enum> Converter<String, T> getConverter(Class<T> targetType) {
11+
return new StringToEnumConverter(targetType);
12+
}
13+
14+
private final class StringToEnumConverter<T extends Enum> implements Converter<String, T> {
15+
16+
private Class<T> enumType;
17+
18+
public StringToEnumConverter(Class<T> enumType) {
19+
this.enumType = enumType;
20+
}
21+
22+
public T convert(String source) {
23+
return (T) Enum.valueOf(this.enumType, source.trim());
24+
}
25+
}
26+
}

src/main/java/uk/gov/companieshouse/orders/api/dto/AddToBasketRequestDTO.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
package uk.gov.companieshouse.orders.api.dto;
22

3-
import com.fasterxml.jackson.annotation.JsonInclude;
43
import com.fasterxml.jackson.annotation.JsonProperty;
54
import com.google.gson.Gson;
65

76
import javax.validation.constraints.NotBlank;
8-
import javax.validation.constraints.NotNull;
97

108
public class AddToBasketRequestDTO {
119

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package uk.gov.companieshouse.orders.api.exception;
2+
3+
import org.springframework.http.HttpStatus;
4+
import org.springframework.web.bind.annotation.ResponseStatus;
5+
6+
@ResponseStatus(HttpStatus.CONFLICT)
7+
public class ConflictException extends RuntimeException {
8+
9+
public ConflictException() {
10+
this("Conflict");
11+
}
12+
13+
public ConflictException(String message) {
14+
this(message, (Throwable)null);
15+
}
16+
17+
public ConflictException(String message, Throwable cause) {
18+
super(message, cause);
19+
}
20+
}

0 commit comments

Comments
 (0)