Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/denis256/trade-validator

Trades validation service
https://github.com/denis256/trade-validator

java java8 spring spring-boot

Last synced: 27 days ago
JSON representation

Trades validation service

Awesome Lists containing this project

README

        

Trade validation service
========================

Service which checks trade details

Service is based on Gradle, Spring 4.3.3 and Spring Boot 1.4.1

Service built from modules which implement separated functionality.

- trade-validator-model : model classes for trade, validation errors

- trade-validator-api : API interfaces to add new things into validation service

- trade-validator-core : core services for trade validation

- trade-validator-app : REST interface for validating trades

- trade-validators : implementation of trade validation business rules

Each validation rule should implement `TradeValidator` interface and be a spring managed bean, during startup Spring will inject available validators into `ValidationCore`.
REST API controllers calls `ValidationCore` for validate trodes and return results.

Validators from `trade-validators` have pre-defined, hardcoded settings, can load configurations from spring configurations and also expose JMX managed beans which allow settings change on runtime.

API endpoints
=============

`/api/validate` - validate single trade, as result is returned trade and list of invalid fields

`/api/validateBulk` - bulk validate of a trade list, as result is returned list of trades and each trade have list of errors

`/api/shutdown` - shutdown endpoint, `GET` request to fetch status, `POST` to shutdown service. Shutdown can be canceled by sending `DELETE` on shutdown API.
Shutdown status is also available through default `/info` endpoint. When shutdown status is set, service no more accept trades for validation.

`/metrics` - fetch application metrics

`/swagger-ui.html#/validation-controller` - swagger Rest API documentation

Example API calls
=================

**Validate single trade**

Request

`curl -v -H "Content-Type: application/json" -X POST --data "@./raw_trades/single_trade.json" localhost:8080/api/validate`

Response

```
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> POST /api/validate HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:8080
> Accept: */*
> Content-Type: application/json
> Content-Length: 232
>
* upload completely sent off: 232 out of 232 bytes
< HTTP/1.1 200
< X-Application-Context: application
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Sun, 09 Oct 2016 09:40:17 GMT
<
* Connection #0 to host localhost left intact
{"trade":{"tradeDate":"2016-08-11","valueDate":"2016-08-15","customer":"PLUTO1","ccyPair":"EURUSD","type":"Spot","style":null,"excerciseStartDate":null,"expiryDate":null,"premiumDate":null,"deliveryDate":null,"legalEntity":"CS Zurich"},"invalidFields":{"valueDate":["On spot trades valueDate should be +2 days from today date"]},"haveErrors":true}
```
**Bulk trades validation**

Request

`curl -v -H "Content-Type: application/json" -X POST --data "@./raw_trades/bulk_trades.json" localhost:8080/api/validateBulk`

Response

```
curl -v -H "Content-Type: application/json" -X POST --data "@./raw_trades/bulk_trades.json" localhost:8080/api/validateBulk
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> POST /api/validateBulk HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:8080
> Accept: */*
> Content-Type: application/json
> Content-Length: 5089
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
< HTTP/1.1 200
< X-Application-Context: application
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Sun, 09 Oct 2016 09:43:29 GMT
<
[{"trade":{"tradeDate":"2016-08-11","valueDate":"2016-08-15","customer":"PLUTO1","ccyPair":"EURUSD","type":"Spot","style":null,"excerciseStartDate":null,"expiryDate":null,"premiumDate":null,"deliveryDate":null,"legalEntity":"CS Zurich"},"invalidFields":{"valueDate":["On spot trades valueDate should be +2 days from today date"]},"haveErrors":true},{"trade":{"tradeDate":"2016-08-11","valueDate":"2016-08-22","customer":"PLUTO1","ccyPair":"EURUSD","type":"Spot","style":null,"excerciseStartDate":null,"expiryDate":null,"premiumDate":null,"deliveryDate":null,"legalEntity":"CS Zurich"},"invalidFields":{"valueDate":["On spot trades valueDate should be +2 days from today date"]},"haveErrors":true},{"trade":{"tradeDate":"2016-08-11","valueDate":"2016-08-22","customer":"PLUTO2","ccyPair":"EURUSD","type":"Forward","style":null,"excerciseStartDate":null,"expiryDate":null,"premiumDate":null,"deliveryDate":null,"legalEntity":"CS Zurich"},"invalidFields":{"valueDate":["On forward trades valueDate should be more than 2 days"]},"haveErrors":true},{"trade":{"tradeDate":"2016-08-11","valueDate":"2016-08-21","customer":"PLUTO2","ccyPair":"EURUSD","type":"Forward","style":null,"excerciseStartDate":null,"expiryDate":null,"premiumDate":null,"deliveryDate":null,"legalEntity":"CS Zurich"},"invalidFields":{"valueDate":["On forward trades valueDate should be more than 2 days","valueDate is holiday date"]},"haveErrors":true},{"trade":{"tradeDate":"2016-08-11","valueDate":"2016-08-08","customer":"PLUTO2","ccyPair":"EURUSD","type":"Forward","style":null,"excerciseStartDate":null,"expiryDate":null,"premiumDate":null,"deliveryDate":null,"legalEntity":"CS Zurich"},"invalidFields":{"valueDate":["On forward trades valueDate should be more than 2 days","Value date cannot be before Trade date"]},"haveErrors":true},{"trade":{"tradeDate":"2016-08-11","valueDate":"2016-08-08","customer":"PLUT02","ccyPair":"EURUSD","type":"Forward","style":null,"excerciseStartDate":null,"expiryDate":null,"premiumDate":null,"deliveryDate":null,"legalEntity":"CS Zurich"},"invalidFields":{"valueDate":["On forward trades valueDate should be more than 2 days","Value date cannot be before Trade date"],"customer":["Customer is not in approved list"]},"haveErrors":true},{"trade":{"tradeDate":"2016-08-11","valueDate":"2016-08-22","customer":"PLUTO3","ccyPair":"EURUSD","type":"Forward","style":null,"excerciseStartDate":null,"expiryDate":null,"premiumDate":null,"deliveryDate":null,"legalEntity":"CS Zurich"},"invalidFields":{"valueDate":["On forward trades valueDate should be more than 2 days"],"customer":["Customer is not in approved list"]},"haveErrors":true},{"trade":{"tradeDate":"2016-08-11","valueDate":null,"customer":"PLUTO1","ccyPair":"EURUSD","type":"VanillaOption","style":"EUROPEAN","excerciseStartDate":null,"expiryDate":"2016-08-19","premiumDate":"2016-08-12","deliveryDate":"2016-08-22","legalEntity":"CS Zurich"},"invalidFields":{"valueDate":["valueDate is missing"]},"haveErrors":true},{"trade":{"tradeDate":"2016-08-11","valueDate":null,"customer":"PLUTO2","ccyPair":"EURUSD","type":"VanillaOption","style":"EUROPEAN","excerciseStartDate":null,"expiryDate":"2016-08-21","premiumDate":"2016-08-12","deliveryDate":"2016-08-22","legalEntity":"CS Zurich"},"invalidFields":{"valueDate":["valueDate is missing"]},"haveErrors":true},{"trade":{"tradeDate":"2016-08-11","valueDate":null,"customer":"PLUTO1","ccyPair":"EURUSD","type":"VanillaOption","style":"EUROPEAN","excerciseStartDate":null,"expiryDate":"2016-08-25","premiumDate":"2016-08-12","deliveryDate":"2016-08-22","legalEntity":"CS Zurich"},"invalidFields":{"expiryDate":["expiry date should be before delivery date"],"valueDate":["valueDate is missing"]},"haveErrors":true},{"trade":{"tradeDate":"2016-08-11","valueDate":null,"customer":"PLUTO1","ccyPair":"EURUSD","type":"VanillaOption","style":"AMERICAN","excerciseStartDate":"2016-08-12","expiryDate":"2016-08-19","premiumDate":"2016-08-12","deliveryDate":"2016-08-22","legalEntity":"CS Zurich"},"invalidFields":{"valueDate":["valueDate is missing"]},"haveErrors":true},{"trade":{"tradeDate":"2016-08-11","valueDate":null,"customer":"PLUTO2","ccyPair":"EURUSD","type":"VanillaOption","style":"AMERICAN","excerciseStartDate":"2016-08-12","expiryDate":"2016-08-21","premiumDate":"2016-08-12","deliveryDate":"2016-08-22","legalEntity":"CS Zurich"},"invalidFields":{"valueDate":["valueDate is missing"]},"haveErrors":true},{"trade":{"tradeDate":"2016-08-11","valueDate":null,"customer":"PLUTO1","ccyPair":"EURUSD","type":"VanillaOption","style":"AMERICAN","excerciseStartDate":"2016-08-12","expiryDate":"2016-08-25","premiumDate":"2016-08-12","deliveryDate":"2016-08-22","legalEntity":"CS Zurich"},"invalidFields":{"expiryDate":["expiry date should be before delivery date"],"valueDate":["valueDate is missing"]},"haveErrors":true},{"trade":{"tradeDate":"2016-08-11","valueDate":null,"customer":"PLUTO1","ccyPair":"EURUSD","type":"VanillaOption","style":"AMERICAN","excerciseStartDate":"2016-08-10","expiryDate":"2016-08-19","premiumDate":"2016-08-12","deliveryDate":"2016-08-22","legalEntity":"CS Zurich"},"invalidFields":{* Connection #0 to host localhost left intact
"excerciseStartDate":["excerciseStartDate should be after trade date"],"valueDate":["valueDate is missing"]},"haveErrors":true},{"trade":{"tradeDate":"2016-08-11","valueDate":null,"customer":"PLUTO3","ccyPair":"EURUSD","type":"VanillaOption","style":"AMERICAN","excerciseStartDate":"2016-08-10","expiryDate":"2016-08-19","premiumDate":"2016-08-12","deliveryDate":"2016-08-22","legalEntity":"CS Zurich"},"invalidFields":{"excerciseStartDate":["excerciseStartDate should be after trade date"],"valueDate":["valueDate is missing"],"customer":["Customer is not in approved list"]},"haveErrors":true}]
```

**Fetch shutdown status**

Request
`curl http://localhost:8080/api/shutdown`

Response
```
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /api/shutdown HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 200
< X-Application-Context: application
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Sun, 09 Oct 2016 09:45:08 GMT
<
* Connection #0 to host localhost left intact
false⏎
```

**Set shutdown flag**

Request
`curl -v -X POST http://localhost:8080/api/shutdown`

Response
```
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> POST /api/shutdown HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:8080
> Accept: */*
>
< HTTP/1.1 200
< X-Application-Context: application
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Sun, 09 Oct 2016 09:46:29 GMT
<
* Connection #0 to host localhost left intact
true⏎
```