diff --git a/app/Dockerfile b/app/Dockerfile deleted file mode 100644 index 429a177..0000000 --- a/app/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -# Dockerfile/Docker-Compose file based on an initial version authored by Alexander Lontke (ASSE, Fall Semester 2021) - -FROM maven as build - -COPY . /app - -RUN mvn -f app/pom.xml --batch-mode --update-snapshots verify - -FROM openjdk - -COPY --from=build /app/target/app-0.1.0.jar ./app-0.1.0.jar - -CMD java -jar app-0.1.0.jar diff --git a/doc/architecture/decisions/0002-seperate-service-for-executors-and-pool.md b/doc/architecture/decisions/0002-seperate-service-for-executors-and-pool.md deleted file mode 100644 index 37594fa..0000000 --- a/doc/architecture/decisions/0002-seperate-service-for-executors-and-pool.md +++ /dev/null @@ -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. diff --git a/doc/architecture/decisions/0002-seperate-service-for-executors.md b/doc/architecture/decisions/0002-seperate-service-for-executors.md new file mode 100644 index 0000000..781d9b4 --- /dev/null +++ b/doc/architecture/decisions/0002-seperate-service-for-executors.md @@ -0,0 +1,21 @@ +# 2. Seperate service for Executors + +Date: 2021-10-18 + +## Status + +Accepted + +## Context + +The users need to be able to add new executors to the executor pool. The functionality of the executor is currently unknown. + +## Decision + +We will use a separate microservice for each executor. +New executors will be added/removed during runtime. Therefore, we need a high extensibility. +Different executors can have different execution times and a different load. This means the executors scale differently. + +## Consequences + +Having executors as its own service we can deploy new executors independently and easily add new executors during runtime and guarantee high scalability as well as evolvability. diff --git a/doc/architecture/decisions/0003-seperate-service-for-assignment-domain.md b/doc/architecture/decisions/0003-seperate-service-for-assignment-domain.md new file mode 100644 index 0000000..309c793 --- /dev/null +++ b/doc/architecture/decisions/0003-seperate-service-for-assignment-domain.md @@ -0,0 +1,21 @@ +# 3. Seperate service for assignment domain + +Date: 2021-10-18 + +## Status + +Accepted + +## Context + +The Assignment Service handles the assignment of a task to a corresponding and available executor. It keeps track of all the connections between tasks and executors. + +## Decision + +The assignment domain will be its own service. +The assignment service will be a central point in our application. It will have most of the business logic in it and will communicate with all the different services. Therefore, other services can be kind of “dumb” and only need to focus on their simple tasks. +The code of the assignment will change more often than the code of the other services, thus having the assignment service split from the other makes it more deployable. + +## Consequences + +Having this system as its own service we reduce the Fault tolerance because the assignment service can be the single point of failure. We can mitigate this risk by implementing (server) replication and/or having an event driven communication with persisting messages. Therefore, all other services can run independently, and the assignment service can recover from a crash. diff --git a/doc/architecture/decisions/0003-seperate-service-for-roster.md b/doc/architecture/decisions/0003-seperate-service-for-roster.md deleted file mode 100644 index 4cb13fa..0000000 --- a/doc/architecture/decisions/0003-seperate-service-for-roster.md +++ /dev/null @@ -1,21 +0,0 @@ -# 3. Separate service for the Roster - -Date: 2021-11-21 - -## Status - -Accepted - -## Context - -The roster acts as an orchestrator for the system. It communicates directly with the task list, the executors, the executor pool, and the auction house. It handles the assignment of a task to a corresponding and available executor, keeps track of all the connections between tasks and executors, and communicates the status of tasks and executors to other services. - -## Decision - -The Roster domain will be its own service. -The Roster service will be a central point in our application. It will have most of the workflow logic in it and will communicate with all the different services. Therefore, other services can focus on their business logic and be largely ignorant of the overall workflow. -The code of the assignment will change more often than the code of the other services, thus having the assignment service split from the other makes it more deployable. - -## Consequences - -Having this system as its own service will reduce the fault tolerance because the assignment service can be the single point of failure. We can mitigate this risk by implementing (server) replication and/or having an event driven communication with persisting messages. Therefore, all other services can run independently, and the assignment service can recover from a crash. Additionally, we need to ensure a high level of interoperability, since the roster has to communicate with all other parts of the system. \ No newline at end of file diff --git a/doc/architecture/decisions/0004-seperate-service-for-executor-pool.md b/doc/architecture/decisions/0004-seperate-service-for-executor-pool.md new file mode 100644 index 0000000..6c8aea2 --- /dev/null +++ b/doc/architecture/decisions/0004-seperate-service-for-executor-pool.md @@ -0,0 +1,21 @@ +# 4. Seperate service for executor pool + +Date: 2021-10-18 + +## Status + +Accepted + +## Context + +The Executor pool keeps track of the connected executors and their purpose and status. + +## Decision + +We will have a separate service for the executor pool. +There are no other domains which share the same or similar functionality. +The executor pool also scales differently than other services. + +## Consequences + +Having the executor pool as a separate service will help with the deployability of this service but will make the overall structure more complex and reduces testability. diff --git a/doc/architecture/decisions/0004-seperate-service-for-task-list.md b/doc/architecture/decisions/0004-seperate-service-for-task-list.md deleted file mode 100644 index 74ebd93..0000000 --- a/doc/architecture/decisions/0004-seperate-service-for-task-list.md +++ /dev/null @@ -1,20 +0,0 @@ -# 4. Separate service for the Task List - -Date: 2021-11-21 - -## Status - -Accepted - -## Context - -Tasks are created in the task list, and the status of each task (created, assigned, executing, executed) is tracked in the task list as well. The task list mainly communicates with the roster so that tasks can get assigned and the roster will give the task list feedback about the tasks’ status. - -## Decision - -The task list will be its own service. -The task list needs to scale based on the number of active users and the intensity of their activity at any time while the scaling of other parts of the system can be constrained by other factors. - -## Consequences - -Although having the task list as its own service might slightly increase the complexity of the system and decrease the testability, it also makes the system easier to deploy and protective of its data. However, to ensure that this data is always available and does not get lost, the task list needs to be able to recover all its data (the entire history of all tasks) in case it goes down. diff --git a/doc/architecture/decisions/0005-event-driven-communication.md b/doc/architecture/decisions/0005-event-driven-communication.md index 5cb8a48..c711f62 100644 --- a/doc/architecture/decisions/0005-event-driven-communication.md +++ b/doc/architecture/decisions/0005-event-driven-communication.md @@ -4,7 +4,7 @@ Date: 2021-10-18 ## Status -Superceded by [8. Switch to an event-driven microservices architecture](0008-switch-to-an-event-driven-microservices-architecture.md) +Accepted ## Context diff --git a/doc/architecture/decisions/0007-seperate-service-for-auction-house.md b/doc/architecture/decisions/0007-seperate-service-for-auction-house.md deleted file mode 100644 index a218224..0000000 --- a/doc/architecture/decisions/0007-seperate-service-for-auction-house.md +++ /dev/null @@ -1,22 +0,0 @@ -# 7. Seperate service for Auction House - -Date: 2021-11-21 - -## Status - -Accepted - -## Context - -The auction house is the service that can connect to other groups’ auction houses. If there is a task whose task type does not match that of our executors, the auction house can start an auction where other groups can bid on doing the task for us. Moreover, it can also bid on other groups’ auctions. - -## Decision - -The auction house will be its own service. -The auction house is the only part of our system that has external communication; therefore, it makes sense to have it as its own service, also to guarantee better deployability. -The auction house does not scale directly based on the number of tasks, but only the proportion which needs external executors. Moreover, there could be limits on the number of auctions that could be started. Therefore, the auction house scales differently to other services. -Moreover, having the auction house as its own service also improves the fault tolerance of our system. - -## Consequences - -Since the auction house will be a standalone service, we have to make sure that if it goes down, it can recover its data in some way (which auctions it has launched, which auctions it has placed bids on or even won, etc.). Even though the testability and latency of our system might worsen by having a separate service for the auction house, we can implement different kinds of communication for internal and external communication in a much easier way. \ No newline at end of file diff --git a/doc/architecture/decisions/0008-switch-to-an-event-driven-microservices-architecture.md b/doc/architecture/decisions/0008-switch-to-an-event-driven-microservices-architecture.md deleted file mode 100644 index 48e63cc..0000000 --- a/doc/architecture/decisions/0008-switch-to-an-event-driven-microservices-architecture.md +++ /dev/null @@ -1,26 +0,0 @@ -# 8. Switch to an event-driven microservices architecture - -Date: 2021-11-21 - -## Status - -Proposed - -Supercedes [5. Event driven communication](0005-event-driven-communication.md) - -## Context - -Our Tapas App is currently implemented based on a microservice architecture, where the services communicate synchronously via request-response. Each service encapsulates a different bounded context with different functional and non-functional requirements. Internal communication could also be done using asynchronous or event-driven communication. - -## Decision - -Pros: -Scalability: Different services within the Tapas app are not always able to scale at the same rate. For example, we could have thousands of users adding printing tasks at the same time, but maybe we only have one printer. In this scenario we might want to scale the task-list service up to handle the creation load, but scaling up the printing executor operates on a different time-scale (i.e. adding a printer takes time). Moreover, we could have a lot of new tasks coming in, most of which can be executed internally. In this case we want to be able to scale up the task list but might not need to scale up the auction house. Event-driven communication would decrease the coupling of services. Consequently, the scalability of individual services would be enhanced as they no longer depend on the scalability of other services. This improves the apps overall scalability. Since scalability is one of the systems top 3 -ility, this seems quite important. -Fault tolerance: Another of the systems top 3 -ilities is fault tolerance. We could have highly unstable IoT executors that fail often. This should not disrupt the system’s overall operation. The decoupling facilitated by event-driven, asynchronous, communication ensures that when individual services go down, the impact of other services is limited and once they go back up then can recover the systems state from persisted messages. -Cons: -Error handling, workflow control, and event timing: -The aforementioned topics outline the drawbacks of event- driven architecture. These drawbacks can be mitigated by using an orchestrator (like we currently do with the roster) to orchestrate assignment of tasks, auctioning off tasks and error handling when executors fail. More research needed. - -## Consequences - -Consequences to be determined but would relate to the three concepts mentioned as cons. diff --git a/docker-compose-local.yml b/docker-compose-local.yml deleted file mode 100644 index 1ddfc24..0000000 --- a/docker-compose-local.yml +++ /dev/null @@ -1,60 +0,0 @@ -# Dockerfile/Docker-Compose file based on an initial version authored by Alexander Lontke (ASSE, Fall Semester 2021) - -version: "3.7" - -services: - app: - build: - context: ./app - dockerfile: Dockerfile - # Use environment variables instead of application.properties - environment: - - KEY=VALUE - ports: #Just needed when testing from outside the docker network - - "8080:8080" - networks: - - tapas-network - - tapas-tasks: - build: - context: ./tapas-tasks - dockerfile: Dockerfile - # Use environment variables instead of application.properties - environment: - - KEY=VALUE - ports: #Just needed when testing from outside - - "8081:8081" - networks: - - tapas-network - - tapas-auction-house: - build: - context: ./tapas-auction-house - dockerfile: Dockerfile - # Use environment variables instead of application.properties - environment: - - KEY=VALUE - ports: #Just needed when testing from outside - - "8082:8082" - networks: - - tapas-network - - mongodb: - image: mongo - container_name: mongodb - restart: unless-stopped - environment: - MONGO_INITDB_ROOT_USERNAME: root - MONGO_INITDB_ROOT_PASSWORD: 8nP7s0a # Can not be changed again later on - volumes: - - database:/data/db - networks: - - tapas-network - -#Volume for mongodb. One per server. -volumes: - database: - -networks: - tapas-network: - driver: bridge diff --git a/executor-pool/pom.xml b/executor-pool/pom.xml index 512235d..e8e3774 100644 --- a/executor-pool/pom.xml +++ b/executor-pool/pom.xml @@ -68,6 +68,15 @@ org.eclipse.paho.client.mqttv3 1.2.5 compile + + + org.springframework.data + spring-data-mongodb + 3.2.6 + + + org.springframework.boot + spring-boot-starter-data-mongodb diff --git a/executor-pool/src/main/java/ch/unisg/executorpool/adapter/out/persistence/mongodb/ExecutorMapper.java b/executor-pool/src/main/java/ch/unisg/executorpool/adapter/out/persistence/mongodb/ExecutorMapper.java new file mode 100644 index 0000000..8948522 --- /dev/null +++ b/executor-pool/src/main/java/ch/unisg/executorpool/adapter/out/persistence/mongodb/ExecutorMapper.java @@ -0,0 +1,31 @@ +package ch.unisg.executorpool.adapter.out.persistence.mongodb; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.springframework.stereotype.Component; + +import ch.unisg.executorpool.domain.ExecutorClass; + +@Component +public class ExecutorMapper { + + ExecutorClass mapToDomainEntity(MongoExecutorDocument executorClass) { + try { + return new ExecutorClass( + new ExecutorClass.ExecutorUri(new URI(executorClass.executorUri)), + new ExecutorClass.ExecutorTaskType(executorClass.executorTaskType) + ); + } catch (URISyntaxException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return null; + } + } + + MongoExecutorDocument mapToMongoDocument(ExecutorClass executorClass) { + return new MongoExecutorDocument(executorClass.getExecutorUri().getValue().toString(), + executorClass.getExecutorTaskType().getValue() + ); + } +} diff --git a/executor-pool/src/main/java/ch/unisg/executorpool/adapter/out/persistence/mongodb/ExecutorPersistenceAdapter.java b/executor-pool/src/main/java/ch/unisg/executorpool/adapter/out/persistence/mongodb/ExecutorPersistenceAdapter.java new file mode 100644 index 0000000..a165096 --- /dev/null +++ b/executor-pool/src/main/java/ch/unisg/executorpool/adapter/out/persistence/mongodb/ExecutorPersistenceAdapter.java @@ -0,0 +1,40 @@ +package ch.unisg.executorpool.adapter.out.persistence.mongodb; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import ch.unisg.executorpool.application.port.out.AddExecutorPort; +import ch.unisg.executorpool.application.port.out.LoadExecutorPort; +import ch.unisg.executorpool.application.port.out.RemoveExecutorPort; +import ch.unisg.executorpool.domain.ExecutorClass; +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +public class ExecutorPersistenceAdapter implements AddExecutorPort, RemoveExecutorPort, LoadExecutorPort { + + @Autowired + private final ExecutorRepository executorRepository; + + private final ExecutorMapper executorMapper; + + @Override + public void addExecutor(ExecutorClass executorClass) { + MongoExecutorDocument mongoExecutorDocument = executorMapper.mapToMongoDocument(executorClass); + executorRepository.save(mongoExecutorDocument); + } + + @Override + public void removeExecutor(ExecutorClass executorClass) { + MongoExecutorDocument mongoExecutorDocument = executorMapper.mapToMongoDocument(executorClass); + executorRepository.delete(mongoExecutorDocument); + } + + @Override + public ExecutorClass loadExecutor(ExecutorClass.ExecutorUri executorUri, ExecutorClass.ExecutorTaskType executorTaskType) { + MongoExecutorDocument mongoExecutorDocument = executorRepository.findByExecutorUri(executorUri.getValue().toString(), executorTaskType.getValue()); + ExecutorClass executorClass = executorMapper.mapToDomainEntity(mongoExecutorDocument); + return executorClass; + } + +} diff --git a/executor-pool/src/main/java/ch/unisg/executorpool/adapter/out/persistence/mongodb/ExecutorRepository.java b/executor-pool/src/main/java/ch/unisg/executorpool/adapter/out/persistence/mongodb/ExecutorRepository.java new file mode 100644 index 0000000..36c3fd0 --- /dev/null +++ b/executor-pool/src/main/java/ch/unisg/executorpool/adapter/out/persistence/mongodb/ExecutorRepository.java @@ -0,0 +1,15 @@ +package ch.unisg.executorpool.adapter.out.persistence.mongodb; + +import java.util.List; + +import org.springframework.data.mongodb.repository.MongoRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface ExecutorRepository extends MongoRepository { + + public MongoExecutorDocument findByExecutorUri(String executorUri, String executorTaskType); + + public List findByExecutorTaskType(String executorTaskType); + +} diff --git a/executor-pool/src/main/java/ch/unisg/executorpool/adapter/out/persistence/mongodb/MongoExecutorDocument.java b/executor-pool/src/main/java/ch/unisg/executorpool/adapter/out/persistence/mongodb/MongoExecutorDocument.java new file mode 100644 index 0000000..3c94ae7 --- /dev/null +++ b/executor-pool/src/main/java/ch/unisg/executorpool/adapter/out/persistence/mongodb/MongoExecutorDocument.java @@ -0,0 +1,16 @@ +package ch.unisg.executorpool.adapter.out.persistence.mongodb; + +import lombok.Data; + +@Data +public class MongoExecutorDocument { + + public String executorUri; + public String executorTaskType; + + public MongoExecutorDocument(String executorUri, String executorTaskType) { + + this.executorUri = executorUri; + this.executorTaskType = executorTaskType; + } +} diff --git a/executor-pool/src/main/java/ch/unisg/executorpool/application/port/out/AddExecutorPort.java b/executor-pool/src/main/java/ch/unisg/executorpool/application/port/out/AddExecutorPort.java new file mode 100644 index 0000000..8e280e9 --- /dev/null +++ b/executor-pool/src/main/java/ch/unisg/executorpool/application/port/out/AddExecutorPort.java @@ -0,0 +1,9 @@ +package ch.unisg.executorpool.application.port.out; + +import ch.unisg.executorpool.domain.ExecutorClass; + +public interface AddExecutorPort { + + void addExecutor(ExecutorClass executorClass); + +} diff --git a/executor-pool/src/main/java/ch/unisg/executorpool/application/port/out/ExecutorAddedEventPort.java b/executor-pool/src/main/java/ch/unisg/executorpool/application/port/out/ExecutorAddedEventPort.java index ad75c75..a94cf16 100644 --- a/executor-pool/src/main/java/ch/unisg/executorpool/application/port/out/ExecutorAddedEventPort.java +++ b/executor-pool/src/main/java/ch/unisg/executorpool/application/port/out/ExecutorAddedEventPort.java @@ -1,7 +1,6 @@ package ch.unisg.executorpool.application.port.out; import ch.unisg.executorpool.domain.ExecutorAddedEvent; -import org.eclipse.paho.client.mqttv3.MqttException; public interface ExecutorAddedEventPort { void publishExecutorAddedEvent(ExecutorAddedEvent event); diff --git a/executor-pool/src/main/java/ch/unisg/executorpool/application/port/out/LoadExecutorPort.java b/executor-pool/src/main/java/ch/unisg/executorpool/application/port/out/LoadExecutorPort.java new file mode 100644 index 0000000..d7cb18a --- /dev/null +++ b/executor-pool/src/main/java/ch/unisg/executorpool/application/port/out/LoadExecutorPort.java @@ -0,0 +1,9 @@ +package ch.unisg.executorpool.application.port.out; + +import ch.unisg.executorpool.domain.ExecutorClass; + +public interface LoadExecutorPort { + + ExecutorClass loadExecutor(ExecutorClass.ExecutorUri executorUri, ExecutorClass.ExecutorTaskType executorTaskType); + +} diff --git a/executor-pool/src/main/java/ch/unisg/executorpool/application/port/out/RemoveExecutorPort.java b/executor-pool/src/main/java/ch/unisg/executorpool/application/port/out/RemoveExecutorPort.java new file mode 100644 index 0000000..5813891 --- /dev/null +++ b/executor-pool/src/main/java/ch/unisg/executorpool/application/port/out/RemoveExecutorPort.java @@ -0,0 +1,9 @@ +package ch.unisg.executorpool.application.port.out; + +import ch.unisg.executorpool.domain.ExecutorClass; + +public interface RemoveExecutorPort { + + void removeExecutor(ExecutorClass executorClass); + +} diff --git a/executor-pool/src/main/java/ch/unisg/executorpool/application/service/AddNewExecutorToExecutorPoolService.java b/executor-pool/src/main/java/ch/unisg/executorpool/application/service/AddNewExecutorToExecutorPoolService.java index 393024a..5ce3ee4 100644 --- a/executor-pool/src/main/java/ch/unisg/executorpool/application/service/AddNewExecutorToExecutorPoolService.java +++ b/executor-pool/src/main/java/ch/unisg/executorpool/application/service/AddNewExecutorToExecutorPoolService.java @@ -2,11 +2,11 @@ package ch.unisg.executorpool.application.service; import ch.unisg.executorpool.application.port.in.AddNewExecutorToExecutorPoolUseCase; import ch.unisg.executorpool.application.port.in.AddNewExecutorToExecutorPoolCommand; +import ch.unisg.executorpool.application.port.out.AddExecutorPort; import ch.unisg.executorpool.application.port.out.ExecutorAddedEventPort; import ch.unisg.executorpool.domain.ExecutorAddedEvent; import ch.unisg.executorpool.domain.ExecutorClass; import ch.unisg.executorpool.domain.ExecutorPool; -import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import javax.transaction.Transactional; @@ -16,9 +16,11 @@ import javax.transaction.Transactional; public class AddNewExecutorToExecutorPoolService implements AddNewExecutorToExecutorPoolUseCase { private final ExecutorAddedEventPort executorAddedEventPort; + private final AddExecutorPort addExecutorToRepositoryPort; - public AddNewExecutorToExecutorPoolService(ExecutorAddedEventPort executorAddedEventPort){ + public AddNewExecutorToExecutorPoolService(ExecutorAddedEventPort executorAddedEventPort, AddExecutorPort addExecutorToRepositoryPort){ this.executorAddedEventPort = executorAddedEventPort; + this.addExecutorToRepositoryPort = addExecutorToRepositoryPort; } @Override @@ -29,6 +31,8 @@ public class AddNewExecutorToExecutorPoolService implements AddNewExecutorToExec var executorAddedEvent = new ExecutorAddedEvent(newExecutor); executorAddedEventPort.publishExecutorAddedEvent(executorAddedEvent); + addExecutorToRepositoryPort.addExecutor(newExecutor); + return newExecutor; } } diff --git a/executor-pool/src/main/java/ch/unisg/executorpool/application/service/RemoveExecutorFromExecutorPoolService.java b/executor-pool/src/main/java/ch/unisg/executorpool/application/service/RemoveExecutorFromExecutorPoolService.java index 4d2457d..0fc724c 100644 --- a/executor-pool/src/main/java/ch/unisg/executorpool/application/service/RemoveExecutorFromExecutorPoolService.java +++ b/executor-pool/src/main/java/ch/unisg/executorpool/application/service/RemoveExecutorFromExecutorPoolService.java @@ -3,10 +3,10 @@ package ch.unisg.executorpool.application.service; import ch.unisg.executorpool.application.port.in.RemoveExecutorFromExecutorPoolCommand; import ch.unisg.executorpool.application.port.in.RemoveExecutorFromExecutorPoolUseCase; import ch.unisg.executorpool.application.port.out.ExecutorRemovedEventPort; +import ch.unisg.executorpool.application.port.out.RemoveExecutorPort; import ch.unisg.executorpool.domain.ExecutorClass; import ch.unisg.executorpool.domain.ExecutorPool; import ch.unisg.executorpool.domain.ExecutorRemovedEvent; -import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; import javax.transaction.Transactional; @@ -17,9 +17,11 @@ import java.util.Optional; public class RemoveExecutorFromExecutorPoolService implements RemoveExecutorFromExecutorPoolUseCase { private final ExecutorRemovedEventPort executorRemovedEventPort; + private final RemoveExecutorPort removeExecutorFromRepositoryPort; - public RemoveExecutorFromExecutorPoolService(ExecutorRemovedEventPort executorRemovedEventPort){ + public RemoveExecutorFromExecutorPoolService(ExecutorRemovedEventPort executorRemovedEventPort, RemoveExecutorPort removeExecutorFromRepositoryPort){ this.executorRemovedEventPort = executorRemovedEventPort; + this.removeExecutorFromRepositoryPort = removeExecutorFromRepositoryPort; } @Override @@ -32,6 +34,8 @@ public class RemoveExecutorFromExecutorPoolService implements RemoveExecutorFrom executorRemovedEventPort.publishExecutorRemovedEvent(executorRemovedEvent); } + removeExecutorFromRepositoryPort.removeExecutor(removedExecutor); + return removedExecutor; } } diff --git a/executor-pool/src/main/java/ch/unisg/executorpool/domain/ExecutorRemovedEvent.java b/executor-pool/src/main/java/ch/unisg/executorpool/domain/ExecutorRemovedEvent.java index a038928..417e8a7 100644 --- a/executor-pool/src/main/java/ch/unisg/executorpool/domain/ExecutorRemovedEvent.java +++ b/executor-pool/src/main/java/ch/unisg/executorpool/domain/ExecutorRemovedEvent.java @@ -1,6 +1,5 @@ package ch.unisg.executorpool.domain; -import ch.unisg.executorpool.domain.ExecutorClass; import lombok.Getter; public class ExecutorRemovedEvent { diff --git a/tapas-auction-house/BROKERS.md b/tapas-auction-house/BROKERS.md index 80eed02..7e0d37a 100644 --- a/tapas-auction-house/BROKERS.md +++ b/tapas-auction-house/BROKERS.md @@ -14,8 +14,10 @@ Running this WebSub Hub implementation requires Docker, Node.js, and npm: ### How to run ```shell -docker run -d -p 27017:27017 -p 28017:28017 -e AUTH=no mongo:latest -npm i -g websub-hub +git clone https://github.com/hemerajs/websub-hub.git +cd websub-hub +docker run -d -p 27017:27017 -p 28017:28017 -e AUTH=no tutum/mongodb +npm i -g websub-hub-cli websub-hub -l info -m mongodb://localhost:27017/hub ``` diff --git a/tapas-auction-house/Dockerfile b/tapas-auction-house/Dockerfile deleted file mode 100644 index fcc6d83..0000000 --- a/tapas-auction-house/Dockerfile +++ /dev/null @@ -1,13 +0,0 @@ -# Dockerfile/Docker-Compose file based on an initial version authored by Alexander Lontke (ASSE, Fall Semester 2021) - -FROM maven as build - -COPY . /app - -RUN mvn -f app/pom.xml --batch-mode --update-snapshots verify - -FROM openjdk - -COPY --from=build /app/target/tapas-auction-house-0.0.1-SNAPSHOT.jar ./tapas-auction-house-0.0.1-SNAPSHOT.jar - -CMD java -jar tapas-auction-house-0.0.1-SNAPSHOT.jar diff --git a/tapas-auction-house/src/main/java/ch/unisg/tapas/TapasAuctionHouseApplication.java b/tapas-auction-house/src/main/java/ch/unisg/tapas/TapasAuctionHouseApplication.java index ee66761..476c7d0 100644 --- a/tapas-auction-house/src/main/java/ch/unisg/tapas/TapasAuctionHouseApplication.java +++ b/tapas-auction-house/src/main/java/ch/unisg/tapas/TapasAuctionHouseApplication.java @@ -29,7 +29,6 @@ public class TapasAuctionHouseApplication { private static ConfigurableEnvironment ENVIRONMENT; - public static void main(String[] args) { SpringApplication tapasAuctioneerApp = new SpringApplication(TapasAuctionHouseApplication.class); ENVIRONMENT = tapasAuctioneerApp.run(args).getEnvironment(); diff --git a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/web/WinningBidWebController.java b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/web/WinningBidWebController.java index e4c5aa1..9d252b5 100644 --- a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/web/WinningBidWebController.java +++ b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/in/web/WinningBidWebController.java @@ -35,7 +35,7 @@ public class WinningBidWebController { try { var body = payload.serialize(); LOGGER.info(body); - var postURI = URI.create("https://tapas-tasks.86-119-35-40.nip.io/tasks/"); + var postURI = URI.create(taskListURI + "/tasks/"); HttpRequest postRequest = HttpRequest.newBuilder() .uri(postURI) .header("Content-Type", TaskJsonRepresentation.MEDIA_TYPE) diff --git a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/web/AuctionWonEventHttpAdapter.java b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/web/AuctionWonEventHttpAdapter.java index ec04b2b..9dc1508 100644 --- a/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/web/AuctionWonEventHttpAdapter.java +++ b/tapas-auction-house/src/main/java/ch/unisg/tapas/auctionhouse/adapter/out/web/AuctionWonEventHttpAdapter.java @@ -68,7 +68,7 @@ public class AuctionWonEventHttpAdapter implements AuctionWonEventPort { .POST(HttpRequest.BodyPublishers.ofString(body)) .build(); - var postResponse = client.send(postRequest, HttpResponse.BodyHandlers.ofString()); + var postResponse = client.send(request, HttpResponse.BodyHandlers.ofString()); LOGGER.info(postResponse.statusCode()); } catch (IOException e) { diff --git a/tapas-auction-house/src/main/resources/application.properties b/tapas-auction-house/src/main/resources/application.properties index dd9735d..78bda13 100644 --- a/tapas-auction-house/src/main/resources/application.properties +++ b/tapas-auction-house/src/main/resources/application.properties @@ -1,7 +1,5 @@ server.port=8086 -broker.mqtt=tcp://broker.hivemq.com - websub.hub=https://websub.appspot.com/ websub.hub.publish=https://websub.appspot.com/ diff --git a/tapas-tasks/README.md b/tapas-tasks/README.md index 55f120f..90016c3 100644 --- a/tapas-tasks/README.md +++ b/tapas-tasks/README.md @@ -167,25 +167,3 @@ Date: Sun, 17 Oct 2021 21:32:25 GMT Internally, this request is mapped to a [TaskExecutedEvent](src/main/java/ch/unisg/tapastasks/tasks/application/port/in/TaskExecutedEvent.java). The HTTP response returns a `200 OK` status code together with the updated representation of the task. - -## Working with MongoDB -The provided TAPAS Tasks service is connected to a MongoDB as a repository for persisting data. - -Here are some pointers to start integrating the MongoDB with the other microservices: -* [application.properties](src/main/resources/application.properties) defines the - * URI of the DB server that Spring will connect to (`mongodb`service running in Docker container). Username and password for the server can be found in [docker-compose.yml](../docker-compose.yml). - * Name of the database for the microservice (`tapas-tasks`) -* [docker-compose.yml](../docker-compose.yml) defines - * in lines 74-82: the configuration of the mongodb service based on the mongodb container including the root username and password (once deployed this cannot be changed anymore!) - * in lines 84-102: the configuration of a web application called `mongo-express` to manage the MongoDB server. The web app can be reached via the URI: [http://dbadmin.${PUB_IP}.nip.io]([http://dbadmin.${PUB_IP}.nip.io]). Login credentials for mongo-express can be found in lines 89 and 90. - * in lines 104-105: the volume to be used by the mongodb service for writing and storing data (do not forget!). -* The [pom.xml](./pom.xml) needs to have `spring-boot-starter-data-mongodb` and `spring-data-mongodb` as new dependencies. -* The [TapasTasksApplication.java](/src/main/java/ch/unisg/tapastasks/TapasTasksApplication.java) specifies in line 9 the location of the MongoRepository classes for the microservice. -* The [persistence.mongodb](/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb) package has the relevant classes to work with MongoDB: - * The [MongoTaskDocument.java](/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/MongoTaskDocument.java) class defines the attributes of a Document for storing a task in the collection `tasks`. - * The [TaskRepository.java](/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskRepository.java) class specifies the MongoRepository. - * The [TaskPersistenceAdapter.java](/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskPersistenceAdapter.java) implements the two ports to add a new task ([AddTaskPort](/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/AddTaskPort.java)) and retrieve a task ([LoadTaskPort](/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/LoadTaskPort.java)). These ports are used in the classes [AddNewTaskToTaskListService.java](/src/main/java/ch/unisg/tapastasks/tasks/application/service/AddNewTaskToTaskListService.java) and [RetrieveTaskFromTaskListService.java](/src/main/java/ch/unisg/tapastasks/tasks/application/service/RetrieveTaskFromTaskListService.java). - -#### General hints: -* To not overload the VMs we recommend to use only one MongoDB server that all microservices connect to. Per microservice you could use one database or one collection (discuss in your ADRs!). To use more than one MongoDB server you have to extend the [docker-compose.yml](../docker-compose.yml) file by basically replicating lines 74-105 and changing the names of the services and volumes to be unique (ask your tutors!). -* For local testing you have to install the MongoDB server locally on your computers and change the `spring.data.mongodb.uri` String in [application.properties](./src/main/resources/application.properties). diff --git a/tapas-tasks/pom.xml b/tapas-tasks/pom.xml index 74a60f9..715b947 100644 --- a/tapas-tasks/pom.xml +++ b/tapas-tasks/pom.xml @@ -29,25 +29,6 @@ org.springframework.boot spring-boot-starter-web - - org.springframework.data - spring-data-mongodb - 3.2.6 - - - org.springframework.boot - spring-boot-starter-data-mongodb - - - - org.springframework.boot - spring-boot-starter-actuator - - - de.codecentric - chaos-monkey-spring-boot - 2.5.4 - org.projectlombok @@ -59,17 +40,6 @@ spring-boot-starter-test test - - org.mockito - mockito-core - 2.21.0 - - - com.tngtech.archunit - archunit-junit4 - 0.22.0 - test - org.springframework.boot @@ -114,10 +84,7 @@ 0.0.20131108.vaadin1 compile - - org.springframework.boot - spring-boot-test - + diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/TapasTasksApplication.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/TapasTasksApplication.java index 78a6145..2675391 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/TapasTasksApplication.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/TapasTasksApplication.java @@ -1,20 +1,14 @@ package ch.unisg.tapastasks; -import ch.unisg.tapastasks.tasks.adapter.out.persistence.mongodb.TaskRepository; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; @SpringBootApplication -@EnableMongoRepositories(basePackageClasses = TaskRepository.class) public class TapasTasksApplication { public static void main(String[] args) { SpringApplication tapasTasksApp = new SpringApplication(TapasTasksApplication.class); tapasTasksApp.run(args); - - - } } diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/MongoTaskDocument.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/MongoTaskDocument.java deleted file mode 100644 index 442e01e..0000000 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/MongoTaskDocument.java +++ /dev/null @@ -1,32 +0,0 @@ -package ch.unisg.tapastasks.tasks.adapter.out.persistence.mongodb; - -import lombok.Data; -import org.springframework.data.annotation.Id; -import org.springframework.data.mongodb.core.mapping.Document; - -@Data -@Document(collection = "tasks") -public class MongoTaskDocument { - - @Id - public String taskId; - - public String taskName; - public String taskType; - public String originalTaskUri; - public String taskStatus; - public String taskListName; - - - public MongoTaskDocument(String taskId, String taskName, String taskType, - String originalTaskUri, - String taskStatus, String taskListName) { - - this.taskId = taskId; - this.taskName = taskName; - this.taskType = taskType; - this.originalTaskUri = originalTaskUri; - this.taskStatus = taskStatus; - this.taskListName = taskListName; - } -} diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskMapper.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskMapper.java deleted file mode 100644 index 0af73b6..0000000 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskMapper.java +++ /dev/null @@ -1,30 +0,0 @@ -package ch.unisg.tapastasks.tasks.adapter.out.persistence.mongodb; - -import ch.unisg.tapastasks.tasks.domain.Task; -import ch.unisg.tapastasks.tasks.domain.TaskList; -import org.springframework.stereotype.Component; - -@Component -class TaskMapper { - - Task mapToDomainEntity(MongoTaskDocument task) { - return Task.withIdNameTypeOriginaluriStatus( - new Task.TaskId(task.taskId), - new Task.TaskName(task.taskName), - new Task.TaskType(task.taskType), - new Task.OriginalTaskUri(task.originalTaskUri), - new Task.TaskStatus(Task.Status.valueOf(task.taskStatus)) - ); - } - - MongoTaskDocument mapToMongoDocument(Task task) { - return new MongoTaskDocument( - task.getTaskId().getValue(), - task.getTaskName().getValue(), - task.getTaskType().getValue(), - task.getOriginalTaskUri().getValue(), - task.getTaskStatus().getValue().toString(), - TaskList.getTapasTaskList().getTaskListName().getValue() - ); - } -} diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskPersistenceAdapter.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskPersistenceAdapter.java deleted file mode 100644 index beabf63..0000000 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskPersistenceAdapter.java +++ /dev/null @@ -1,34 +0,0 @@ -package ch.unisg.tapastasks.tasks.adapter.out.persistence.mongodb; - -import ch.unisg.tapastasks.tasks.application.port.out.AddTaskPort; -import ch.unisg.tapastasks.tasks.application.port.out.LoadTaskPort; -import ch.unisg.tapastasks.tasks.domain.Task; -import ch.unisg.tapastasks.tasks.domain.TaskList; -import lombok.RequiredArgsConstructor; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -@Component -@RequiredArgsConstructor -public class TaskPersistenceAdapter implements - AddTaskPort, - LoadTaskPort { - - @Autowired - private final TaskRepository taskRepository; - - private final TaskMapper taskMapper; - - @Override - public void addTask(Task task) { - MongoTaskDocument mongoTaskDocument = taskMapper.mapToMongoDocument(task); - taskRepository.save(mongoTaskDocument); - } - - @Override - public Task loadTask(Task.TaskId taskId, TaskList.TaskListName taskListName) { - MongoTaskDocument mongoTaskDocument = taskRepository.findByTaskId(taskId.getValue(),taskListName.getValue()); - Task task = taskMapper.mapToDomainEntity(mongoTaskDocument); - return task; - } -} diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskRepository.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskRepository.java deleted file mode 100644 index 867671c..0000000 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package ch.unisg.tapastasks.tasks.adapter.out.persistence.mongodb; - -import org.springframework.data.mongodb.repository.MongoRepository; -import org.springframework.stereotype.Repository; - -import java.util.List; - -@Repository -public interface TaskRepository extends MongoRepository { - - public MongoTaskDocument findByTaskId(String taskId, String taskListName); - - public List findByTaskListName(String taskListName); -} diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/web/ExternalTaskExecutedWebAdapter.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/web/ExternalTaskExecutedWebAdapter.java index c0e3651..8e6f106 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/web/ExternalTaskExecutedWebAdapter.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/adapter/out/web/ExternalTaskExecutedWebAdapter.java @@ -44,7 +44,7 @@ public class ExternalTaskExecutedWebAdapter implements ExternalTaskExecutedEvent op2 = new JSONObject() .put("op", "add") .put("path", "/outputData") - .put("value", externalTaskExecutedEvent.getOutputData()); + .put("value", "0"); } catch (JSONException e) { logger.log(Level.SEVERE, e.getLocalizedMessage(), e); return; @@ -55,7 +55,7 @@ public class ExternalTaskExecutedWebAdapter implements ExternalTaskExecutedEvent HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(externalTaskExecutedEvent.getOriginalTaskUri().getValue())) - .header("Content-Type", TaskJsonPatchRepresentation.MEDIA_TYPE) + .header("Content-Type", "application/json") .method("PATCH", HttpRequest.BodyPublishers.ofString(body)) .build(); diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/AddTaskPort.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/AddTaskPort.java deleted file mode 100644 index b87795d..0000000 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/AddTaskPort.java +++ /dev/null @@ -1,9 +0,0 @@ -package ch.unisg.tapastasks.tasks.application.port.out; - -import ch.unisg.tapastasks.tasks.domain.Task; - -public interface AddTaskPort { - - void addTask(Task task); - -} diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/LoadTaskPort.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/LoadTaskPort.java deleted file mode 100644 index acca3c0..0000000 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/LoadTaskPort.java +++ /dev/null @@ -1,10 +0,0 @@ -package ch.unisg.tapastasks.tasks.application.port.out; - -import ch.unisg.tapastasks.tasks.domain.Task; -import ch.unisg.tapastasks.tasks.domain.TaskList; - -public interface LoadTaskPort { - - Task loadTask(Task.TaskId taskId, TaskList.TaskListName taskListName); - -} diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/TaskListLock.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/TaskListLock.java deleted file mode 100644 index 802abba..0000000 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/port/out/TaskListLock.java +++ /dev/null @@ -1,11 +0,0 @@ -package ch.unisg.tapastasks.tasks.application.port.out; - -import ch.unisg.tapastasks.tasks.domain.TaskList; - -public interface TaskListLock { - - void lockTaskList(TaskList.TaskListName taskListName); - - void releaseTaskList(TaskList.TaskListName taskListName); - -} diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/AddNewTaskToTaskListService.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/AddNewTaskToTaskListService.java index b390548..d7b9740 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/AddNewTaskToTaskListService.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/AddNewTaskToTaskListService.java @@ -2,35 +2,26 @@ package ch.unisg.tapastasks.tasks.application.service; import ch.unisg.tapastasks.tasks.application.port.in.AddNewTaskToTaskListCommand; import ch.unisg.tapastasks.tasks.application.port.in.AddNewTaskToTaskListUseCase; -import ch.unisg.tapastasks.tasks.application.port.out.AddTaskPort; import ch.unisg.tapastasks.tasks.application.port.out.NewTaskAddedEventPort; -import ch.unisg.tapastasks.tasks.application.port.out.TaskListLock; import ch.unisg.tapastasks.tasks.domain.Task; import ch.unisg.tapastasks.tasks.domain.NewTaskAddedEvent; import ch.unisg.tapastasks.tasks.domain.TaskList; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -import org.springframework.stereotype.Service; - import javax.transaction.Transactional; @RequiredArgsConstructor @Component @Transactional -@Service("AddNewTaskToTaskList") public class AddNewTaskToTaskListService implements AddNewTaskToTaskListUseCase { private final NewTaskAddedEventPort newTaskAddedEventPort; - private final AddTaskPort addTaskToRepositoryPort; - private final TaskListLock taskListLock; @Override public Task addNewTaskToTaskList(AddNewTaskToTaskListCommand command) { TaskList taskList = TaskList.getTapasTaskList(); - taskListLock.lockTaskList(taskList.getTaskListName()); - Task newTask; if (command.getOriginalTaskUri().isPresent() && command.getInputData().isPresent()) { @@ -46,9 +37,6 @@ public class AddNewTaskToTaskListService implements AddNewTaskToTaskListUseCase newTask = taskList.addNewTaskWithNameAndType(command.getTaskName(), command.getTaskType()); } - addTaskToRepositoryPort.addTask(newTask); - taskListLock.releaseTaskList(taskList.getTaskListName()); - //Here we are using the application service to emit the domain event to the outside of the bounded context. //This event should be considered as a light-weight "integration event" to communicate with other services. //Domain events are usually rather "fat". In our implementation we simplify at this point. In general, it is diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/NoOpTaskListLock.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/NoOpTaskListLock.java deleted file mode 100644 index 783dca1..0000000 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/NoOpTaskListLock.java +++ /dev/null @@ -1,18 +0,0 @@ -package ch.unisg.tapastasks.tasks.application.service; - -import ch.unisg.tapastasks.tasks.application.port.out.TaskListLock; -import ch.unisg.tapastasks.tasks.domain.TaskList; -import org.springframework.stereotype.Component; - -@Component -public class NoOpTaskListLock implements TaskListLock { - @Override - public void lockTaskList(TaskList.TaskListName taskListName) { - //do nothing - } - - @Override - public void releaseTaskList(TaskList.TaskListName taskListName) { - //do nothing - } -} diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/RetrieveTaskFromTaskListService.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/RetrieveTaskFromTaskListService.java index 39026f5..fd6aea5 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/RetrieveTaskFromTaskListService.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/application/service/RetrieveTaskFromTaskListService.java @@ -2,12 +2,10 @@ package ch.unisg.tapastasks.tasks.application.service; import ch.unisg.tapastasks.tasks.application.port.in.RetrieveTaskFromTaskListQuery; import ch.unisg.tapastasks.tasks.application.port.in.RetrieveTaskFromTaskListUseCase; -import ch.unisg.tapastasks.tasks.application.port.out.LoadTaskPort; import ch.unisg.tapastasks.tasks.domain.Task; import ch.unisg.tapastasks.tasks.domain.TaskList; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; -import org.springframework.stereotype.Service; import javax.transaction.Transactional; import java.util.Optional; @@ -15,19 +13,10 @@ import java.util.Optional; @RequiredArgsConstructor @Component @Transactional -@Service("RetrieveTaskFromTaskList") public class RetrieveTaskFromTaskListService implements RetrieveTaskFromTaskListUseCase { - - private final LoadTaskPort loadTaskFromRepositoryPort; - @Override public Optional retrieveTaskFromTaskList(RetrieveTaskFromTaskListQuery query) { TaskList taskList = TaskList.getTapasTaskList(); - - Optional task = taskList.retrieveTaskById(query.getTaskId()); - - Optional taskFromRepo = Optional.ofNullable(loadTaskFromRepositoryPort.loadTask(query.getTaskId(), taskList.getTaskListName())); - - return taskFromRepo; + return taskList.retrieveTaskById(query.getTaskId()); } } diff --git a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/domain/Task.java b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/domain/Task.java index 666a16a..aca71dd 100644 --- a/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/domain/Task.java +++ b/tapas-tasks/src/main/java/ch/unisg/tapastasks/tasks/domain/Task.java @@ -80,22 +80,11 @@ public class Task { this.outputData = null; } - public Task(TaskId taskId, TaskName taskName, TaskType taskType, OriginalTaskUri taskUri, - TaskStatus taskStatus) { -this.taskId = taskId; -this.taskName = taskName; -this.taskType = taskType; -this.originalTaskUri = taskUri; -this.taskStatus = taskStatus; -this.inputData = null; -this.outputData = null; -} protected static Task createTaskWithNameAndType(TaskName name, TaskType type) { return new Task(name, type); - } - public static Task createTaskWithNameAndTypeAndOriginalTaskUri(TaskName name, TaskType type, + protected static Task createTaskWithNameAndTypeAndOriginalTaskUri(TaskName name, TaskType type, OriginalTaskUri originalTaskUri) { return new Task(name, type, originalTaskUri); } @@ -110,13 +99,6 @@ this.outputData = null; return new Task(name, type, originalTaskUri, inputData); } - public static Task withIdNameTypeOriginaluriStatus(TaskId taskId, TaskName taskName, - TaskType taskType, - OriginalTaskUri originalTaskUri, - TaskStatus taskStatus) { - return new Task(taskId, taskName, taskType, originalTaskUri, taskStatus); - } - @Value public static class TaskId { String value; diff --git a/tapas-tasks/src/main/resources/application.properties b/tapas-tasks/src/main/resources/application.properties index 3b5922b..485e4e7 100644 --- a/tapas-tasks/src/main/resources/application.properties +++ b/tapas-tasks/src/main/resources/application.properties @@ -1,40 +1,3 @@ server.port=8081 -spring.data.mongodb.uri=mongodb://127.0.0.1:27017 -#spring.data.mongodb.uri=mongodb://root:8nP7s0a@mongodb:27017/ -spring.data.mongodb.database=tapas-tasks baseuri=https://tapas-tasks.86-119-34-23.nip.io/ - roster.uri=http://127.0.0.1:8082 - -spring.profiles.active=chaos-monkey -chaos.monkey.enabled=true -management.endpoint.chaosmonkey.enabled=true -management.endpoint.chaosmonkeyjmx.enabled=true -# include specific endpoints -management.endpoints.web.exposure.include=health,info,chaosmonkey -chaos.monkey.watcher.controller=true -chaos.monkey.watcher.restController=true -chaos.monkey.watcher.service=true -chaos.monkey.watcher.repository=true -chaos.monkey.watcher.component=true - -#Chaos Monkey configs taken from here: https://www.baeldung.com/spring-boot-chaos-monkey - -#Latency Assault -#chaos.monkey.assaults.latencyActive=true -#chaos.monkey.assaults.latencyRangeStart=3000 -#chaos.monkey.assaults.latencyRangeEnd=15000 - -#Exception Assault -#chaos.monkey.assaults.latencyActive=false -#chaos.monkey.assaults.exceptionsActive=true -#chaos.monkey.assaults.killApplicationActive=false - -#AppKiller Assault -#chaos.monkey.assaults.latencyActive=false -#chaos.monkey.assaults.exceptionsActive=false -#chaos.monkey.assaults.killApplicationActive=true - -#Chaos Monkey assaults via REST to endpoint /actuator/chaosmonkey/assaults/ -#https://softwarehut.com/blog/tech/chaos-monkey -#https://codecentric.github.io/chaos-monkey-spring-boot/latest/ diff --git a/tapas-tasks/src/test/java/ch/unisg/tapastasks/AddNewTaskToTaskListSystemTest.java b/tapas-tasks/src/test/java/ch/unisg/tapastasks/AddNewTaskToTaskListSystemTest.java deleted file mode 100644 index e17c2e2..0000000 --- a/tapas-tasks/src/test/java/ch/unisg/tapastasks/AddNewTaskToTaskListSystemTest.java +++ /dev/null @@ -1,76 +0,0 @@ -package ch.unisg.tapastasks; - -import ch.unisg.tapastasks.tasks.adapter.in.formats.TaskJsonRepresentation; -import ch.unisg.tapastasks.tasks.application.port.out.AddTaskPort; -import ch.unisg.tapastasks.tasks.domain.Task; -import ch.unisg.tapastasks.tasks.domain.TaskList; -import org.json.JSONException; -import org.json.JSONObject; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.*; - -import static org.assertj.core.api.BDDAssertions.*; - - -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -public class AddNewTaskToTaskListSystemTest { - - @Autowired - private TestRestTemplate restTemplate; - - @Autowired - private AddTaskPort addTaskPort; - - @Test - void addNewTaskToTaskList() throws JSONException { - - Task.TaskName taskName = new Task.TaskName("system-integration-test-task"); - Task.TaskType taskType = new Task.TaskType("system-integration-test-type"); - Task.OriginalTaskUri originalTaskUri = new Task.OriginalTaskUri("example.org"); - - ResponseEntity response = whenAddNewTaskToEmptyList(taskName, taskType, originalTaskUri); - - JSONObject responseJson = new JSONObject(response.getBody().toString()); - String respTaskId = responseJson.getString("taskId"); - String respTaskName = responseJson.getString("taskName"); - String respTaskType = responseJson.getString("taskType"); - - then(response.getStatusCode()).isEqualTo(HttpStatus.CREATED); - then(respTaskId).isNotEmpty(); - then(respTaskName).isEqualTo(taskName.getValue()); - then(respTaskType).isEqualTo(taskType.getValue()); - then(TaskList.getTapasTaskList().getListOfTasks().getValue()).hasSize(1); - - } - - private ResponseEntity whenAddNewTaskToEmptyList( - Task.TaskName taskName, - Task.TaskType taskType, - Task.OriginalTaskUri originalTaskUri) throws JSONException { - - TaskList.getTapasTaskList().getListOfTasks().getValue().clear(); - - HttpHeaders headers = new HttpHeaders(); - headers.add("Content-Type", TaskJsonRepresentation.MEDIA_TYPE); - - String jsonPayLoad = new JSONObject() - .put("taskName", taskName.getValue() ) - .put("taskType", taskType.getValue()) - .put("originalTaskUri",originalTaskUri.getValue()) - .toString(); - - HttpEntity request = new HttpEntity<>(jsonPayLoad,headers); - - return restTemplate.exchange( - "/tasks/", - HttpMethod.POST, - request, - Object.class - ); - - } - -} diff --git a/tapas-tasks/src/test/java/ch/unisg/tapastasks/DependencyRuleTests.java b/tapas-tasks/src/test/java/ch/unisg/tapastasks/DependencyRuleTests.java deleted file mode 100644 index 0d26f37..0000000 --- a/tapas-tasks/src/test/java/ch/unisg/tapastasks/DependencyRuleTests.java +++ /dev/null @@ -1,24 +0,0 @@ -package ch.unisg.tapastasks; - -import ch.unisg.tapastasks.archunit.HexagonalArchitecture; -import com.tngtech.archunit.core.importer.ClassFileImporter; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; - -import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; - -class DependencyRuleTests { - - @Test - void testPackageDependencies() { - noClasses() - .that() - .resideInAPackage("ch.unisg.tapastasks.tasks.domain..") - .should() - .dependOnClassesThat() - .resideInAnyPackage("ch.unisg.tapastasks.tasks.application..") - .check(new ClassFileImporter() - .importPackages("ch.unisg.tapastasks.tasks..")); - } - -} diff --git a/tapas-tasks/src/test/java/ch/unisg/tapastasks/TapasTasksApplicationTests.java b/tapas-tasks/src/test/java/ch/unisg/tapastasks/TapasTasksApplicationTests.java index a343151..b96cb8b 100644 --- a/tapas-tasks/src/test/java/ch/unisg/tapastasks/TapasTasksApplicationTests.java +++ b/tapas-tasks/src/test/java/ch/unisg/tapastasks/TapasTasksApplicationTests.java @@ -1,18 +1,13 @@ package ch.unisg.tapastasks; -import ch.unisg.tapastasks.tasks.application.port.out.AddTaskPort; -import ch.unisg.tapastasks.tasks.application.port.out.NewTaskAddedEventPort; -import ch.unisg.tapastasks.tasks.application.port.out.TaskListLock; -import ch.unisg.tapastasks.tasks.application.service.AddNewTaskToTaskListService; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class TapasTasksApplicationTests { - @Test + @Test void contextLoads() { - } } diff --git a/tapas-tasks/src/test/java/ch/unisg/tapastasks/archunit/Adapters.java b/tapas-tasks/src/test/java/ch/unisg/tapastasks/archunit/Adapters.java deleted file mode 100644 index 92a764b..0000000 --- a/tapas-tasks/src/test/java/ch/unisg/tapastasks/archunit/Adapters.java +++ /dev/null @@ -1,62 +0,0 @@ -package ch.unisg.tapastasks.archunit; - -import com.tngtech.archunit.core.domain.JavaClasses; - -import java.util.ArrayList; -import java.util.List; - -public class Adapters extends ArchitectureElement { - - private final HexagonalArchitecture parentContext; - private List incomingAdapterPackages = new ArrayList<>(); - private List outgoingAdapterPackages = new ArrayList<>(); - - Adapters(HexagonalArchitecture parentContext, String basePackage) { - super(basePackage); - this.parentContext = parentContext; - } - - public Adapters outgoing(String packageName) { - this.incomingAdapterPackages.add(fullQualifiedPackage(packageName)); - return this; - } - - public Adapters incoming(String packageName) { - this.outgoingAdapterPackages.add(fullQualifiedPackage(packageName)); - return this; - } - - List allAdapterPackages() { - List allAdapters = new ArrayList<>(); - allAdapters.addAll(incomingAdapterPackages); - allAdapters.addAll(outgoingAdapterPackages); - return allAdapters; - } - - public HexagonalArchitecture and() { - return parentContext; - } - - String getBasePackage() { - return basePackage; - } - - void dontDependOnEachOther(JavaClasses classes) { - List allAdapters = allAdapterPackages(); - for (String adapter1 : allAdapters) { - for (String adapter2 : allAdapters) { - if (!adapter1.equals(adapter2)) { - denyDependency(adapter1, adapter2, classes); - } - } - } - } - - void doesNotDependOn(String packageName, JavaClasses classes) { - denyDependency(this.basePackage, packageName, classes); - } - - void doesNotContainEmptyPackages() { - denyEmptyPackages(allAdapterPackages()); - } -} diff --git a/tapas-tasks/src/test/java/ch/unisg/tapastasks/archunit/ApplicationLayer.java b/tapas-tasks/src/test/java/ch/unisg/tapastasks/archunit/ApplicationLayer.java deleted file mode 100644 index e8e00a5..0000000 --- a/tapas-tasks/src/test/java/ch/unisg/tapastasks/archunit/ApplicationLayer.java +++ /dev/null @@ -1,59 +0,0 @@ -package ch.unisg.tapastasks.archunit; - -import com.tngtech.archunit.core.domain.JavaClasses; - -import java.util.ArrayList; -import java.util.List; - -public class ApplicationLayer extends ArchitectureElement { - - private final HexagonalArchitecture parentContext; - private List incomingPortsPackages = new ArrayList<>(); - private List outgoingPortsPackages = new ArrayList<>(); - private List servicePackages = new ArrayList<>(); - - public ApplicationLayer(String basePackage, HexagonalArchitecture parentContext) { - super(basePackage); - this.parentContext = parentContext; - } - - public ApplicationLayer incomingPorts(String packageName) { - this.incomingPortsPackages.add(fullQualifiedPackage(packageName)); - return this; - } - - public ApplicationLayer outgoingPorts(String packageName) { - this.outgoingPortsPackages.add(fullQualifiedPackage(packageName)); - return this; - } - - public ApplicationLayer services(String packageName) { - this.servicePackages.add(fullQualifiedPackage(packageName)); - return this; - } - - public HexagonalArchitecture and() { - return parentContext; - } - - public void doesNotDependOn(String packageName, JavaClasses classes) { - denyDependency(this.basePackage, packageName, classes); - } - - public void incomingAndOutgoingPortsDoNotDependOnEachOther(JavaClasses classes) { - denyAnyDependency(this.incomingPortsPackages, this.outgoingPortsPackages, classes); - denyAnyDependency(this.outgoingPortsPackages, this.incomingPortsPackages, classes); - } - - private List allPackages() { - List allPackages = new ArrayList<>(); - allPackages.addAll(incomingPortsPackages); - allPackages.addAll(outgoingPortsPackages); - allPackages.addAll(servicePackages); - return allPackages; - } - - void doesNotContainEmptyPackages() { - denyEmptyPackages(allPackages()); - } -} diff --git a/tapas-tasks/src/test/java/ch/unisg/tapastasks/archunit/ArchitectureElement.java b/tapas-tasks/src/test/java/ch/unisg/tapastasks/archunit/ArchitectureElement.java deleted file mode 100644 index 465f441..0000000 --- a/tapas-tasks/src/test/java/ch/unisg/tapastasks/archunit/ArchitectureElement.java +++ /dev/null @@ -1,74 +0,0 @@ -package ch.unisg.tapastasks.archunit; - -import com.tngtech.archunit.core.domain.JavaClasses; -import com.tngtech.archunit.core.importer.ClassFileImporter; - -import java.util.List; - -import static com.tngtech.archunit.base.DescribedPredicate.*; -import static com.tngtech.archunit.base.DescribedPredicate.greaterThanOrEqualTo; -import static com.tngtech.archunit.lang.conditions.ArchConditions.*; -import static com.tngtech.archunit.lang.conditions.ArchConditions.containNumberOfElements; -import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.*; -import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.classes; -import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; - -abstract class ArchitectureElement { - - final String basePackage; - - public ArchitectureElement(String basePackage) { - this.basePackage = basePackage; - } - - String fullQualifiedPackage(String relativePackage) { - return this.basePackage + "." + relativePackage; - } - - static void denyDependency(String fromPackageName, String toPackageName, JavaClasses classes) { - noClasses() - .that() - .resideInAPackage("ch.unisg.tapastasks.tasks.domain..") - .should() - .dependOnClassesThat() - .resideInAnyPackage("ch.unisg.tapastasks.tasks.application..") - .check(classes); - } - - static void denyAnyDependency( - List fromPackages, List toPackages, JavaClasses classes) { - for (String fromPackage : fromPackages) { - for (String toPackage : toPackages) { - noClasses() - .that() - .resideInAPackage(matchAllClassesInPackage(fromPackage)) - .should() - .dependOnClassesThat() - .resideInAnyPackage(matchAllClassesInPackage(toPackage)) - .check(classes); - } - } - } - - static String matchAllClassesInPackage(String packageName) { - return packageName + ".."; - } - - void denyEmptyPackage(String packageName) { - classes() - .that() - .resideInAPackage(matchAllClassesInPackage(packageName)) - .should(containNumberOfElements(greaterThanOrEqualTo(1))) - .check(classesInPackage(packageName)); - } - - private JavaClasses classesInPackage(String packageName) { - return new ClassFileImporter().importPackages(packageName); - } - - void denyEmptyPackages(List packages) { - for (String packageName : packages) { - denyEmptyPackage(packageName); - } - } -} diff --git a/tapas-tasks/src/test/java/ch/unisg/tapastasks/archunit/HexagonalArchitecture.java b/tapas-tasks/src/test/java/ch/unisg/tapastasks/archunit/HexagonalArchitecture.java deleted file mode 100644 index 1445968..0000000 --- a/tapas-tasks/src/test/java/ch/unisg/tapastasks/archunit/HexagonalArchitecture.java +++ /dev/null @@ -1,61 +0,0 @@ -package ch.unisg.tapastasks.archunit; - -import com.tngtech.archunit.core.domain.JavaClasses; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class HexagonalArchitecture extends ArchitectureElement { - - private Adapters adapters; - private ApplicationLayer applicationLayer; - private String configurationPackage; - private List domainPackages = new ArrayList<>(); - - public static HexagonalArchitecture boundedContext(String basePackage) { - return new HexagonalArchitecture(basePackage); - } - - public HexagonalArchitecture(String basePackage) { - super(basePackage); - } - - public Adapters withAdaptersLayer(String adaptersPackage) { - this.adapters = new Adapters(this, fullQualifiedPackage(adaptersPackage)); - return this.adapters; - } - - public HexagonalArchitecture withDomainLayer(String domainPackage) { - this.domainPackages.add(fullQualifiedPackage(domainPackage)); - return this; - } - - public ApplicationLayer withApplicationLayer(String applicationPackage) { - this.applicationLayer = new ApplicationLayer(fullQualifiedPackage(applicationPackage), this); - return this.applicationLayer; - } - - public HexagonalArchitecture withConfiguration(String packageName) { - this.configurationPackage = fullQualifiedPackage(packageName); - return this; - } - - private void domainDoesNotDependOnOtherPackages(JavaClasses classes) { - denyAnyDependency( - this.domainPackages, Collections.singletonList(adapters.basePackage), classes); - denyAnyDependency( - this.domainPackages, Collections.singletonList(applicationLayer.basePackage), classes); - } - - public void check(JavaClasses classes) { - this.adapters.doesNotContainEmptyPackages(); - this.adapters.dontDependOnEachOther(classes); - this.adapters.doesNotDependOn(this.configurationPackage, classes); - this.applicationLayer.doesNotContainEmptyPackages(); - this.applicationLayer.doesNotDependOn(this.adapters.getBasePackage(), classes); - this.applicationLayer.doesNotDependOn(this.configurationPackage, classes); - this.applicationLayer.incomingAndOutgoingPortsDoNotDependOnEachOther(classes); - this.domainDoesNotDependOnOtherPackages(classes); - } -} diff --git a/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/adapter/in/web/AddNewTaskToTaskListWebControllerTest.java b/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/adapter/in/web/AddNewTaskToTaskListWebControllerTest.java deleted file mode 100644 index d397908..0000000 --- a/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/adapter/in/web/AddNewTaskToTaskListWebControllerTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package ch.unisg.tapastasks.tasks.adapter.in.web; - -import ch.unisg.tapastasks.tasks.adapter.in.formats.TaskJsonRepresentation; -import ch.unisg.tapastasks.tasks.adapter.in.web.AddNewTaskToTaskListWebController; -import ch.unisg.tapastasks.tasks.adapter.out.persistence.mongodb.TaskRepository; -import ch.unisg.tapastasks.tasks.application.port.in.AddNewTaskToTaskListCommand; -import ch.unisg.tapastasks.tasks.application.port.in.AddNewTaskToTaskListUseCase; -import ch.unisg.tapastasks.tasks.domain.Task; -import org.json.JSONObject; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; -import org.springframework.boot.test.mock.mockito.MockBean; -import org.springframework.test.web.servlet.MockMvc; - -import java.util.Optional; - -import static org.mockito.BDDMockito.eq; -import static org.mockito.BDDMockito.then; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - - -@WebMvcTest(controllers = AddNewTaskToTaskListWebController.class) -public class AddNewTaskToTaskListWebControllerTest { - - @Autowired - private MockMvc mockMvc; - - @MockBean - private AddNewTaskToTaskListUseCase addNewTaskToTaskListUseCase; - - @MockBean - TaskRepository taskRepository; - - @Disabled - @Test - void testAddNewTaskToTaskList() throws Exception { - - String taskName = "test-request"; - String taskType = "test-request-type"; - String originalTaskUri = "example.org"; - - String jsonPayLoad = new JSONObject() - .put("taskName", taskName ) - .put("taskType", taskType) - .put("originalTaskUri",originalTaskUri) - .toString(); - - //This raises a NullPointerException since it tries to build the HTTP response with attributes from - //the domain object (created task), which is mocked --> we need System Tests here! - //See the buckpal example from the lecture for a working integration test for testing the web controller - mockMvc.perform(post("/tasks/") - .contentType(TaskJsonRepresentation.MEDIA_TYPE) - .content(jsonPayLoad)) - .andExpect(status().isCreated()); - - then(addNewTaskToTaskListUseCase).should() - .addNewTaskToTaskList(eq(new AddNewTaskToTaskListCommand( - new Task.TaskName(taskName), new Task.TaskType(taskType), - Optional.of(new Task.OriginalTaskUri(originalTaskUri)) - ))); - - } - - -} diff --git a/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskPersistenceAdapterTest.java b/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskPersistenceAdapterTest.java deleted file mode 100644 index ef1fa99..0000000 --- a/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/adapter/out/persistence/mongodb/TaskPersistenceAdapterTest.java +++ /dev/null @@ -1,77 +0,0 @@ -package ch.unisg.tapastasks.tasks.adapter.out.persistence.mongodb; - -import ch.unisg.tapastasks.tasks.domain.Task; -import ch.unisg.tapastasks.tasks.domain.TaskList; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.data.mongo.AutoConfigureDataMongo; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.context.annotation.Import; - -import java.util.UUID; - -import static org.assertj.core.api.Assertions.assertThat; - -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) -@AutoConfigureDataMongo -@Import({TaskPersistenceAdapter.class, TaskMapper.class}) -public class TaskPersistenceAdapterTest { - - @Autowired - private TaskRepository taskRepository; - - @Autowired - private TaskPersistenceAdapter adapterUnderTest; - - @Test - void addsNewTask() { - - String testTaskId = UUID.randomUUID().toString(); - String testTaskName = "adds-persistence-task-name"; - String testTaskType = "adds-persistence-task-type"; - String testTaskOuri = "adds-persistence-test-task-ouri"; - String testTaskStatus = Task.Status.OPEN.toString(); - String testTaskListName = "tapas-tasks-tutors"; - - - Task testTask = new Task( - new Task.TaskId(testTaskId), - new Task.TaskName(testTaskName), - new Task.TaskType(testTaskType), - new Task.OriginalTaskUri(testTaskOuri), - new Task.TaskStatus(Task.Status.valueOf(testTaskStatus)) - ); - adapterUnderTest.addTask(testTask); - - MongoTaskDocument retrievedDoc = taskRepository.findByTaskId(testTaskId,testTaskListName); - - assertThat(retrievedDoc.taskId).isEqualTo(testTaskId); - assertThat(retrievedDoc.taskName).isEqualTo(testTaskName); - assertThat(retrievedDoc.taskListName).isEqualTo(testTaskListName); - - } - - @Test - void retrievesTask() { - - String testTaskId = UUID.randomUUID().toString(); - String testTaskName = "reads-persistence-task-name"; - String testTaskType = "reads-persistence-task-type"; - String testTaskOuri = "reads-persistence-test-task-ouri"; - String testTaskStatus = Task.Status.OPEN.toString(); - String testTaskListName = "tapas-tasks-tutors"; - - MongoTaskDocument mongoTask = new MongoTaskDocument(testTaskId, testTaskName, testTaskType, testTaskOuri, - testTaskStatus, testTaskListName); - taskRepository.insert(mongoTask); - - Task retrievedTask = adapterUnderTest.loadTask(new Task.TaskId(testTaskId), - new TaskList.TaskListName(testTaskListName)); - - assertThat(retrievedTask.getTaskName().getValue()).isEqualTo(testTaskName); - assertThat(retrievedTask.getTaskId().getValue()).isEqualTo(testTaskId); - assertThat(retrievedTask.getTaskStatus().getValue()).isEqualTo(Task.Status.valueOf(testTaskStatus)); - - } - -} diff --git a/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/application/service/AddNewTaskToTaskListServiceTest.java b/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/application/service/AddNewTaskToTaskListServiceTest.java deleted file mode 100644 index 10d21fd..0000000 --- a/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/application/service/AddNewTaskToTaskListServiceTest.java +++ /dev/null @@ -1,63 +0,0 @@ -package ch.unisg.tapastasks.tasks.application.service; - -import ch.unisg.tapastasks.tasks.application.port.in.AddNewTaskToTaskListCommand; -import ch.unisg.tapastasks.tasks.application.port.out.AddTaskPort; -import ch.unisg.tapastasks.tasks.application.port.out.NewTaskAddedEventPort; -import ch.unisg.tapastasks.tasks.application.port.out.TaskListLock; -import ch.unisg.tapastasks.tasks.domain.NewTaskAddedEvent; -import ch.unisg.tapastasks.tasks.domain.Task; -import ch.unisg.tapastasks.tasks.domain.TaskList; -import org.junit.jupiter.api.Test; -import org.mockito.Mockito; - -import java.util.Optional; - -import static org.mockito.BDDMockito.*; -import static org.assertj.core.api.Assertions.*; - - -public class AddNewTaskToTaskListServiceTest { - - private final AddTaskPort addTaskPort = Mockito.mock(AddTaskPort.class); - private final TaskListLock taskListLock = Mockito.mock(TaskListLock.class); - private final NewTaskAddedEventPort newTaskAddedEventPort = Mockito.mock(NewTaskAddedEventPort.class); - private final AddNewTaskToTaskListService addNewTaskToTaskListService = new AddNewTaskToTaskListService( - newTaskAddedEventPort, addTaskPort, taskListLock); - - @Test - void addingSucceeds() { - - Task newTask = givenATaskWithNameAndTypeAndURI(new Task.TaskName("test-task"), - new Task.TaskType("test-type"), Optional.of(new Task.OriginalTaskUri("example.org"))); - - TaskList taskList = givenAnEmptyTaskList(TaskList.getTapasTaskList()); - - AddNewTaskToTaskListCommand addNewTaskToTaskListCommand = new AddNewTaskToTaskListCommand(newTask.getTaskName(), - newTask.getTaskType(), Optional.ofNullable(newTask.getOriginalTaskUri())); - - Task addedTask = addNewTaskToTaskListService.addNewTaskToTaskList(addNewTaskToTaskListCommand); - - assertThat(addedTask).isNotNull(); - assertThat(taskList.getListOfTasks().getValue()).hasSize(1); - - then(taskListLock).should().lockTaskList(eq(TaskList.getTapasTaskList().getTaskListName())); - then(newTaskAddedEventPort).should(times(1)) - .publishNewTaskAddedEvent(any(NewTaskAddedEvent.class)); - - } - - private TaskList givenAnEmptyTaskList(TaskList taskList) { - taskList.getListOfTasks().getValue().clear(); - return taskList; - } - - private Task givenATaskWithNameAndTypeAndURI(Task.TaskName taskName, Task.TaskType taskType, - Optional originalTaskUri) { - Task task = Mockito.mock(Task.class); - given(task.getTaskName()).willReturn(taskName); - given(task.getTaskType()).willReturn(taskType); - given(task.getOriginalTaskUri()).willReturn(originalTaskUri.get()); - return task; - } - -} diff --git a/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/domain/TaskListTest.java b/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/domain/TaskListTest.java deleted file mode 100644 index 05dc664..0000000 --- a/tapas-tasks/src/test/java/ch/unisg/tapastasks/tasks/domain/TaskListTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package ch.unisg.tapastasks.tasks.domain; - -import org.junit.jupiter.api.Test; - -import java.util.Optional; - -import static org.assertj.core.api.Assertions.*; - - -public class TaskListTest { - - @Test - void addNewTaskToTaskListSuccess() { - TaskList taskList = TaskList.getTapasTaskList(); - taskList.getListOfTasks().getValue().clear(); - Task newTask = taskList.addNewTaskWithNameAndType(new Task.TaskName("My-Test-Task"), - new Task.TaskType("My-Test-Type")); - - assertThat(newTask.getTaskName().getValue()).isEqualTo("My-Test-Task"); - assertThat(taskList.getListOfTasks().getValue()).hasSize(1); - assertThat(taskList.getListOfTasks().getValue().get(0)).isEqualTo(newTask); - - } - - @Test - void retrieveTaskSuccess() { - TaskList taskList = TaskList.getTapasTaskList(); - Task newTask = taskList.addNewTaskWithNameAndType(new Task.TaskName("My-Test-Task2"), - new Task.TaskType("My-Test-Type2")); - - Task retrievedTask = taskList.retrieveTaskById(newTask.getTaskId()).get(); - - assertThat(retrievedTask).isEqualTo(newTask); - - } - - @Test - void retrieveTaskFailure() { - TaskList taskList = TaskList.getTapasTaskList(); - Task newTask = taskList.addNewTaskWithNameAndType(new Task.TaskName("My-Test-Task3"), - new Task.TaskType("My-Test-Type3")); - - Task.TaskId fakeId = new Task.TaskId("fake-id"); - - Optional retrievedTask = taskList.retrieveTaskById(fakeId); - - assertThat(retrievedTask.isPresent()).isFalse(); - } -} diff --git a/tapas-tasks/src/test/resources/application-test.properties b/tapas-tasks/src/test/resources/application-test.properties deleted file mode 100644 index e45b53d..0000000 --- a/tapas-tasks/src/test/resources/application-test.properties +++ /dev/null @@ -1,2 +0,0 @@ -spring.data.mongodb.uri=mongodb://127.0.0.1:27017 -spring.data.mongodb.database=tapas-tasks