Merge pull request #105 from SCS-ASSE-FS21-Group1/websub-improvements
Websub improvements
This commit is contained in:
commit
27ccc54458
|
@ -67,6 +67,8 @@ services:
|
||||||
- ./:/data/
|
- ./:/data/
|
||||||
environment:
|
environment:
|
||||||
mqtt.broker.uri: tcp://broker.hivemq.com:1883
|
mqtt.broker.uri: tcp://broker.hivemq.com:1883
|
||||||
|
discovery.endpoint.uri: https://tapas-auction-house.86.119.35.213.nip.io/discovery/
|
||||||
|
auction.house.uri: https://tapas-auction-house.86-119-35-40.nip.io
|
||||||
labels:
|
labels:
|
||||||
- "traefik.enable=true"
|
- "traefik.enable=true"
|
||||||
- "traefik.http.routers.tapas-auction-house.rule=Host(`tapas-auction-house.${PUB_IP}.nip.io`)"
|
- "traefik.http.routers.tapas-auction-house.rule=Host(`tapas-auction-house.${PUB_IP}.nip.io`)"
|
||||||
|
|
|
@ -72,15 +72,15 @@ services:
|
||||||
volumes:
|
volumes:
|
||||||
- ./executor-computation/src:/opt/app/src
|
- ./executor-computation/src:/opt/app/src
|
||||||
- ./executor-computation/target:/opt/app/target
|
- ./executor-computation/target:/opt/app/target
|
||||||
executor-robot:
|
# executor-robot:
|
||||||
container_name: executor-robot
|
# container_name: executor-robot
|
||||||
build:
|
# build:
|
||||||
context: "."
|
# context: "."
|
||||||
dockerfile: "./executor-robot/Dockerfile"
|
# dockerfile: "./executor-robot/Dockerfile"
|
||||||
target: development
|
# target: development
|
||||||
ports:
|
# ports:
|
||||||
- "8084:8084"
|
# - "8084:8084"
|
||||||
- "5009:5005"
|
# - "5009:5005"
|
||||||
volumes:
|
# volumes:
|
||||||
- ./executor-robot/src:/opt/app/src
|
# - ./executor-robot/src:/opt/app/src
|
||||||
- ./executor-robot/target:/opt/app/target
|
# - ./executor-robot/target:/opt/app/target
|
||||||
|
|
|
@ -13,7 +13,7 @@ public class ExecutorcomputationApplication {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
TimeUnit.SECONDS.sleep(40);
|
TimeUnit.SECONDS.sleep(10);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
// TODO Auto-generated catch block
|
// TODO Auto-generated catch block
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
server.port=8083
|
server.port=8083
|
||||||
|
|
||||||
mqtt.broker.uri=tcp://localhost:1883
|
# mqtt.broker.uri=tcp://localhost:1883
|
||||||
|
mqtt.broker.uri=tcp://broker.hivemq.com
|
||||||
|
|
||||||
spring.data.mongodb.uri=mongodb://root:password@localhost:27017
|
spring.data.mongodb.uri=mongodb://root:password@localhost:27017
|
||||||
spring.data.mongodb.database=tapas-executors
|
spring.data.mongodb.database=tapas-executors
|
||||||
|
|
|
@ -33,7 +33,7 @@ public class RosterApplication {
|
||||||
SpringApplication rosterApp = new SpringApplication(RosterApplication.class);
|
SpringApplication rosterApp = new SpringApplication(RosterApplication.class);
|
||||||
ENVIRONMENT = rosterApp.run(args).getEnvironment();
|
ENVIRONMENT = rosterApp.run(args).getEnvironment();
|
||||||
bootstrapMarketplaceWithMqtt();
|
bootstrapMarketplaceWithMqtt();
|
||||||
initialiseRoster();
|
// initialiseRoster();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,7 +3,8 @@ executor.robot.uri=http://127.0.0.1:8084
|
||||||
executor.computation.uri=http://127.0.0.1:8085
|
executor.computation.uri=http://127.0.0.1:8085
|
||||||
auction.house.uri=http://127.0.0.1:8086
|
auction.house.uri=http://127.0.0.1:8086
|
||||||
task.list.uri=http://127.0.0.1:8081
|
task.list.uri=http://127.0.0.1:8081
|
||||||
mqtt.broker.uri=tcp://localhost:1883
|
# mqtt.broker.uri=tcp://localhost:1883
|
||||||
|
mqtt.broker.uri=tcp://broker.hivemq.com
|
||||||
|
|
||||||
spring.data.mongodb.uri=mongodb://root:password@localhost:27017/
|
spring.data.mongodb.uri=mongodb://root:password@localhost:27017/
|
||||||
spring.data.mongodb.database=tapas-roster
|
spring.data.mongodb.database=tapas-roster
|
||||||
|
|
|
@ -3,20 +3,19 @@ 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.domain.AuctionHouseDiscovery;
|
||||||
|
import ch.unisg.tapas.auctionhouse.domain.AuctionHouseDiscoveryInformation;
|
||||||
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 org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.eclipse.paho.client.mqttv3.MqttException;
|
import org.eclipse.paho.client.mqttv3.MqttException;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.core.env.ConfigurableEnvironment;
|
import org.springframework.core.env.ConfigurableEnvironment;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.List;
|
import java.net.URISyntaxException;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
@ -28,35 +27,35 @@ import java.util.concurrent.TimeUnit;
|
||||||
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 = "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;
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication tapasAuctioneerApp = new SpringApplication(TapasAuctionHouseApplication.class);
|
SpringApplication tapasAuctioneerApp = new SpringApplication(TapasAuctionHouseApplication.class);
|
||||||
ENVIRONMENT = tapasAuctioneerApp.run(args).getEnvironment();
|
ENVIRONMENT = tapasAuctioneerApp.run(args).getEnvironment();
|
||||||
|
|
||||||
// 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() {
|
||||||
discoverAuctionHouseEndpoints();
|
// discoverAuctionHouseEndpoints();
|
||||||
|
|
||||||
// WebSubSubscriber subscriber = new WebSubSubscriber();
|
WebSubSubscriber subscriber = new WebSubSubscriber(ENVIRONMENT.getProperty("auction.house.uri"));
|
||||||
|
|
||||||
// for (String endpoint : auctionHouseEndpoints) {
|
// for (AuctionHouseDiscoveryInformation endpoint : AuctionHouseDiscovery.getInstance().getAuctionHouseDiscoveryList()) {
|
||||||
// subscriber.subscribeToAuctionHouseEndpoint(URI.create(endpoint));
|
// subscriber.subscribeToAuctionHouseEndpoint(endpoint.getWebSubUri().getValue());
|
||||||
// }
|
// }
|
||||||
|
try {
|
||||||
|
subscriber.subscribeToAuctionHouseEndpoint(new URI("http://6b4e-130-82-250-227.ngrok.io/websub-discovery"));
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,22 +80,26 @@ public class TapasAuctionHouseApplication {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void discoverAuctionHouseEndpoints() {
|
// private static void discoverAuctionHouseEndpoints() {
|
||||||
AuctionHouseResourceDirectory rd = new AuctionHouseResourceDirectory(
|
|
||||||
URI.create(RESOURCE_DIRECTORY)
|
|
||||||
);
|
|
||||||
|
|
||||||
AuctionHouseDiscovery.getInstance().addAuctionHouseDiscoveryInformation(rd.retrieveAuctionHouseEndpoints());
|
// AuctionHouseResourceDirectory rd = new AuctionHouseResourceDirectory(
|
||||||
}
|
// URI.create(ENVIRONMENT.getProperty("discovery.endpoint.uri"))
|
||||||
|
// );
|
||||||
|
|
||||||
|
// AuctionHouseDiscovery.getInstance().addAuctionHouseDiscoveryInformation(rd.retrieveAuctionHouseEndpoints());
|
||||||
|
|
||||||
|
// ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
|
||||||
|
// executor.scheduleAtFixedRate(crawlerRunnable, 300, 300, TimeUnit.SECONDS);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
private static Runnable crawlerRunnable = new Runnable() {
|
// private static Runnable crawlerRunnable = new Runnable() {
|
||||||
public void run() {
|
// public void run() {
|
||||||
AuctionHouseResourceDirectory rd = new AuctionHouseResourceDirectory(
|
// AuctionHouseResourceDirectory rd = new AuctionHouseResourceDirectory(
|
||||||
URI.create(RESOURCE_DIRECTORY)
|
// URI.create(ENVIRONMENT.getProperty("discovery.endpoint.uri"))
|
||||||
);
|
// );
|
||||||
|
|
||||||
AuctionHouseDiscovery.getInstance().addAuctionHouseDiscoveryInformation(rd.retrieveAuctionHouseEndpoints());
|
// AuctionHouseDiscovery.getInstance().addAuctionHouseDiscoveryInformation(rd.retrieveAuctionHouseEndpoints());
|
||||||
}
|
// }
|
||||||
};
|
// };
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,11 @@ package ch.unisg.tapas.auctionhouse.adapter.common.clients;
|
||||||
|
|
||||||
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;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
@ -18,25 +20,24 @@ import org.springframework.http.HttpStatus;
|
||||||
*/
|
*/
|
||||||
public class WebSubSubscriber {
|
public class WebSubSubscriber {
|
||||||
|
|
||||||
// TODO get this somehow from properties file. But on clue how to do this with static variables
|
|
||||||
static String WEBSUB_HUB_ENDPOINT = "http://localhost:3000";
|
|
||||||
static String AUCTION_HOUSE_ENDPOINT = "http://localhost:8086";
|
|
||||||
|
|
||||||
Logger logger = Logger.getLogger(WebSubSubscriber.class.getName());
|
Logger logger = Logger.getLogger(WebSubSubscriber.class.getName());
|
||||||
|
|
||||||
public void subscribeToAuctionHouseEndpoint(URI endpoint) {
|
String AUCTION_HOUSE_ENDPOINT;
|
||||||
// TODO decide with other groups about auction house endpoint uri to discover websub topics
|
|
||||||
// and replace the hardcoded one with it
|
|
||||||
String topic = discoverWebSubTopic("http://localhost:3100/websub");
|
|
||||||
|
|
||||||
if (topic == null) {
|
public WebSubSubscriber(String AUCTION_HOUSE_ENDPOINT) {
|
||||||
|
this.AUCTION_HOUSE_ENDPOINT = AUCTION_HOUSE_ENDPOINT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void subscribeToAuctionHouseEndpoint(URI endpoint) {
|
||||||
|
|
||||||
|
HashMap<String, String> links = discoverWebSubTopic(endpoint);
|
||||||
|
|
||||||
|
if (links.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
subscribeToWebSub(topic);
|
subscribeToWebSub(links.get("hub"), links.get("self"));
|
||||||
|
|
||||||
// Shoudl be done :D
|
|
||||||
// TODO Subscribe to the auction house endpoint via WebSub:
|
|
||||||
// 1. Send a request to the auction house in order to discover the WebSub hub to subscribe to.
|
// 1. Send a request to the auction house in order to discover the WebSub hub to subscribe to.
|
||||||
// The request URI should depend on the design of the Auction House HTTP API.
|
// The request URI should depend on the design of the Auction House HTTP API.
|
||||||
// 2. Send a subscription request to the discovered WebSub hub to subscribe to events relevant
|
// 2. Send a subscription request to the discovered WebSub hub to subscribe to events relevant
|
||||||
|
@ -52,23 +53,30 @@ public class WebSubSubscriber {
|
||||||
// - the implementation notes of the WebSub hub you are using to distribute events
|
// - the implementation notes of the WebSub hub you are using to distribute events
|
||||||
}
|
}
|
||||||
|
|
||||||
private String discoverWebSubTopic(String endpoint) {
|
private HashMap<String, String> discoverWebSubTopic(URI endpoint) {
|
||||||
HttpClient client = HttpClient.newHttpClient();
|
HttpClient client = HttpClient.newHttpClient();
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
.uri(URI.create(endpoint))
|
.uri(endpoint)
|
||||||
.header("Content-Type", "application/json")
|
.header("Content-Type", "application/json")
|
||||||
.GET()
|
.GET()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
HashMap<String, String> links = new HashMap<>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
if (response.statusCode() == HttpStatus.OK.value()) {
|
if (response.statusCode() == HttpStatus.OK.value()) {
|
||||||
// TODO decide with other groups about response structure and replace the hardcoded
|
for (String link : response.headers().allValues("link")) {
|
||||||
// uri with response uri
|
if (link.contains("rel=\"hub\"")) {
|
||||||
JSONObject jsonObject = new JSONObject(response.body());
|
String hub = link.split(">")[0];
|
||||||
System.out.println(jsonObject);
|
links.put("hub", hub.substring(1));
|
||||||
return jsonObject.getString("topic");
|
} else if(link.contains("rel=\"self\"")) {
|
||||||
|
String self = link.split(">")[0];
|
||||||
|
links.put("self", self.substring(1));
|
||||||
|
}
|
||||||
|
System.out.println(link);
|
||||||
|
}
|
||||||
|
// TODO check for HTML tags second if links are not present in headers
|
||||||
} else {
|
} else {
|
||||||
logger.log(Level.SEVERE, "Could not find a websub uri");
|
logger.log(Level.SEVERE, "Could not find a websub uri");
|
||||||
}
|
}
|
||||||
|
@ -78,24 +86,26 @@ public class WebSubSubscriber {
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.log(Level.SEVERE, e.getLocalizedMessage(), e);
|
logger.log(Level.SEVERE, e.getLocalizedMessage(), e);
|
||||||
}
|
}
|
||||||
return null;
|
return links;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void subscribeToWebSub(String topic) {
|
private void subscribeToWebSub(String hub, String topic) {
|
||||||
HttpClient client = HttpClient.newHttpClient();
|
HttpClient client = HttpClient.newHttpClient();
|
||||||
|
|
||||||
String body = new JSONObject()
|
URI hubURI;
|
||||||
.put("hub.callback", AUCTION_HOUSE_ENDPOINT + "/auction-started")
|
try {
|
||||||
.put("hub.mode", "subscribe")
|
hubURI = new URI(hub);
|
||||||
.put("hub.topic", topic)
|
} catch (URISyntaxException e) {
|
||||||
.put("hub.ws", false)
|
// TODO Auto-generated catch block
|
||||||
.toString();
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
.uri(URI.create(WEBSUB_HUB_ENDPOINT))
|
.uri(hubURI)
|
||||||
.header("Content-Type", "application/json")
|
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||||
.POST(HttpRequest.BodyPublishers.ofString(body))
|
.POST(HttpRequest.BodyPublishers.ofString("hub.mode=subscribe&hub.callback=" + AUCTION_HOUSE_ENDPOINT +
|
||||||
|
"/auction-started/74c72c7f-2739-4124-aa35-a3225171a97c" + "&hub.topic=" + topic))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,16 @@ package ch.unisg.tapas.auctionhouse.adapter.common.formats;
|
||||||
import ch.unisg.tapas.auctionhouse.domain.Auction;
|
import ch.unisg.tapas.auctionhouse.domain.Auction;
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to expose a representation of the state of an auction through an interface. This class is
|
* Used to expose a representation of the state of an auction through an interface. This class is
|
||||||
|
@ -60,4 +64,28 @@ public class AuctionJsonRepresentation {
|
||||||
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
|
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
|
||||||
return mapper.writeValueAsString(representation);
|
return mapper.writeValueAsString(representation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Auction deserialize(String auctionJson) throws JsonProcessingException {
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
JsonNode jsonNode = objectMapper.readTree(auctionJson);
|
||||||
|
Auction.AuctionId auctionId = new Auction.AuctionId(jsonNode.get("auctionId").asText());
|
||||||
|
Auction.AuctionHouseUri auctionHouseUri = new Auction.AuctionHouseUri(URI.create(jsonNode.get("auctionHouseUri").asText()));
|
||||||
|
Auction.AuctionedTaskUri taskUri = new Auction.AuctionedTaskUri(URI.create(jsonNode.get("taskUri").asText()));
|
||||||
|
Auction.AuctionedTaskType taskType = new Auction.AuctionedTaskType(jsonNode.get("taskType").asText());
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
Date parsedDate;
|
||||||
|
try {
|
||||||
|
parsedDate = dateFormat.parse(jsonNode.get("deadline").toString());
|
||||||
|
Timestamp timestamp = new java.sql.Timestamp(parsedDate.getTime());
|
||||||
|
Auction.AuctionDeadline deadline = new Auction.AuctionDeadline(timestamp);
|
||||||
|
|
||||||
|
Auction auction = new Auction(auctionId, auctionHouseUri, taskUri, taskType, deadline);
|
||||||
|
return auction;
|
||||||
|
} catch (ParseException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,31 @@
|
||||||
package ch.unisg.tapas.auctionhouse.adapter.in.messaging.websub;
|
package ch.unisg.tapas.auctionhouse.adapter.in.messaging.websub;
|
||||||
|
|
||||||
import ch.unisg.tapas.auctionhouse.adapter.common.formats.AuctionJsonRepresentation;
|
import ch.unisg.tapas.auctionhouse.adapter.common.formats.AuctionJsonRepresentation;
|
||||||
|
import ch.unisg.tapas.auctionhouse.adapter.common.formats.BidJsonRepresentation;
|
||||||
import ch.unisg.tapas.auctionhouse.application.handler.AuctionStartedHandler;
|
import ch.unisg.tapas.auctionhouse.application.handler.AuctionStartedHandler;
|
||||||
import ch.unisg.tapas.auctionhouse.application.port.in.AuctionStartedEvent;
|
import ch.unisg.tapas.auctionhouse.application.port.in.AuctionStartedEvent;
|
||||||
import ch.unisg.tapas.auctionhouse.domain.Auction;
|
import ch.unisg.tapas.auctionhouse.domain.Auction;
|
||||||
|
import ch.unisg.tapas.auctionhouse.domain.Bid;
|
||||||
import ch.unisg.tapas.auctionhouse.domain.Auction.AuctionDeadline;
|
import ch.unisg.tapas.auctionhouse.domain.Auction.AuctionDeadline;
|
||||||
import ch.unisg.tapas.auctionhouse.domain.Auction.AuctionHouseUri;
|
import ch.unisg.tapas.auctionhouse.domain.Auction.AuctionHouseUri;
|
||||||
import ch.unisg.tapas.auctionhouse.domain.Auction.AuctionId;
|
import ch.unisg.tapas.auctionhouse.domain.Auction.AuctionId;
|
||||||
import ch.unisg.tapas.auctionhouse.domain.Auction.AuctionedTaskType;
|
import ch.unisg.tapas.auctionhouse.domain.Auction.AuctionedTaskType;
|
||||||
import ch.unisg.tapas.auctionhouse.domain.Auction.AuctionedTaskUri;
|
import ch.unisg.tapas.auctionhouse.domain.Auction.AuctionedTaskUri;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.net.http.HttpClient;
|
||||||
|
import java.net.http.HttpRequest;
|
||||||
|
import java.net.http.HttpResponse;
|
||||||
|
import java.security.Timestamp;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONObject;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
@ -34,20 +45,89 @@ public class AuctionStartedEventListenerWebSubAdapter {
|
||||||
* @return 200 OK
|
* @return 200 OK
|
||||||
* @throws URISyntaxException
|
* @throws URISyntaxException
|
||||||
**/
|
**/
|
||||||
@PostMapping(path = "/auction-started")
|
// TODO generate a new capability ID instead of using a hardcoded one.
|
||||||
public ResponseEntity<Void> handleExecutorAddedEvent(@RequestBody Collection<AuctionJsonRepresentation> payload) throws URISyntaxException {
|
@PostMapping(path = "/auction-started/74c72c7f-2739-4124-aa35-a3225171a97c")
|
||||||
|
public ResponseEntity<Void> handleExecutorAddedEvent(@RequestBody String payload) throws URISyntaxException {
|
||||||
|
|
||||||
for (AuctionJsonRepresentation auction : payload) {
|
System.out.println("new auctions :O");
|
||||||
auctionStartedHandler.handleAuctionStartedEvent(
|
System.out.println(payload);
|
||||||
new AuctionStartedEvent(
|
|
||||||
new Auction(new AuctionId(auction.getAuctionId()),
|
|
||||||
new AuctionHouseUri(new URI(auction.getAuctionHouseUri())),
|
JSONArray auctions = new JSONArray(payload);
|
||||||
new AuctionedTaskUri(new URI(auction.getTaskUri())),
|
if (auctions.length() > 0) {
|
||||||
new AuctionedTaskType(auction.getTaskType()),
|
JSONObject auction = auctions.getJSONObject(0);
|
||||||
new AuctionDeadline(auction.getDeadline()))
|
System.out.print(auction);
|
||||||
));
|
// try {
|
||||||
|
// System.out.println(auction.getString("deadline"));
|
||||||
|
// System.out.println(AuctionJsonRepresentation.deserialize(auction.toString()));
|
||||||
|
|
||||||
|
// auctionStartedHandler.handleAuctionStartedEvent(
|
||||||
|
// new AuctionStartedEvent(AuctionJsonRepresentation.deserialize(auction.toString())));
|
||||||
|
// } catch (JsonProcessingException e) {
|
||||||
|
// // TODO Auto-generated catch block
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// String auctionHouseURI = "https://tapas-auction-house.86-119-35-40.nip.io/";
|
||||||
|
String auctionHouseURI = "http://b311-130-82-247-153.eu.ngrok.io";
|
||||||
|
|
||||||
|
// String taskListURI = "https://tapas-tasks.86-119-35-40.nip.io";
|
||||||
|
String taskListURI = "http://c64f-130-82-247-153.ngrok.io";
|
||||||
|
|
||||||
|
// TODO Sanitize URIs
|
||||||
|
String auctionId = auction.getString("auctionId");
|
||||||
|
String auctionHouseUri = auction.getString("auctionHouseUri");
|
||||||
|
String taskUri = auction.getString("taskUri");
|
||||||
|
String taskType = auction.getString("taskType");
|
||||||
|
String deadline = auction.getString("deadline");
|
||||||
|
|
||||||
|
var bid = new Bid(
|
||||||
|
new Auction.AuctionId(auctionId),
|
||||||
|
new Bid.BidderName("Group-1"),
|
||||||
|
new Bid.BidderAuctionHouseUri(URI.create(auctionHouseURI)),
|
||||||
|
new Bid.BidderTaskListUri(URI.create(taskListURI))
|
||||||
|
);
|
||||||
|
|
||||||
|
String body;
|
||||||
|
try {
|
||||||
|
body = BidJsonRepresentation.serialize(bid);
|
||||||
|
//LOGGER.info(body);
|
||||||
|
var postURI = URI.create(auctionHouseUri + "/bid");
|
||||||
|
HttpRequest postRequest = HttpRequest.newBuilder()
|
||||||
|
.uri(postURI)
|
||||||
|
.header("Content-Type", BidJsonRepresentation.MEDIA_TYPE)
|
||||||
|
.POST(HttpRequest.BodyPublishers.ofString(body))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpClient client = HttpClient.newHttpClient();
|
||||||
|
var postResponse = client.send(postRequest, HttpResponse.BodyHandlers.ofString());
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//LOGGER.info(postResponse.statusCode());
|
||||||
|
};
|
||||||
|
|
||||||
|
// for (JSONObject auction : auctions) {
|
||||||
|
// auctionStartedHandler.handleAuctionStartedEvent(
|
||||||
|
// new AuctionStartedEvent(
|
||||||
|
// new Auction(new AuctionId(auction.getAuctionId()),
|
||||||
|
// new AuctionHouseUri(new URI(auction.getAuctionHouseUri())),
|
||||||
|
// new AuctionedTaskUri(new URI(auction.getTaskUri())),
|
||||||
|
// new AuctionedTaskType(auction.getTaskType()),
|
||||||
|
// new AuctionDeadline(auction.getDeadline()))
|
||||||
|
// ));
|
||||||
|
// }
|
||||||
|
|
||||||
return new ResponseEntity<>(HttpStatus.OK);
|
return new ResponseEntity<>(HttpStatus.OK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
package ch.unisg.tapas.auctionhouse.adapter.in.messaging.websub;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is a template for handling auction started events received via WebSub
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
public class DiscoverWebSubAdapter {
|
||||||
|
|
||||||
|
@Value("${websub.hub.uri}")
|
||||||
|
private String webSubHubUri;
|
||||||
|
|
||||||
|
@Value("${auction.house.uri}")
|
||||||
|
private String auctionHouseUri;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller to discover our websub topic
|
||||||
|
* @return 200 OK
|
||||||
|
**/
|
||||||
|
@GetMapping(path = "/websub/auctions")
|
||||||
|
public ResponseEntity<String> handleDiscoverWebSubAuction() {
|
||||||
|
|
||||||
|
HttpHeaders header = new HttpHeaders();
|
||||||
|
header.add("link", "<" + auctionHouseUri + "/auctions/>; rel=\"self\"");
|
||||||
|
header.add("link", "<" + webSubHubUri + ">; rel=\"hub\"");
|
||||||
|
|
||||||
|
return ResponseEntity.ok().headers(header).body("");
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,21 +13,9 @@ import org.springframework.web.bind.annotation.*;
|
||||||
@RestController
|
@RestController
|
||||||
public class ValidateIntentWebSubAdapter {
|
public class ValidateIntentWebSubAdapter {
|
||||||
|
|
||||||
@Value("${application.environment}")
|
// TODO generate a new capability ID instead of using a hardcoded one.
|
||||||
private String environment;
|
@GetMapping(path = "/auction-started/74c72c7f-2739-4124-aa35-a3225171a97c")
|
||||||
|
|
||||||
@GetMapping(path = "/auction-started")
|
|
||||||
public ResponseEntity<String> validateIntent(@RequestParam("hub.challenge") String challenge) {
|
public ResponseEntity<String> validateIntent(@RequestParam("hub.challenge") String challenge) {
|
||||||
// Different implementation depending on local development or production
|
|
||||||
if (environment.equalsIgnoreCase("development")) {
|
|
||||||
HttpHeaders headers = new HttpHeaders();
|
|
||||||
headers.add("Content-Type", "application/json");
|
|
||||||
String body = new JSONObject()
|
|
||||||
.put("hub.challenge", challenge)
|
|
||||||
.toString();
|
|
||||||
return new ResponseEntity<>(body, headers, HttpStatus.OK);
|
|
||||||
} else {
|
|
||||||
return new ResponseEntity<>(challenge, HttpStatus.OK);
|
return new ResponseEntity<>(challenge, HttpStatus.OK);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@Primary
|
// @Primary
|
||||||
public class PublishAuctionStartedEventMqttAdapter implements AuctionStartedEventPort {
|
public class PublishAuctionStartedEventMqttAdapter implements AuctionStartedEventPort {
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger(PublishAuctionStartedEventMqttAdapter.class);
|
private static final Logger LOGGER = LogManager.getLogger(PublishAuctionStartedEventMqttAdapter.class);
|
||||||
|
|
|
@ -1,41 +1,27 @@
|
||||||
package ch.unisg.tapas.auctionhouse.adapter.out.messaging.websub;
|
package ch.unisg.tapas.auctionhouse.adapter.out.messaging.websub;
|
||||||
|
|
||||||
import ch.unisg.tapas.auctionhouse.application.port.out.AuctionStartedEventPort;
|
import ch.unisg.tapas.auctionhouse.application.port.out.AuctionStartedEventPort;
|
||||||
import ch.unisg.tapas.auctionhouse.domain.Auction;
|
|
||||||
import ch.unisg.tapas.auctionhouse.domain.AuctionStartedEvent;
|
import ch.unisg.tapas.auctionhouse.domain.AuctionStartedEvent;
|
||||||
import ch.unisg.tapas.common.ConfigProperties;
|
|
||||||
|
|
||||||
import org.json.JSONObject;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Primary;
|
import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URLEncoder;
|
|
||||||
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;
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is a template for publishing auction started events via WebSub.
|
* This class is a template for publishing auction started events via WebSub.
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
|
@Primary
|
||||||
public class PublishAuctionStartedEventWebSubAdapter implements AuctionStartedEventPort {
|
public class PublishAuctionStartedEventWebSubAdapter implements AuctionStartedEventPort {
|
||||||
// You can use this object to retrieve properties from application.properties, e.g. the
|
@Value("${auction.house.uri}")
|
||||||
// WebSub hub publish endpoint, etc.
|
|
||||||
@Autowired
|
|
||||||
private ConfigProperties config;
|
|
||||||
|
|
||||||
@Value("${auctionhouse.uri}")
|
|
||||||
private String auctionHouseUri;
|
private String auctionHouseUri;
|
||||||
|
|
||||||
@Value("${websub.hub.uri}")
|
@Value("${websub.hub.uri}")
|
||||||
|
@ -47,21 +33,20 @@ public class PublishAuctionStartedEventWebSubAdapter implements AuctionStartedEv
|
||||||
public void publishAuctionStartedEvent(AuctionStartedEvent event) {
|
public void publishAuctionStartedEvent(AuctionStartedEvent event) {
|
||||||
HttpClient client = HttpClient.newHttpClient();
|
HttpClient client = HttpClient.newHttpClient();
|
||||||
|
|
||||||
String body = new JSONObject()
|
String body = "hub.url=" + auctionHouseUri + "/auctions/&hub.mode=publish";
|
||||||
.put("hub.url", auctionHouseUri + "/auctions")
|
|
||||||
.put("hub.mode", "publish")
|
|
||||||
.toString();
|
|
||||||
|
|
||||||
|
logger.info("Auctions updated:" + body);
|
||||||
|
|
||||||
HttpRequest request = HttpRequest.newBuilder()
|
HttpRequest request = HttpRequest.newBuilder()
|
||||||
.uri(URI.create(webSubHubUri))
|
.uri(URI.create(webSubHubUri))
|
||||||
.header("Content-Type", "application/json")
|
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||||
.POST(HttpRequest.BodyPublishers.ofString(body))
|
.POST(HttpRequest.BodyPublishers.ofString(body))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
client.send(request, HttpResponse.BodyHandlers.ofString());
|
client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
|
logger.info("WEBSUB send successfuly");
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
logger.log(Level.SEVERE, e.getLocalizedMessage(), e);
|
logger.log(Level.SEVERE, e.getLocalizedMessage(), e);
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
|
|
|
@ -43,6 +43,7 @@ public class AuctionWonEventHttpAdapter implements AuctionWonEventPort {
|
||||||
.uri(auction.get().getTaskUri().getValue())
|
.uri(auction.get().getTaskUri().getValue())
|
||||||
.GET()
|
.GET()
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||||
LOGGER.info(response.body());
|
LOGGER.info(response.body());
|
||||||
JSONObject responseBody = new JSONObject(response.body());
|
JSONObject responseBody = new JSONObject(response.body());
|
||||||
|
|
|
@ -20,6 +20,9 @@ public class AuctionHouseDiscovery {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO load from config
|
||||||
|
// static String AUCTION_HOUSE_URI = "http://localhost:8086";
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private List<AuctionHouseDiscoveryInformation> auctionHouseDiscoveryList = new ArrayList<>() {
|
private List<AuctionHouseDiscoveryInformation> auctionHouseDiscoveryList = new ArrayList<>() {
|
||||||
};
|
};
|
||||||
|
@ -29,7 +32,7 @@ public class AuctionHouseDiscovery {
|
||||||
// Add our information to list
|
// Add our information to list
|
||||||
auctionHouseDiscoveryList.add(new AuctionHouseDiscoveryInformation(
|
auctionHouseDiscoveryList.add(new AuctionHouseDiscoveryInformation(
|
||||||
new AuctionHouseDiscoveryInformation.AuctionHouseUri(new URI("http://localhost:8086")),
|
new AuctionHouseDiscoveryInformation.AuctionHouseUri(new URI("http://localhost:8086")),
|
||||||
new AuctionHouseDiscoveryInformation.WebSubUri(new URI("http://localhost:8086/websub")),
|
new AuctionHouseDiscoveryInformation.WebSubUri(new URI("http://localhost:8086/websub/auctions")),
|
||||||
new AuctionHouseDiscoveryInformation.TaskTypes(tasktypes),
|
new AuctionHouseDiscoveryInformation.TaskTypes(tasktypes),
|
||||||
new AuctionHouseDiscoveryInformation.TimeStamp(new Timestamp(new Date().getTime())),
|
new AuctionHouseDiscoveryInformation.TimeStamp(new Timestamp(new Date().getTime())),
|
||||||
new AuctionHouseDiscoveryInformation.GroupName("Group 1")
|
new AuctionHouseDiscoveryInformation.GroupName("Group 1")
|
||||||
|
|
|
@ -10,6 +10,8 @@ auction.house.uri=https://tapas-auction-house.86-119-35-40.nip.io
|
||||||
tasks.list.uri=http://localhost:8081
|
tasks.list.uri=http://localhost:8081
|
||||||
|
|
||||||
application.environment=development
|
application.environment=development
|
||||||
auctionhouse.uri=http://localhost:8086
|
websub.hub.uri=https://pubsubhubbub.appspot.com
|
||||||
websub.hub.uri=http://localhost:3000
|
mqtt.broker.uri=tcp://broker.hivemq.com
|
||||||
mqtt.broker.uri=tcp://localhost:1883
|
# mqtt.broker.uri=tcp://localhost:1883
|
||||||
|
|
||||||
|
discovery.endpoint.uri=http://localhost:3500
|
||||||
|
|
Loading…
Reference in New Issue
Block a user