diff options
Diffstat (limited to 'jws/epibazaar/inventory')
10 files changed, 394 insertions, 0 deletions
diff --git a/jws/epibazaar/inventory/pom.xml b/jws/epibazaar/inventory/pom.xml new file mode 100644 index 0000000..b8af7c8 --- /dev/null +++ b/jws/epibazaar/inventory/pom.xml @@ -0,0 +1,135 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>fr.epita.assistants</groupId> + <artifactId>epibazaar</artifactId> + <version>1.0.0</version> + </parent> + + <artifactId>inventory</artifactId> + <version>1.0.0</version> + <dependencies> + <dependency> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-messaging-kafka</artifactId> + </dependency> + <dependency> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-jdbc-postgresql</artifactId> + </dependency> + <dependency> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-hibernate-orm-panache</artifactId> + </dependency> + <dependency> + <groupId>fr.epita.assistants</groupId> + <artifactId>common</artifactId> + <version>1.0.0</version> + <scope>compile</scope> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-assembly-plugin</artifactId> + <configuration> + <archive> + <manifest> + <mainClass>fully.qualified.MainClass</mainClass> + </manifest> + </archive> + <descriptorRefs> + <descriptorRef>jar-with-dependencies</descriptorRef> + </descriptorRefs> + </configuration> + </plugin> + <plugin> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-maven-plugin</artifactId> + <version>${quarkus.platform.version}</version> + <extensions>true</extensions> + <executions> + <execution> + <goals> + <goal>build</goal> + <goal>generate-code</goal> + <goal>generate-code-tests</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <version>${compiler-plugin.version}</version> + <configuration> + <parameters>${maven.compiler.parameters}</parameters> + </configuration> + </plugin> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <configuration> + <systemPropertyVariables> + <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager> + <maven.home>${maven.home}</maven.home> + </systemPropertyVariables> + </configuration> + </plugin> + </plugins> + </build> + <profiles> + <profile> + <id>fetch-bom</id> + <activation> + <activeByDefault>true</activeByDefault> + </activation> + <dependencies> + <dependency> + <groupId>io.quarkus.platform</groupId> + <artifactId>quarkus-bom-quarkus-platform-properties</artifactId> + <version>3.17.5</version> + <type>properties</type> + </dependency> + </dependencies> + </profile> + <profile> + <id>native</id> + <activation> + <property> + <name>native</name> + </property> + </activation> + <build> + <plugins> + <plugin> + <artifactId>maven-failsafe-plugin</artifactId> + <version>${versions.maven-surefire-plugin}</version> + <executions> + <execution> + <goals> + <goal>integration-test</goal> + <goal>verify</goal> + </goals> + <configuration> + <systemPropertyVariables> + <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path> + <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager> + <maven.home>${maven.home}</maven.home> + </systemPropertyVariables> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + <properties> + <quarkus.package.type>native</quarkus.package.type> + </properties> + </profile> + </profiles> +</project> diff --git a/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/converter/InventoryConverter.java b/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/converter/InventoryConverter.java new file mode 100644 index 0000000..62c7994 --- /dev/null +++ b/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/converter/InventoryConverter.java @@ -0,0 +1,24 @@ +package fr.epita.assistants.inventory.converter; + +import fr.epita.assistants.common.aggregate.ItemAggregate; +import fr.epita.assistants.common.api.response.ItemResponse; +import fr.epita.assistants.common.api.response.ItemsResponse; +import fr.epita.assistants.inventory.data.model.ItemModel; +import fr.epita.assistants.inventory.domain.entity.ItemEntity; +import fr.epita.assistants.inventory.domain.entity.ItemsEntity; + +public class InventoryConverter { + public static ItemAggregate updatedItem(ItemModel item) { + return new ItemAggregate(item.getType(), item.getQuantity()); + } + + public static ItemResponse EntityToResponse(ItemEntity e) { + return new ItemResponse(e.getId(), e.getQuantity(), e.getType()); + } + + public static ItemsResponse EntityToResponse(ItemsEntity e) { + if (e == null) + return null; + return new ItemsResponse(e.getItems().stream().map(InventoryConverter::EntityToResponse).toList()); + } +} diff --git a/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/data/model/ItemModel.java b/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/data/model/ItemModel.java new file mode 100644 index 0000000..29a182b --- /dev/null +++ b/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/data/model/ItemModel.java @@ -0,0 +1,25 @@ +package fr.epita.assistants.inventory.data.model; + +import fr.epita.assistants.common.aggregate.ItemAggregate; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.persistence.*; +import lombok.*; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Setter +@Table(name = "item") +public class ItemModel { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + Long id; + Float quantity; + @Enumerated(value = EnumType.STRING) + ItemAggregate.ResourceType type; + + public ItemModel(float quantity, ItemAggregate.ResourceType type) { + this.quantity = quantity; + this.type = type; + } +} diff --git a/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/data/repository/ItemRepository.java b/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/data/repository/ItemRepository.java new file mode 100644 index 0000000..129c815 --- /dev/null +++ b/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/data/repository/ItemRepository.java @@ -0,0 +1,48 @@ +package fr.epita.assistants.inventory.data.repository; + +import fr.epita.assistants.common.aggregate.ItemAggregate; +import fr.epita.assistants.inventory.data.model.ItemModel; +import io.quarkus.hibernate.orm.panache.PanacheRepository; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.transaction.Transactional; + +import java.util.List; +import java.util.Optional; + +@ApplicationScoped +public class ItemRepository implements PanacheRepository<ItemModel> { + + @Transactional + public void clearDB() { + deleteAll(); + } + + @Transactional + public List<ItemModel> getItems() { + return find("where quantity > 0").stream().toList(); + } + + @Transactional + public Optional<ItemModel> exists(ItemAggregate.ResourceType type) { + return find("type = ?1", type).firstResultOptional(); + } + + @Transactional + public ItemModel addItem(ItemAggregate.ResourceType type, Float amount) { + ItemModel res = new ItemModel(amount, type); + persist(res); + return res; + } + + // amount should already be the updated amount + @Transactional + public ItemModel fillInventory(ItemAggregate.ResourceType type, Float amount) { + update("quantity = ?1 where type = ?2", amount, type); + return new ItemModel(amount, type); + } + + @Transactional + public List<ItemModel> getMoney() { + return find("where type = ?1", ItemAggregate.ResourceType.MONEY).stream().toList(); + } +} diff --git a/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/domain/entity/ItemEntity.java b/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/domain/entity/ItemEntity.java new file mode 100644 index 0000000..028d09e --- /dev/null +++ b/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/domain/entity/ItemEntity.java @@ -0,0 +1,13 @@ +package fr.epita.assistants.inventory.domain.entity; + +import fr.epita.assistants.common.aggregate.ItemAggregate; +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class ItemEntity { + long id; + float quantity; + ItemAggregate.ResourceType type; +} diff --git a/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/domain/entity/ItemsEntity.java b/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/domain/entity/ItemsEntity.java new file mode 100644 index 0000000..c0a96ac --- /dev/null +++ b/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/domain/entity/ItemsEntity.java @@ -0,0 +1,13 @@ +package fr.epita.assistants.inventory.domain.entity; + +import fr.epita.assistants.inventory.domain.entity.ItemEntity; +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.List; + +@Getter +@AllArgsConstructor +public class ItemsEntity { + List<ItemEntity> items; +} diff --git a/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/domain/service/InventoryService.java b/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/domain/service/InventoryService.java new file mode 100644 index 0000000..fc25abf --- /dev/null +++ b/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/domain/service/InventoryService.java @@ -0,0 +1,59 @@ +package fr.epita.assistants.inventory.domain.service; + +import fr.epita.assistants.common.aggregate.ItemAggregate; +import fr.epita.assistants.common.aggregate.ResetInventoryAggregate; +import fr.epita.assistants.common.command.CollectItemCommand; +import fr.epita.assistants.inventory.converter.InventoryConverter; +import fr.epita.assistants.inventory.data.model.ItemModel; +import fr.epita.assistants.inventory.data.repository.ItemRepository; +import fr.epita.assistants.inventory.domain.entity.ItemEntity; +import fr.epita.assistants.inventory.domain.entity.ItemsEntity; +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; + +import java.util.List; +import java.util.Optional; + +@ApplicationScoped +public class InventoryService { + @Inject + ItemRepository itemRepository; + + public ResetInventoryAggregate resetInventory() { + ResetInventoryAggregate res = + new ResetInventoryAggregate(itemRepository.getItems().stream().map(m -> new ItemAggregate(m.getType() + , m.getQuantity())).toList()); + itemRepository.clearDB(); + return res; + } + + public ItemAggregate collectItem(CollectItemCommand cmd) { + Optional<ItemModel> item = itemRepository.exists(cmd.getType()); + if (item.isPresent()) { + ItemModel updated = itemRepository.fillInventory(cmd.getType(), + cmd.getCollectRateMultiplier() * cmd.getType().getItemInfo().getCollectQuantity() + item.get().getQuantity()); + return InventoryConverter.updatedItem(updated); + } else { + ItemModel newItem = itemRepository.addItem(cmd.getType(), + cmd.getCollectRateMultiplier() * cmd.getType().getItemInfo().getCollectQuantity()); + return InventoryConverter.updatedItem(newItem); + } + } + + public ItemsEntity getAllItems() { + return new ItemsEntity(itemRepository.getItems().stream().map(m -> new ItemEntity(m.getId(), + m.getQuantity(), m.getType())).toList()); + } + + public Double getMoney() { + List<ItemModel> entries = itemRepository.getMoney(); + if (entries.isEmpty()) + return null; + return entries.stream().mapToDouble(m -> m.getQuantity().doubleValue()).sum(); + } + + public Float pay(Float price) { + itemRepository.fillInventory(ItemAggregate.ResourceType.MONEY, getMoney().floatValue() - price); + return getMoney().floatValue(); + } +} diff --git a/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/presentation/subscriber/CommandSubscriber.java b/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/presentation/subscriber/CommandSubscriber.java new file mode 100644 index 0000000..3a95a3a --- /dev/null +++ b/jws/epibazaar/inventory/src/main/java/fr/epita/assistants/inventory/presentation/subscriber/CommandSubscriber.java @@ -0,0 +1,59 @@ +package fr.epita.assistants.inventory.presentation.subscriber; + +import fr.epita.assistants.common.aggregate.ItemAggregate; +import fr.epita.assistants.common.aggregate.ResetInventoryAggregate; +import fr.epita.assistants.common.aggregate.SyncInventoryAggregate; +import fr.epita.assistants.common.aggregate.UpgradeItemProducerAggregate; +import fr.epita.assistants.common.command.*; +import fr.epita.assistants.inventory.domain.service.InventoryService; +import io.smallrye.reactive.messaging.annotations.Broadcast; +import jakarta.inject.Inject; +import org.eclipse.microprofile.reactive.messaging.Incoming; +import org.eclipse.microprofile.reactive.messaging.Outgoing; + +public class CommandSubscriber { + @Inject + InventoryService inventoryService; + + @Broadcast + @Incoming("reset-inventory-command") + @Outgoing("reset-inventory-aggregate") + public ResetInventoryAggregate commandListener(ResetInventoryCommand cmd) { + return inventoryService.resetInventory(); + } + + @Broadcast + @Incoming("collect-item-command") + @Outgoing("collect-item-aggregate") + public ItemAggregate commandListener(CollectItemCommand cmd) { + return inventoryService.collectItem(cmd); + } + + @Broadcast + @Incoming("sync-inventory-command") + @Outgoing("sync-inventory-aggregate") + public SyncInventoryAggregate commandListener(SyncInventoryCommand cmd) { + return new SyncInventoryAggregate(inventoryService.getAllItems().getItems().stream().map(e -> new ItemAggregate(e.getType(), e.getQuantity())).toList()); + } + + @Broadcast + @Incoming("upgrade-collect-rate-command") + @Outgoing("upgrade-collect-rate-aggregate") + public UpgradeItemProducerAggregate commandListener(UpgradeCollectRateCommand cmd) { + return new UpgradeItemProducerAggregate(inventoryService.pay(cmd.getPrice())); + } + + @Broadcast + @Incoming("upgrade-movement-speed-command") + @Outgoing("upgrade-movement-speed-aggregate") + public UpgradeItemProducerAggregate commandListener(UpgradeMovementSpeedCommand cmd) { + return new UpgradeItemProducerAggregate(inventoryService.pay(cmd.getPrice())); + } + + @Broadcast + @Incoming("upgrade-stamina-command") + @Outgoing("upgrade-stamina-aggregate") + public UpgradeItemProducerAggregate commandListener(UpgradeStaminaCommand cmd) { + return new UpgradeItemProducerAggregate(inventoryService.pay(cmd.getPrice())); + } +} diff --git a/jws/epibazaar/inventory/src/main/resources/application.properties b/jws/epibazaar/inventory/src/main/resources/application.properties new file mode 100644 index 0000000..fedcdd0 --- /dev/null +++ b/jws/epibazaar/inventory/src/main/resources/application.properties @@ -0,0 +1,11 @@ +%dev.quarkus.http.port=8999 +quarkus.datasource.db-kind=postgresql +quarkus.datasource.username=postgres +quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/inventory?currentSchema=public +quarkus.transaction-manager.default-transaction-timeout=3000s +quarkus.hibernate-orm.log.queries-slower-than-ms=200 +quarkus.hibernate-orm.database.generation=drop-and-create + +quarkus.kafka.devservices.image-name=reg.undercloud.cri.epita.fr/docker/redpandadata/redpanda:v24.1.2 +quarkus.devservices.enabled=true +%test.quarkus.devservices.enabled=false diff --git a/jws/epibazaar/inventory/src/main/resources/db/migration/V1__Init.sql b/jws/epibazaar/inventory/src/main/resources/db/migration/V1__Init.sql new file mode 100644 index 0000000..3c1e091 --- /dev/null +++ b/jws/epibazaar/inventory/src/main/resources/db/migration/V1__Init.sql @@ -0,0 +1,7 @@ +CREATE TABLE IF NOT EXISTS "item" +( + id SERIAL PRIMARY KEY NOT NULL, + + type VARCHAR(64) NOT NULL, + quantity FLOAT NOT NULL +); |
