Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
32bf461026 | |||
560f1ff34b | |||
|
ec26b84dc9 | ||
|
0b89e88905 | ||
|
9f42fcfcc4 | ||
|
96e323a705 | ||
|
de2f6cf0c4 | ||
67a952003d |
@@ -0,0 +1,21 @@
|
|||||||
|
# 2. Seperate service for Executor Pool
|
||||||
|
|
||||||
|
Date: 2021-11-21
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
The Executor Pool has to keep track of which Executors are online and what task types they can execute. The Roster keeps track of tasks that need to be executed and assigns Executors to tasks. The Executor Pool functionalty could be implemented in a seperate service or as a part of the Roster.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
The executor pool will be implemented as a seperate service. (TODO decision might change. Need to reevaluate)
|
||||||
|
|
||||||
|
TODO explain why.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
TODO
|
@@ -1,23 +0,0 @@
|
|||||||
# 2. Seperate service for Executors and Executor Pool
|
|
||||||
|
|
||||||
Date: 2021-11-21
|
|
||||||
|
|
||||||
## Status
|
|
||||||
|
|
||||||
Accepted
|
|
||||||
|
|
||||||
## Context
|
|
||||||
|
|
||||||
The executor pool has a complete list of all executors and knows if they are available or not, executors can execute tasks that match their type. The executors can therefore be part of the executor pool service, or each executor is a standalone service, as well as the executor pool.
|
|
||||||
|
|
||||||
## Decision
|
|
||||||
|
|
||||||
We will use a separate microservice for each executor and one service for the executor pool.
|
|
||||||
Having the executor pool and the executors as separate services would increase fault tolerance. If the executor pool goes down, the executors would stay online and execute their tasks without being affected by the executor pool’s outage. Likewise, if an executor goes down it does not impact other executors or the executor pool.
|
|
||||||
Different executors can have different execution times and a different load. This means the executors scale differently. Thus, we need a separate service for each executor.
|
|
||||||
Executors of different kinds will also scale differently than the executor pool and new executors of new types might be added at some point, further increasing the need for separate services to guarantee scalability and evolvability.
|
|
||||||
New executors will be added/removed during runtime. Therefore, we need a high extensibility.
|
|
||||||
|
|
||||||
## Consequences
|
|
||||||
|
|
||||||
Executors will be added/removed quite frequently, making the deployment of the system easier and less risk-prone if each executor is a separate service, also separated from the executor pool, which just keeps track of the executors and their status. However, having these separate services, the complexity might increase, and the testability of the system will decrease.
|
|
@@ -6,7 +6,7 @@ Date: 2021-11-21
|
|||||||
|
|
||||||
Proposed
|
Proposed
|
||||||
|
|
||||||
Supercedes [5. Event driven communication](0005-event-driven-communication.md)
|
Supercedes [5. Event driven communication](0005-event-driven-communication.md) TODO Fix this. Should only supercede it if this has been accepted. This should also subercede 0013 - Microservice Architecture if accepted.
|
||||||
|
|
||||||
## Context
|
## Context
|
||||||
|
|
||||||
|
@@ -0,0 +1,27 @@
|
|||||||
|
# 12. seperate service for each executor
|
||||||
|
|
||||||
|
Date: 2021-11-21
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
Executors must receive tasks of different types and execute them. The executors could either all be implemented within one service or as multiple services, one for each type of executor.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
We will have a seperate service for each type of executor.
|
||||||
|
|
||||||
|
Firstly, execution time differs significantly between task types. Therefore, having seperate services will allow the executos to scale differently based on their tasks' specific needs.
|
||||||
|
|
||||||
|
Secondly, the systems functioning should not be disrupted in case an Executor fails. Having each type of executor in a seperate service will increase fault tolerance in this regard.
|
||||||
|
|
||||||
|
Lastly, extensibilty is one of the systems most important non-functional requirement and providers of executors need to be able to easily add executors to the executor pool. These factors are also positively impacted by having seperate services.
|
||||||
|
|
||||||
|
There should not be any shared data between the executors. Additionally, there should be no flow of information between them. Thus, there should be no issues due to workflow and data concerns due to this decision.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
Executors share a lot of functionality when it comes to connecting to the rest of the system. Therefore, this decision means that we will either have to duplicate the code that implements the common functionality, or we have to have a way to share the code (e.g. through a common library)
|
23
doc/architecture/decisions/0013-microservice-architecture.md
Normal file
23
doc/architecture/decisions/0013-microservice-architecture.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# 13. microservice architecture
|
||||||
|
|
||||||
|
Date: 2021-12-02
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
The system is made up of five distinct bounded contexts, namely the Task Domain, the Roster Domain, the Executor Pool Domain, the Executor Domain, and the Auction Domain. The way that these bounded contexts function together to fulfil the system requirements can be based on many different architectures. (Feedback needed. Should we name specific 'next-best' alternative architectures to compare, or just leave it as is since technically all architectures were considered)
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
The system will follow the Microservice architecture.
|
||||||
|
|
||||||
|
Scalability and fault tolerance are two of the systems top 3 -ilities. Moreover, elasticity and evolvability are two of the systems other main -ilities. These are all non-functional requirements that the Microservice architecture excels at.
|
||||||
|
|
||||||
|
We do not expect to have a single monolithic database, so this is not a concern.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
There is a considerable amount of communication between bounded contexts. This could cause responsiveness and performance issues due to added latency. This could therefore mean we would need to use asynchronous REST calls or publish-subscribe communication to mitigate these issues as much of the communication does not have to be synchronous.
|
19
doc/architecture/decisions/0014-data-ownership.md
Normal file
19
doc/architecture/decisions/0014-data-ownership.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# 14. data ownership
|
||||||
|
|
||||||
|
Date: 2021-12-02
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
Accepted
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
The issue motivating this decision, and any context that influences or constrains the decision.
|
||||||
|
|
||||||
|
## Decision
|
||||||
|
|
||||||
|
The change that we're proposing or have agreed to implement.
|
||||||
|
|
||||||
|
## Consequences
|
||||||
|
|
||||||
|
What becomes easier or more difficult to do and any risks introduced by the change that will need to be mitigated.
|
File diff suppressed because it is too large
Load Diff
BIN
doc/workflow.png
BIN
doc/workflow.png
Binary file not shown.
Before Width: | Height: | Size: 817 KiB After Width: | Height: | Size: 2.0 MiB |
1
mocks/.gitignore
vendored
Normal file
1
mocks/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
node_modules/
|
35
mocks/auction-house/discoveryEndpoin2.js
Normal file
35
mocks/auction-house/discoveryEndpoin2.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
// Require the framework and instantiate it
|
||||||
|
const fastify = require("fastify")({ logger: true });
|
||||||
|
|
||||||
|
// Declare a route
|
||||||
|
fastify.get("/discovery/", async (request, reply) => {
|
||||||
|
return {
|
||||||
|
auctionHouseInfo: [
|
||||||
|
{
|
||||||
|
auctionHouseURI: "http://localhost:3501",
|
||||||
|
webSubURI: "http://example.org",
|
||||||
|
taskTypes: ["COMPUTATION", "RANDOMTEXT"],
|
||||||
|
timeStamp: "2021-12-24 12:00:00",
|
||||||
|
groupName: "Group3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
auctionHouseURI: "http://localhost:3502",
|
||||||
|
webSubURI: "http://facemash.com",
|
||||||
|
taskTypes: ["BIGROBOT"],
|
||||||
|
timeStamp: "2021-12-24 12:00:00",
|
||||||
|
groupName: "Group2",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Run the server!
|
||||||
|
const start = async () => {
|
||||||
|
try {
|
||||||
|
await fastify.listen(3501);
|
||||||
|
} catch (err) {
|
||||||
|
fastify.log.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
start();
|
35
mocks/auction-house/discoveryEndpoin3.js
Normal file
35
mocks/auction-house/discoveryEndpoin3.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
// Require the framework and instantiate it
|
||||||
|
const fastify = require("fastify")({ logger: true });
|
||||||
|
|
||||||
|
// Declare a route
|
||||||
|
fastify.get("/discovery/", async (request, reply) => {
|
||||||
|
return {
|
||||||
|
auctionHouseInfo: [
|
||||||
|
{
|
||||||
|
auctionHouseURI: "http://localhost:3502",
|
||||||
|
webSubURI: "http://example.org",
|
||||||
|
taskTypes: ["COMPUTATION", "RANDOMTEXT"],
|
||||||
|
timeStamp: "2021-12-24 12:00:00",
|
||||||
|
groupName: "Group3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
auctionHouseURI: "http://localhost:3501",
|
||||||
|
webSubURI: "http://facemash.com",
|
||||||
|
taskTypes: ["BIGROBOT"],
|
||||||
|
timeStamp: "2021-12-26 12:00:00",
|
||||||
|
groupName: "GroupHAHAHA222",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Run the server!
|
||||||
|
const start = async () => {
|
||||||
|
try {
|
||||||
|
await fastify.listen(3502);
|
||||||
|
} catch (err) {
|
||||||
|
fastify.log.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
start();
|
35
mocks/auction-house/discoveryEndpoint.js
Normal file
35
mocks/auction-house/discoveryEndpoint.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
// Require the framework and instantiate it
|
||||||
|
const fastify = require("fastify")({ logger: true });
|
||||||
|
|
||||||
|
// Declare a route
|
||||||
|
fastify.get("/discovery/", async (request, reply) => {
|
||||||
|
return {
|
||||||
|
auctionHouseInfo: [
|
||||||
|
{
|
||||||
|
auctionHouseURI: "http://localhost:3500",
|
||||||
|
webSubURI: "http://example.org",
|
||||||
|
taskTypes: ["COMPUTATION", "RANDOMTEXT"],
|
||||||
|
timeStamp: "2021-12-24 12:00:00",
|
||||||
|
groupName: "Group3",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
auctionHouseURI: "http://localhost:3501",
|
||||||
|
webSubURI: "http://facemash.com",
|
||||||
|
taskTypes: ["BIGROBOT"],
|
||||||
|
timeStamp: "2021-12-24 12:00:00",
|
||||||
|
groupName: "Group2",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// Run the server!
|
||||||
|
const start = async () => {
|
||||||
|
try {
|
||||||
|
await fastify.listen(3500);
|
||||||
|
} catch (err) {
|
||||||
|
fastify.log.error(err);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
start();
|
5
mocks/package.json
Normal file
5
mocks/package.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"dependencies": {
|
||||||
|
"fastify": "^3.24.1"
|
||||||
|
}
|
||||||
|
}
|
322
mocks/yarn.lock
Normal file
322
mocks/yarn.lock
Normal file
@@ -0,0 +1,322 @@
|
|||||||
|
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||||
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@fastify/ajv-compiler@^1.0.0":
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@fastify/ajv-compiler/-/ajv-compiler-1.1.0.tgz#5ce80b1fc8bebffc8c5ba428d5e392d0f9ed10a1"
|
||||||
|
integrity sha512-gvCOUNpXsWrIQ3A4aXCLIdblL0tDq42BG/2Xw7oxbil9h11uow10ztS2GuFazNBfjbrsZ5nl+nPl5jDSjj5TSg==
|
||||||
|
dependencies:
|
||||||
|
ajv "^6.12.6"
|
||||||
|
|
||||||
|
abstract-logging@^2.0.0:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/abstract-logging/-/abstract-logging-2.0.1.tgz#6b0c371df212db7129b57d2e7fcf282b8bf1c839"
|
||||||
|
integrity sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==
|
||||||
|
|
||||||
|
ajv@^6.11.0, ajv@^6.12.6:
|
||||||
|
version "6.12.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
|
||||||
|
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
|
||||||
|
dependencies:
|
||||||
|
fast-deep-equal "^3.1.1"
|
||||||
|
fast-json-stable-stringify "^2.0.0"
|
||||||
|
json-schema-traverse "^0.4.1"
|
||||||
|
uri-js "^4.2.2"
|
||||||
|
|
||||||
|
ajv@^8.1.0:
|
||||||
|
version "8.8.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.8.2.tgz#01b4fef2007a28bf75f0b7fc009f62679de4abbb"
|
||||||
|
integrity sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==
|
||||||
|
dependencies:
|
||||||
|
fast-deep-equal "^3.1.1"
|
||||||
|
json-schema-traverse "^1.0.0"
|
||||||
|
require-from-string "^2.0.2"
|
||||||
|
uri-js "^4.2.2"
|
||||||
|
|
||||||
|
archy@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40"
|
||||||
|
integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=
|
||||||
|
|
||||||
|
atomic-sleep@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b"
|
||||||
|
integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==
|
||||||
|
|
||||||
|
avvio@^7.1.2:
|
||||||
|
version "7.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/avvio/-/avvio-7.2.2.tgz#58e00e7968870026cd7b7d4f689d596db629e251"
|
||||||
|
integrity sha512-XW2CMCmZaCmCCsIaJaLKxAzPwF37fXi1KGxNOvedOpeisLdmxZnblGc3hpHWYnlP+KOUxZsazh43WXNHgXpbqw==
|
||||||
|
dependencies:
|
||||||
|
archy "^1.0.0"
|
||||||
|
debug "^4.0.0"
|
||||||
|
fastq "^1.6.1"
|
||||||
|
queue-microtask "^1.1.2"
|
||||||
|
|
||||||
|
cookie@^0.4.0:
|
||||||
|
version "0.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1"
|
||||||
|
integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==
|
||||||
|
|
||||||
|
debug@^4.0.0:
|
||||||
|
version "4.3.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"
|
||||||
|
integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==
|
||||||
|
dependencies:
|
||||||
|
ms "2.1.2"
|
||||||
|
|
||||||
|
deepmerge@^4.2.2:
|
||||||
|
version "4.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
|
||||||
|
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
|
||||||
|
|
||||||
|
fast-decode-uri-component@^1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/fast-decode-uri-component/-/fast-decode-uri-component-1.0.1.tgz#46f8b6c22b30ff7a81357d4f59abfae938202543"
|
||||||
|
integrity sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==
|
||||||
|
|
||||||
|
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
||||||
|
version "3.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||||
|
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||||
|
|
||||||
|
fast-json-stable-stringify@^2.0.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
|
||||||
|
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
|
||||||
|
|
||||||
|
fast-json-stringify@^2.5.2:
|
||||||
|
version "2.7.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/fast-json-stringify/-/fast-json-stringify-2.7.12.tgz#5bb7941695b52f545191bc396396230633f43592"
|
||||||
|
integrity sha512-4hjwZDPmgj/ZUKXhEWovGPciE/5mWtAIQQxN+2VBDFun7DRTk2oOItbu9ZZp6kqj+eZ/u7z+dgBgM74cfGRnBQ==
|
||||||
|
dependencies:
|
||||||
|
ajv "^6.11.0"
|
||||||
|
deepmerge "^4.2.2"
|
||||||
|
rfdc "^1.2.0"
|
||||||
|
string-similarity "^4.0.1"
|
||||||
|
|
||||||
|
fast-redact@^3.0.0:
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.0.2.tgz#c940ba7162dde3aeeefc522926ae8c5231412904"
|
||||||
|
integrity sha512-YN+CYfCVRVMUZOUPeinHNKgytM1wPI/C/UCLEi56EsY2dwwvI00kIJHJoI7pMVqGoMew8SMZ2SSfHKHULHXDsg==
|
||||||
|
|
||||||
|
fast-safe-stringify@^2.0.8:
|
||||||
|
version "2.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884"
|
||||||
|
integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==
|
||||||
|
|
||||||
|
fastify-error@^0.3.0:
|
||||||
|
version "0.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/fastify-error/-/fastify-error-0.3.1.tgz#8eb993e15e3cf57f0357fc452af9290f1c1278d2"
|
||||||
|
integrity sha512-oCfpcsDndgnDVgiI7bwFKAun2dO+4h84vBlkWsWnz/OUK9Reff5UFoFl241xTiLeHWX/vU9zkDVXqYUxjOwHcQ==
|
||||||
|
|
||||||
|
fastify-warning@^0.2.0:
|
||||||
|
version "0.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/fastify-warning/-/fastify-warning-0.2.0.tgz#e717776026a4493dc9a2befa44db6d17f618008f"
|
||||||
|
integrity sha512-s1EQguBw/9qtc1p/WTY4eq9WMRIACkj+HTcOIK1in4MV5aFaQC9ZCIt0dJ7pr5bIf4lPpHvAtP2ywpTNgs7hqw==
|
||||||
|
|
||||||
|
fastify@^3.24.1:
|
||||||
|
version "3.24.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/fastify/-/fastify-3.24.1.tgz#979d34e096f40b7a90e90733efbbdae81623034e"
|
||||||
|
integrity sha512-ZL0V6u37d65tAY8lMwVMFtFvnEeJcG80QBNSdChqCm4i4x+is/38OU14gzJuRXhpenTL+pTJzNcu5Kn1ouzM3Q==
|
||||||
|
dependencies:
|
||||||
|
"@fastify/ajv-compiler" "^1.0.0"
|
||||||
|
abstract-logging "^2.0.0"
|
||||||
|
avvio "^7.1.2"
|
||||||
|
fast-json-stringify "^2.5.2"
|
||||||
|
fastify-error "^0.3.0"
|
||||||
|
fastify-warning "^0.2.0"
|
||||||
|
find-my-way "^4.1.0"
|
||||||
|
flatstr "^1.0.12"
|
||||||
|
light-my-request "^4.2.0"
|
||||||
|
pino "^6.13.0"
|
||||||
|
proxy-addr "^2.0.7"
|
||||||
|
rfdc "^1.1.4"
|
||||||
|
secure-json-parse "^2.0.0"
|
||||||
|
semver "^7.3.2"
|
||||||
|
tiny-lru "^7.0.0"
|
||||||
|
|
||||||
|
fastq@^1.6.1:
|
||||||
|
version "1.13.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c"
|
||||||
|
integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==
|
||||||
|
dependencies:
|
||||||
|
reusify "^1.0.4"
|
||||||
|
|
||||||
|
find-my-way@^4.1.0:
|
||||||
|
version "4.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/find-my-way/-/find-my-way-4.4.0.tgz#e4a115031d1c5c538d028d06b666e2174462bc07"
|
||||||
|
integrity sha512-hpntHvK0iOHp3pqWRRUEzioar4tp8euBD8DkPG3VauOriZLgwGZLTNp6yZSrdctJ8RCDS7zhZSR2V+yOaBbNow==
|
||||||
|
dependencies:
|
||||||
|
fast-decode-uri-component "^1.0.1"
|
||||||
|
fast-deep-equal "^3.1.3"
|
||||||
|
safe-regex2 "^2.0.0"
|
||||||
|
semver-store "^0.3.0"
|
||||||
|
|
||||||
|
flatstr@^1.0.12:
|
||||||
|
version "1.0.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/flatstr/-/flatstr-1.0.12.tgz#c2ba6a08173edbb6c9640e3055b95e287ceb5931"
|
||||||
|
integrity sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw==
|
||||||
|
|
||||||
|
forwarded@0.2.0:
|
||||||
|
version "0.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
|
||||||
|
integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
|
||||||
|
|
||||||
|
ipaddr.js@1.9.1:
|
||||||
|
version "1.9.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
|
||||||
|
integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
|
||||||
|
|
||||||
|
json-schema-traverse@^0.4.1:
|
||||||
|
version "0.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
||||||
|
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
|
||||||
|
|
||||||
|
json-schema-traverse@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
|
||||||
|
integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
|
||||||
|
|
||||||
|
light-my-request@^4.2.0:
|
||||||
|
version "4.7.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/light-my-request/-/light-my-request-4.7.0.tgz#5bacd17fa0eaf96fe5eed1682c5e0d361953cf46"
|
||||||
|
integrity sha512-LTa8YZp3K2AUpqUnwwKajoIHcsKOBnzwJNQSrk7unziPwo6CjOYjyO0F9wfkxFvP+nBsCGe3eMPnedVgIIgdAw==
|
||||||
|
dependencies:
|
||||||
|
ajv "^8.1.0"
|
||||||
|
cookie "^0.4.0"
|
||||||
|
fastify-warning "^0.2.0"
|
||||||
|
set-cookie-parser "^2.4.1"
|
||||||
|
|
||||||
|
lru-cache@^6.0.0:
|
||||||
|
version "6.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
|
||||||
|
integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
|
||||||
|
dependencies:
|
||||||
|
yallist "^4.0.0"
|
||||||
|
|
||||||
|
ms@2.1.2:
|
||||||
|
version "2.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||||
|
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||||
|
|
||||||
|
pino-std-serializers@^3.1.0:
|
||||||
|
version "3.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-3.2.0.tgz#b56487c402d882eb96cd67c257868016b61ad671"
|
||||||
|
integrity sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg==
|
||||||
|
|
||||||
|
pino@^6.13.0:
|
||||||
|
version "6.13.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/pino/-/pino-6.13.3.tgz#60b93bcda1541f92fb37b3f2be0a25cf1d05b6fe"
|
||||||
|
integrity sha512-tJy6qVgkh9MwNgqX1/oYi3ehfl2Y9H0uHyEEMsBe74KinESIjdMrMQDWpcZPpPicg3VV35d/GLQZmo4QgU2Xkg==
|
||||||
|
dependencies:
|
||||||
|
fast-redact "^3.0.0"
|
||||||
|
fast-safe-stringify "^2.0.8"
|
||||||
|
fastify-warning "^0.2.0"
|
||||||
|
flatstr "^1.0.12"
|
||||||
|
pino-std-serializers "^3.1.0"
|
||||||
|
quick-format-unescaped "^4.0.3"
|
||||||
|
sonic-boom "^1.0.2"
|
||||||
|
|
||||||
|
proxy-addr@^2.0.7:
|
||||||
|
version "2.0.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
|
||||||
|
integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==
|
||||||
|
dependencies:
|
||||||
|
forwarded "0.2.0"
|
||||||
|
ipaddr.js "1.9.1"
|
||||||
|
|
||||||
|
punycode@^2.1.0:
|
||||||
|
version "2.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||||
|
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
||||||
|
|
||||||
|
queue-microtask@^1.1.2:
|
||||||
|
version "1.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||||
|
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
|
||||||
|
|
||||||
|
quick-format-unescaped@^4.0.3:
|
||||||
|
version "4.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7"
|
||||||
|
integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==
|
||||||
|
|
||||||
|
require-from-string@^2.0.2:
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
|
||||||
|
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
|
||||||
|
|
||||||
|
ret@~0.2.0:
|
||||||
|
version "0.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/ret/-/ret-0.2.2.tgz#b6861782a1f4762dce43402a71eb7a283f44573c"
|
||||||
|
integrity sha512-M0b3YWQs7R3Z917WRQy1HHA7Ba7D8hvZg6UE5mLykJxQVE2ju0IXbGlaHPPlkY+WN7wFP+wUMXmBFA0aV6vYGQ==
|
||||||
|
|
||||||
|
reusify@^1.0.4:
|
||||||
|
version "1.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
||||||
|
integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
|
||||||
|
|
||||||
|
rfdc@^1.1.4, rfdc@^1.2.0:
|
||||||
|
version "1.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b"
|
||||||
|
integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==
|
||||||
|
|
||||||
|
safe-regex2@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/safe-regex2/-/safe-regex2-2.0.0.tgz#b287524c397c7a2994470367e0185e1916b1f5b9"
|
||||||
|
integrity sha512-PaUSFsUaNNuKwkBijoAPHAK6/eM6VirvyPWlZ7BAQy4D+hCvh4B6lIG+nPdhbFfIbP+gTGBcrdsOaUs0F+ZBOQ==
|
||||||
|
dependencies:
|
||||||
|
ret "~0.2.0"
|
||||||
|
|
||||||
|
secure-json-parse@^2.0.0:
|
||||||
|
version "2.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/secure-json-parse/-/secure-json-parse-2.4.0.tgz#5aaeaaef85c7a417f76271a4f5b0cc3315ddca85"
|
||||||
|
integrity sha512-Q5Z/97nbON5t/L/sH6mY2EacfjVGwrCcSi5D3btRO2GZ8pf1K1UN7Z9H5J57hjVU2Qzxr1xO+FmBhOvEkzCMmg==
|
||||||
|
|
||||||
|
semver-store@^0.3.0:
|
||||||
|
version "0.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/semver-store/-/semver-store-0.3.0.tgz#ce602ff07df37080ec9f4fb40b29576547befbe9"
|
||||||
|
integrity sha512-TcZvGMMy9vodEFSse30lWinkj+JgOBvPn8wRItpQRSayhc+4ssDs335uklkfvQQJgL/WvmHLVj4Ycv2s7QCQMg==
|
||||||
|
|
||||||
|
semver@^7.3.2:
|
||||||
|
version "7.3.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
|
||||||
|
integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
|
||||||
|
dependencies:
|
||||||
|
lru-cache "^6.0.0"
|
||||||
|
|
||||||
|
set-cookie-parser@^2.4.1:
|
||||||
|
version "2.4.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.4.8.tgz#d0da0ed388bc8f24e706a391f9c9e252a13c58b2"
|
||||||
|
integrity sha512-edRH8mBKEWNVIVMKejNnuJxleqYE/ZSdcT8/Nem9/mmosx12pctd80s2Oy00KNZzrogMZS5mauK2/ymL1bvlvg==
|
||||||
|
|
||||||
|
sonic-boom@^1.0.2:
|
||||||
|
version "1.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-1.4.1.tgz#d35d6a74076624f12e6f917ade7b9d75e918f53e"
|
||||||
|
integrity sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg==
|
||||||
|
dependencies:
|
||||||
|
atomic-sleep "^1.0.0"
|
||||||
|
flatstr "^1.0.12"
|
||||||
|
|
||||||
|
string-similarity@^4.0.1:
|
||||||
|
version "4.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/string-similarity/-/string-similarity-4.0.4.tgz#42d01ab0b34660ea8a018da8f56a3309bb8b2a5b"
|
||||||
|
integrity sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ==
|
||||||
|
|
||||||
|
tiny-lru@^7.0.0:
|
||||||
|
version "7.0.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/tiny-lru/-/tiny-lru-7.0.6.tgz#b0c3cdede1e5882aa2d1ae21cb2ceccf2a331f24"
|
||||||
|
integrity sha512-zNYO0Kvgn5rXzWpL0y3RS09sMK67eGaQj9805jlK9G6pSadfriTczzLHFXa/xcW4mIRfmlB9HyQ/+SgL0V1uow==
|
||||||
|
|
||||||
|
uri-js@^4.2.2:
|
||||||
|
version "4.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
|
||||||
|
integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
|
||||||
|
dependencies:
|
||||||
|
punycode "^2.1.0"
|
||||||
|
|
||||||
|
yallist@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
|
||||||
|
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
|
@@ -2,6 +2,7 @@ package ch.unisg.tapas;
|
|||||||
|
|
||||||
import ch.unisg.tapas.auctionhouse.adapter.common.clients.TapasMqttClient;
|
import ch.unisg.tapas.auctionhouse.adapter.common.clients.TapasMqttClient;
|
||||||
import ch.unisg.tapas.auctionhouse.adapter.in.messaging.mqtt.AuctionEventsMqttDispatcher;
|
import ch.unisg.tapas.auctionhouse.adapter.in.messaging.mqtt.AuctionEventsMqttDispatcher;
|
||||||
|
import ch.unisg.tapas.auctionhouse.domain.AuctionHouseDiscovery;
|
||||||
import ch.unisg.tapas.auctionhouse.adapter.common.clients.WebSubSubscriber;
|
import ch.unisg.tapas.auctionhouse.adapter.common.clients.WebSubSubscriber;
|
||||||
import ch.unisg.tapas.common.AuctionHouseResourceDirectory;
|
import ch.unisg.tapas.common.AuctionHouseResourceDirectory;
|
||||||
import ch.unisg.tapas.common.ConfigProperties;
|
import ch.unisg.tapas.common.ConfigProperties;
|
||||||
@@ -16,6 +17,9 @@ import org.springframework.core.env.ConfigurableEnvironment;
|
|||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main TAPAS Auction House application.
|
* Main TAPAS Auction House application.
|
||||||
@@ -24,7 +28,7 @@ import java.util.List;
|
|||||||
public class TapasAuctionHouseApplication {
|
public class TapasAuctionHouseApplication {
|
||||||
private static final Logger LOGGER = LogManager.getLogger(TapasAuctionHouseApplication.class);
|
private static final Logger LOGGER = LogManager.getLogger(TapasAuctionHouseApplication.class);
|
||||||
|
|
||||||
public static String RESOURCE_DIRECTORY = "https://api.interactions.ics.unisg.ch/auction-houses/";
|
public static String RESOURCE_DIRECTORY = "http://localhost:3500";
|
||||||
public static String DEFAULT_MQTT_BROKER = "tcp://broker.hivemq.com:1883";
|
public static String DEFAULT_MQTT_BROKER = "tcp://broker.hivemq.com:1883";
|
||||||
|
|
||||||
private static ConfigurableEnvironment ENVIRONMENT;
|
private static ConfigurableEnvironment ENVIRONMENT;
|
||||||
@@ -36,20 +40,23 @@ public class TapasAuctionHouseApplication {
|
|||||||
|
|
||||||
// TODO Set start up of message services with config
|
// TODO Set start up of message services with config
|
||||||
// We will use these bootstrap methods in Week 6:
|
// We will use these bootstrap methods in Week 6:
|
||||||
// bootstrapMarketplaceWithWebSub();
|
bootstrapMarketplaceWithWebSub();
|
||||||
bootstrapMarketplaceWithMqtt();
|
bootstrapMarketplaceWithMqtt();
|
||||||
|
|
||||||
|
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
|
||||||
|
executor.scheduleAtFixedRate(crawlerRunnable, 30, 30, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Discovers auction houses and subscribes to WebSub notifications
|
* Discovers auction houses and subscribes to WebSub notifications
|
||||||
*/
|
*/
|
||||||
private static void bootstrapMarketplaceWithWebSub() {
|
private static void bootstrapMarketplaceWithWebSub() {
|
||||||
List<String> auctionHouseEndpoints = discoverAuctionHouseEndpoints();
|
discoverAuctionHouseEndpoints();
|
||||||
|
|
||||||
WebSubSubscriber subscriber = new WebSubSubscriber();
|
// WebSubSubscriber subscriber = new WebSubSubscriber();
|
||||||
|
|
||||||
for (String endpoint : auctionHouseEndpoints) {
|
// for (String endpoint : auctionHouseEndpoints) {
|
||||||
subscriber.subscribeToAuctionHouseEndpoint(URI.create(endpoint));
|
// subscriber.subscribeToAuctionHouseEndpoint(URI.create(endpoint));
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,11 +81,22 @@ public class TapasAuctionHouseApplication {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> discoverAuctionHouseEndpoints() {
|
private static void discoverAuctionHouseEndpoints() {
|
||||||
AuctionHouseResourceDirectory rd = new AuctionHouseResourceDirectory(
|
AuctionHouseResourceDirectory rd = new AuctionHouseResourceDirectory(
|
||||||
URI.create(RESOURCE_DIRECTORY)
|
URI.create(RESOURCE_DIRECTORY)
|
||||||
);
|
);
|
||||||
|
|
||||||
return rd.retrieveAuctionHouseEndpoints();
|
AuctionHouseDiscovery.getInstance().addAuctionHouseDiscoveryInformation(rd.retrieveAuctionHouseEndpoints());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static Runnable crawlerRunnable = new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
AuctionHouseResourceDirectory rd = new AuctionHouseResourceDirectory(
|
||||||
|
URI.create(RESOURCE_DIRECTORY)
|
||||||
|
);
|
||||||
|
|
||||||
|
AuctionHouseDiscovery.getInstance().addAuctionHouseDiscoveryInformation(rd.retrieveAuctionHouseEndpoints());
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,48 @@
|
|||||||
|
package ch.unisg.tapas.auctionhouse.adapter.common.formats;
|
||||||
|
|
||||||
|
import ch.unisg.tapas.auctionhouse.domain.AuctionHouseDiscoveryInformation;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
public class AuctionHouseDiscoveryJsonRepresentation {
|
||||||
|
public static final String MEDIA_TYPE = "application/auctionhousediscovery+json";
|
||||||
|
|
||||||
|
@Getter @Setter
|
||||||
|
private String auctionHouseUri;
|
||||||
|
|
||||||
|
@Getter @Setter
|
||||||
|
private String webSubUri;
|
||||||
|
|
||||||
|
@Getter @Setter
|
||||||
|
private List<String> taskTypes;
|
||||||
|
|
||||||
|
@Getter @Setter
|
||||||
|
private String timeStamp;
|
||||||
|
|
||||||
|
@Getter @Setter
|
||||||
|
private String groupName;
|
||||||
|
|
||||||
|
public AuctionHouseDiscoveryJsonRepresentation() {}
|
||||||
|
|
||||||
|
public AuctionHouseDiscoveryJsonRepresentation(AuctionHouseDiscoveryInformation auctionHouseDiscoveryInformation){
|
||||||
|
this.auctionHouseUri = auctionHouseDiscoveryInformation.getAuctionHouseUri().getValue().toString();
|
||||||
|
this.webSubUri = auctionHouseDiscoveryInformation.getWebSubUri().getValue().toString();
|
||||||
|
this.taskTypes = auctionHouseDiscoveryInformation.getTaskTypes().getValue();
|
||||||
|
this.timeStamp = auctionHouseDiscoveryInformation.getTimeStamp().getValue().toString();
|
||||||
|
this.groupName = auctionHouseDiscoveryInformation.getGroupName().getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String serialize(AuctionHouseDiscoveryInformation auctionHouseDiscoveryInformation) throws JsonProcessingException {
|
||||||
|
AuctionHouseDiscoveryJsonRepresentation representation = new AuctionHouseDiscoveryJsonRepresentation(auctionHouseDiscoveryInformation);
|
||||||
|
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||||
|
return mapper.writeValueAsString(representation);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,51 @@
|
|||||||
|
package ch.unisg.tapas.auctionhouse.adapter.in.web;
|
||||||
|
|
||||||
|
import ch.unisg.tapas.auctionhouse.adapter.common.formats.AuctionHouseDiscoveryJsonRepresentation;
|
||||||
|
import ch.unisg.tapas.auctionhouse.application.port.in.AuctionHouseDiscoveryUseCase;
|
||||||
|
import ch.unisg.tapas.auctionhouse.domain.AuctionHouseDiscoveryInformation;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller that handles HTTP requests for the auction house discovery. This controller implements
|
||||||
|
* the {@link AuctionHouseDiscoveryUseCase} use case using the {@link AuctionHouseDiscoveryCommand} command.
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
public class AuctionHouseDiscoveryWebController {
|
||||||
|
private final AuctionHouseDiscoveryUseCase auctionHouseDiscoveryUseCase;
|
||||||
|
|
||||||
|
public AuctionHouseDiscoveryWebController(AuctionHouseDiscoveryUseCase auctionHouseDiscoveryUseCase) {
|
||||||
|
this.auctionHouseDiscoveryUseCase = auctionHouseDiscoveryUseCase;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping(path="/discovery/", consumes = AuctionHouseDiscoveryJsonRepresentation.MEDIA_TYPE)
|
||||||
|
public ResponseEntity<String> auctionHouseDiscovery() {
|
||||||
|
List<AuctionHouseDiscoveryInformation> auctionHouseDiscoveryInformation = auctionHouseDiscoveryUseCase.auctionHouseDiscovery();
|
||||||
|
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
ObjectNode response = mapper.createObjectNode();
|
||||||
|
ArrayNode array = response.putArray("auctionHouseInfo");
|
||||||
|
|
||||||
|
|
||||||
|
for (AuctionHouseDiscoveryInformation info : auctionHouseDiscoveryInformation) {
|
||||||
|
array.add(mapper.valueToTree(new AuctionHouseDiscoveryJsonRepresentation(info)));
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpHeaders responseHeaders = new HttpHeaders();
|
||||||
|
responseHeaders.add(HttpHeaders.CONTENT_TYPE, AuctionHouseDiscoveryJsonRepresentation.MEDIA_TYPE);
|
||||||
|
|
||||||
|
return new ResponseEntity<>(response.toString(), responseHeaders, HttpStatus.OK);
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,76 @@
|
|||||||
|
package ch.unisg.tapas.auctionhouse.adapter.out.web;
|
||||||
|
|
||||||
|
import ch.unisg.tapas.auctionhouse.application.port.out.AuctionHouseDiscoveryPort;
|
||||||
|
import ch.unisg.tapas.auctionhouse.domain.AuctionHouseDiscoveryInformation;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.http.HttpClient;
|
||||||
|
import java.net.http.HttpRequest;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class AuctionHouseDiscoveryHttpAdapter implements AuctionHouseDiscoveryPort {
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger(AuctionHouseDiscoveryHttpAdapter.class);
|
||||||
|
|
||||||
|
public List<AuctionHouseDiscoveryInformation> fetchAuctionHouseInformation(URI auctionHouseURI){
|
||||||
|
|
||||||
|
System.out.println(auctionHouseURI);
|
||||||
|
|
||||||
|
try{
|
||||||
|
var client = HttpClient.newHttpClient();
|
||||||
|
var request = HttpRequest.newBuilder()
|
||||||
|
.uri(auctionHouseURI)
|
||||||
|
.GET()
|
||||||
|
.build();
|
||||||
|
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
LOGGER.info(response.body());
|
||||||
|
var responseBody = new JSONObject(response.body());
|
||||||
|
|
||||||
|
var arrayOfInformation = responseBody.getJSONArray("auctionHouseInfo");
|
||||||
|
var returnList = new LinkedList<AuctionHouseDiscoveryInformation>();
|
||||||
|
|
||||||
|
for(int i = 0; i < arrayOfInformation.length(); i++)
|
||||||
|
{
|
||||||
|
var informationJSON = arrayOfInformation.getJSONObject(i);
|
||||||
|
var information = new AuctionHouseDiscoveryInformation(
|
||||||
|
new AuctionHouseDiscoveryInformation.AuctionHouseUri(URI.create(informationJSON.getString("auctionHouseURI"))),
|
||||||
|
new AuctionHouseDiscoveryInformation.WebSubUri(URI.create(informationJSON.getString("webSubURI"))),
|
||||||
|
new AuctionHouseDiscoveryInformation.TaskTypes(getTaskTypes(informationJSON.getJSONArray("taskTypes"))),
|
||||||
|
new AuctionHouseDiscoveryInformation.TimeStamp(Timestamp.valueOf(informationJSON.getString("timeStamp"))),
|
||||||
|
new AuctionHouseDiscoveryInformation.GroupName(informationJSON.getString("groupName"))
|
||||||
|
);
|
||||||
|
returnList.add(information);
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnList;
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return Collections.<AuctionHouseDiscoveryInformation>emptyList();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return Collections.<AuctionHouseDiscoveryInformation>emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> getTaskTypes(JSONArray arrayOfTypes){
|
||||||
|
var listOfTypes = new LinkedList<String>();
|
||||||
|
|
||||||
|
for(int i = 0; i < arrayOfTypes.length(); i++)
|
||||||
|
{
|
||||||
|
listOfTypes.add(arrayOfTypes.getString(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return listOfTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,9 @@
|
|||||||
|
package ch.unisg.tapas.auctionhouse.application.port.in;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import ch.unisg.tapas.auctionhouse.domain.AuctionHouseDiscoveryInformation;
|
||||||
|
|
||||||
|
public interface AuctionHouseDiscoveryUseCase {
|
||||||
|
List<AuctionHouseDiscoveryInformation> auctionHouseDiscovery();
|
||||||
|
}
|
@@ -0,0 +1,10 @@
|
|||||||
|
package ch.unisg.tapas.auctionhouse.application.port.out;
|
||||||
|
|
||||||
|
import ch.unisg.tapas.auctionhouse.domain.AuctionHouseDiscoveryInformation;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface AuctionHouseDiscoveryPort {
|
||||||
|
List<AuctionHouseDiscoveryInformation> fetchAuctionHouseInformation(URI auctionHouseURI);
|
||||||
|
}
|
@@ -0,0 +1,19 @@
|
|||||||
|
package ch.unisg.tapas.auctionhouse.application.service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import ch.unisg.tapas.auctionhouse.application.port.in.AuctionHouseDiscoveryUseCase;
|
||||||
|
import ch.unisg.tapas.auctionhouse.domain.AuctionHouseDiscovery;
|
||||||
|
import ch.unisg.tapas.auctionhouse.domain.AuctionHouseDiscoveryInformation;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class AuctionHouseDiscoveryService implements AuctionHouseDiscoveryUseCase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AuctionHouseDiscoveryInformation> auctionHouseDiscovery() {
|
||||||
|
return AuctionHouseDiscovery.getInstance().getAuctionHouseDiscoveryList();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,73 @@
|
|||||||
|
package ch.unisg.tapas.auctionhouse.domain;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
public class AuctionHouseDiscovery {
|
||||||
|
|
||||||
|
private static final AuctionHouseDiscovery auctionHouseDiscovery = new AuctionHouseDiscovery();
|
||||||
|
|
||||||
|
private final List<String> tasktypes = new ArrayList<String>() {
|
||||||
|
{
|
||||||
|
add("computation");
|
||||||
|
add("smallrobot");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private List<AuctionHouseDiscoveryInformation> auctionHouseDiscoveryList = new ArrayList<>() {
|
||||||
|
};
|
||||||
|
|
||||||
|
private AuctionHouseDiscovery() {
|
||||||
|
try {
|
||||||
|
// Add our information to list
|
||||||
|
auctionHouseDiscoveryList.add(new AuctionHouseDiscoveryInformation(
|
||||||
|
new AuctionHouseDiscoveryInformation.AuctionHouseUri(new URI("http://localhost:8086")),
|
||||||
|
new AuctionHouseDiscoveryInformation.WebSubUri(new URI("http://localhost:8086/websub")),
|
||||||
|
new AuctionHouseDiscoveryInformation.TaskTypes(tasktypes),
|
||||||
|
new AuctionHouseDiscoveryInformation.TimeStamp(new Timestamp(new Date().getTime())),
|
||||||
|
new AuctionHouseDiscoveryInformation.GroupName("Group 1")
|
||||||
|
));
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AuctionHouseDiscovery getInstance() {
|
||||||
|
return auctionHouseDiscovery;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<AuctionHouseDiscoveryInformation> getAuctionHouseDiscoveryInformation() {
|
||||||
|
return auctionHouseDiscoveryList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAuctionHouseDiscoveryInformation(List<AuctionHouseDiscoveryInformation> informations) {
|
||||||
|
|
||||||
|
outerloop:
|
||||||
|
for (AuctionHouseDiscoveryInformation discovery : informations) {
|
||||||
|
for (AuctionHouseDiscoveryInformation endpoint : auctionHouseDiscoveryList) {
|
||||||
|
// Check if discovery is already in our discovery list
|
||||||
|
if (endpoint.getAuctionHouseUri().getValue().toString().equals(discovery.getAuctionHouseUri().getValue().toString())) {
|
||||||
|
// Check if the new discovery is more recent than the current
|
||||||
|
if (endpoint.getTimeStamp().getValue().before(discovery.getTimeStamp().getValue())) {
|
||||||
|
// Endpoint information is older. Remove and add the new discovery to the list
|
||||||
|
auctionHouseDiscoveryList.remove(endpoint);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
continue outerloop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auctionHouseDiscoveryList.add(discovery);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,65 @@
|
|||||||
|
package ch.unisg.tapas.auctionhouse.domain;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Value;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
//TODO: change to array type
|
||||||
|
public class AuctionHouseDiscoveryInformation {
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final AuctionHouseUri auctionHouseUri;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final WebSubUri webSubUri;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final TaskTypes taskTypes;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
private final TimeStamp timeStamp;
|
||||||
|
|
||||||
|
//Had to initialize this in the constructor, but it's not required, so I'm not sure
|
||||||
|
//if this is correct
|
||||||
|
@Getter
|
||||||
|
private final GroupName groupName;
|
||||||
|
|
||||||
|
public AuctionHouseDiscoveryInformation(AuctionHouseUri auctionHouseUri, WebSubUri webSubUri,
|
||||||
|
TaskTypes taskTypes, TimeStamp timeStamp, GroupName groupName){
|
||||||
|
this.auctionHouseUri = auctionHouseUri;
|
||||||
|
this.webSubUri = webSubUri;
|
||||||
|
this.taskTypes = taskTypes;
|
||||||
|
this.timeStamp = timeStamp;
|
||||||
|
this.groupName = groupName; //see above
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Value
|
||||||
|
public static class AuctionHouseUri {
|
||||||
|
private URI value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Value
|
||||||
|
public static class WebSubUri {
|
||||||
|
private URI value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Value
|
||||||
|
public static class TaskTypes {
|
||||||
|
private List<String> value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Value
|
||||||
|
public static class TimeStamp {
|
||||||
|
private Timestamp value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Value
|
||||||
|
public static class GroupName {
|
||||||
|
private String value;
|
||||||
|
}
|
||||||
|
}
|
@@ -3,8 +3,13 @@ package ch.unisg.tapas.common;
|
|||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import ch.unisg.tapas.auctionhouse.adapter.out.web.AuctionHouseDiscoveryHttpAdapter;
|
||||||
|
import ch.unisg.tapas.auctionhouse.application.port.out.AuctionHouseDiscoveryPort;
|
||||||
|
import ch.unisg.tapas.auctionhouse.domain.AuctionHouseDiscoveryInformation;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.net.http.HttpClient;
|
import java.net.http.HttpClient;
|
||||||
import java.net.http.HttpRequest;
|
import java.net.http.HttpRequest;
|
||||||
import java.net.http.HttpResponse;
|
import java.net.http.HttpResponse;
|
||||||
@@ -26,32 +31,68 @@ public class AuctionHouseResourceDirectory {
|
|||||||
this.rdEndpoint = rdEndpoint;
|
this.rdEndpoint = rdEndpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private AuctionHouseDiscoveryPort auctionHouseDiscoveryport = new AuctionHouseDiscoveryHttpAdapter();
|
||||||
|
|
||||||
|
private List<AuctionHouseDiscoveryInformation> auctionHouseEndpoints = new ArrayList<>();
|
||||||
|
|
||||||
|
// List to keep track of already fetched endpoints
|
||||||
|
private List<URI> fetchedEndpoints = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the endpoints of all auctions houses registered with this directory.
|
* Retrieves the endpoints of all auctions houses registered with this directory.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public List<String> retrieveAuctionHouseEndpoints() {
|
public List<AuctionHouseDiscoveryInformation> retrieveAuctionHouseEndpoints() {
|
||||||
List<String> auctionHouseEndpoints = new ArrayList<>();
|
|
||||||
|
|
||||||
try {
|
fetchedEndpoints.clear();
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
auctionHouseEndpoints.clear();
|
||||||
.uri(rdEndpoint).GET().build();
|
|
||||||
|
|
||||||
HttpResponse<String> response = HttpClient.newBuilder().build()
|
fetchedEndpoints.add(rdEndpoint);
|
||||||
.send(request, HttpResponse.BodyHandlers.ofString());
|
// Start recusive fetching of auctionhouses
|
||||||
|
fetchEndpoints(getInformation(rdEndpoint));
|
||||||
// For simplicity, here we just hard code the current representation used by our
|
|
||||||
// resource directory for auction houses
|
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
|
||||||
JsonNode payload = objectMapper.readTree(response.body());
|
|
||||||
|
|
||||||
for (JsonNode node : payload) {
|
|
||||||
auctionHouseEndpoints.add(node.get("endpoint").asText());
|
|
||||||
}
|
|
||||||
} catch (IOException | InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return auctionHouseEndpoints;
|
return auctionHouseEndpoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Recursive function to fetch all endpoints
|
||||||
|
private void fetchEndpoints(List<AuctionHouseDiscoveryInformation> auctionHouses) {
|
||||||
|
|
||||||
|
for (AuctionHouseDiscoveryInformation ah : auctionHouses) {
|
||||||
|
if (!fetchedEndpoints.contains(ah.getAuctionHouseUri().getValue())) {
|
||||||
|
fetchedEndpoints.add(ah.getAuctionHouseUri().getValue());
|
||||||
|
fetchEndpoints(getInformation(ah.getAuctionHouseUri().getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<AuctionHouseDiscoveryInformation> getInformation(URI uri) {
|
||||||
|
List<AuctionHouseDiscoveryInformation> discoveries;
|
||||||
|
try {
|
||||||
|
discoveries = auctionHouseDiscoveryport.fetchAuctionHouseInformation(new URI(uri.toString() + "/discovery/"));
|
||||||
|
outerloop:
|
||||||
|
for (AuctionHouseDiscoveryInformation discovery : discoveries) {
|
||||||
|
for (AuctionHouseDiscoveryInformation endpoint : auctionHouseEndpoints) {
|
||||||
|
// Check if discovery is already in our endpoint list
|
||||||
|
if (endpoint.getAuctionHouseUri().getValue().toString().equals(discovery.getAuctionHouseUri().getValue().toString())) {
|
||||||
|
// Check if the new discovery is more recent than the current
|
||||||
|
if (endpoint.getTimeStamp().getValue().before(discovery.getTimeStamp().getValue())) {
|
||||||
|
// Endpoint information is older. Remove and add the new discovery to the list
|
||||||
|
auctionHouseEndpoints.remove(endpoint);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
continue outerloop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auctionHouseEndpoints.add(discovery);
|
||||||
|
}
|
||||||
|
return discoveries;
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
// When an error happens return empty list
|
||||||
|
return new ArrayList<AuctionHouseDiscoveryInformation>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user