From 3e17c8e674da741bc2fce690673260ada7a99246 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lo=C3=AFc=20Ortola?= <contact@loicortola.com>
Date: Fri, 16 May 2025 16:21:23 +0200
Subject: [PATCH] feat: improved boilerplate and added solution for part-1

---
 .../bakery/MakeCookiesApp.java                |  8 ++++
 .../bakery/OrderCookiesApp.java               | 21 +++++++++++
 .../bakery/kitchen/KitchenWorker.java         | 29 +++++++++++++++
 .../bakery/kitchen/KitchenWorkflow.java       | 10 +++++
 .../bakery/kitchen/KitchenWorkflowImpl.java   |  9 +++++
 .../bakery/kitchen/bake/BakeService.java      |  5 +++
 .../bakery/kitchen/batter/BatterService.java  |  5 +++
 .../signals/ConsumeSignal.java                |  4 ++
 .../signals/InventoryActivity.java            |  7 ++++
 .../signals/InventoryActivityImpl.java        | 26 +++++++++++++
 .../signals/InventoryWorkflow.java            | 10 +++++
 .../temporalpractice/signals/MSMain.java      | 37 +++++++++++++++++++
 .../bakery/MakeCookiesApp.java                |  1 +
 .../bakery/OrderCookiesApp.java               |  2 +
 14 files changed, 174 insertions(+)
 create mode 100644 solutions/day1/part-1/temporalpractice/bakery/MakeCookiesApp.java
 create mode 100644 solutions/day1/part-1/temporalpractice/bakery/OrderCookiesApp.java
 create mode 100644 solutions/day1/part-1/temporalpractice/bakery/kitchen/KitchenWorker.java
 create mode 100644 solutions/day1/part-1/temporalpractice/bakery/kitchen/KitchenWorkflow.java
 create mode 100644 solutions/day1/part-1/temporalpractice/bakery/kitchen/KitchenWorkflowImpl.java
 create mode 100644 solutions/day1/part-1/temporalpractice/bakery/kitchen/bake/BakeService.java
 create mode 100644 solutions/day1/part-1/temporalpractice/bakery/kitchen/batter/BatterService.java
 create mode 100644 solutions/day1/part-1/temporalpractice/signals/ConsumeSignal.java
 create mode 100644 solutions/day1/part-1/temporalpractice/signals/InventoryActivity.java
 create mode 100644 solutions/day1/part-1/temporalpractice/signals/InventoryActivityImpl.java
 create mode 100644 solutions/day1/part-1/temporalpractice/signals/InventoryWorkflow.java
 create mode 100644 solutions/day1/part-1/temporalpractice/signals/MSMain.java

diff --git a/solutions/day1/part-1/temporalpractice/bakery/MakeCookiesApp.java b/solutions/day1/part-1/temporalpractice/bakery/MakeCookiesApp.java
new file mode 100644
index 0000000..d0c3871
--- /dev/null
+++ b/solutions/day1/part-1/temporalpractice/bakery/MakeCookiesApp.java
@@ -0,0 +1,8 @@
+package io.takima.temporalpractice.bakery;
+
+public class MakeCookiesApp {
+    public static void main(String[] args) {
+        // This app should execute the making of all cookies ordered
+        new KitchenWorker().start();
+    }
+}
diff --git a/solutions/day1/part-1/temporalpractice/bakery/OrderCookiesApp.java b/solutions/day1/part-1/temporalpractice/bakery/OrderCookiesApp.java
new file mode 100644
index 0000000..ccb16fb
--- /dev/null
+++ b/solutions/day1/part-1/temporalpractice/bakery/OrderCookiesApp.java
@@ -0,0 +1,21 @@
+package io.takima.temporalpractice.bakery;
+
+import io.temporal.client.WorkflowClient;
+import io.temporal.client.WorkflowOptions;
+import io.temporal.serviceclient.WorkflowServiceStubs;
+
+public class OrderCookiesApp {
+    public static void main(String[] args) {
+        // This app simulates an order of cookies
+        // It should call the workflow which makes cookies
+        WorkflowClient client = WorkflowClient.newInstance(WorkflowServiceStubs.newLocalServiceStubs());
+        WorkflowOptions options = WorkflowOptions.newBuilder()
+          .setTaskQueue("TheOneAndOnlyQueue")
+          .setWorkflowId("best-cookie")
+          .build();
+
+        KitchenWorkflow workflow = client.newWorkflowStub(KitchenWorkflow.class, options);
+
+        workflow.makeCookies(); // Start the Workflow Execution
+    }
+}
diff --git a/solutions/day1/part-1/temporalpractice/bakery/kitchen/KitchenWorker.java b/solutions/day1/part-1/temporalpractice/bakery/kitchen/KitchenWorker.java
new file mode 100644
index 0000000..b61e118
--- /dev/null
+++ b/solutions/day1/part-1/temporalpractice/bakery/kitchen/KitchenWorker.java
@@ -0,0 +1,29 @@
+package io.takima.temporalpractice.bakery.kitchen;
+
+import io.temporal.client.WorkflowClient;
+import io.temporal.client.WorkflowOptions;
+import io.temporal.serviceclient.WorkflowServiceStubs;
+import io.temporal.worker.Worker;
+import io.temporal.worker.WorkerFactory;
+
+public class KitchenWorker {
+  public void start() {
+    // Represents the connection to your local cluster. For now, lets keep it simple
+    WorkflowServiceStubs serviceStub = WorkflowServiceStubs.newLocalServiceStubs();
+    // Your key for interacting with the Temporal world.
+    WorkflowClient client = WorkflowClient.newInstance(serviceStub);
+
+    WorkflowOptions options = WorkflowOptions.newBuilder()
+      .setTaskQueue("TheOneAndOnlyQueue")
+      .setWorkflowId("best-cookie")
+      .build();
+
+    WorkerFactory factory = WorkerFactory.newInstance(client);
+
+    Worker worker = factory.newWorker("TheOneAndOnlyQueue");
+
+    worker.registerWorkflowImplementationTypes(KitchenWorkflowImpl.class);
+
+    factory.start();
+  }
+}
diff --git a/solutions/day1/part-1/temporalpractice/bakery/kitchen/KitchenWorkflow.java b/solutions/day1/part-1/temporalpractice/bakery/kitchen/KitchenWorkflow.java
new file mode 100644
index 0000000..bec377d
--- /dev/null
+++ b/solutions/day1/part-1/temporalpractice/bakery/kitchen/KitchenWorkflow.java
@@ -0,0 +1,10 @@
+package io.takima.temporalpractice.bakery.kitchen;
+
+import io.temporal.workflow.WorkflowInterface;
+import io.temporal.workflow.WorkflowMethod;
+
+@WorkflowInterface
+public interface KitchenWorkflow {
+  @WorkflowMethod
+  void makeCookies();
+}
diff --git a/solutions/day1/part-1/temporalpractice/bakery/kitchen/KitchenWorkflowImpl.java b/solutions/day1/part-1/temporalpractice/bakery/kitchen/KitchenWorkflowImpl.java
new file mode 100644
index 0000000..445fb39
--- /dev/null
+++ b/solutions/day1/part-1/temporalpractice/bakery/kitchen/KitchenWorkflowImpl.java
@@ -0,0 +1,9 @@
+package io.takima.temporalpractice.bakery.kitchen;
+
+public class KitchenWorkflowImpl implements KitchenWorkflow {
+    @Override
+    public void makeCookies() {
+        System.out.println("I'm making cookies");
+        System.out.println("Cookies are done!");
+    }
+}
diff --git a/solutions/day1/part-1/temporalpractice/bakery/kitchen/bake/BakeService.java b/solutions/day1/part-1/temporalpractice/bakery/kitchen/bake/BakeService.java
new file mode 100644
index 0000000..50b3b72
--- /dev/null
+++ b/solutions/day1/part-1/temporalpractice/bakery/kitchen/bake/BakeService.java
@@ -0,0 +1,5 @@
+package io.takima.temporalpractice.bakery.kitchen.bake;
+
+public interface BakeService {
+    void bake();
+}
diff --git a/solutions/day1/part-1/temporalpractice/bakery/kitchen/batter/BatterService.java b/solutions/day1/part-1/temporalpractice/bakery/kitchen/batter/BatterService.java
new file mode 100644
index 0000000..ce25b12
--- /dev/null
+++ b/solutions/day1/part-1/temporalpractice/bakery/kitchen/batter/BatterService.java
@@ -0,0 +1,5 @@
+package io.takima.temporalpractice.bakery.kitchen.batter;
+
+public interface BatterService {
+    void prepareBatter();
+}
diff --git a/solutions/day1/part-1/temporalpractice/signals/ConsumeSignal.java b/solutions/day1/part-1/temporalpractice/signals/ConsumeSignal.java
new file mode 100644
index 0000000..ea74daf
--- /dev/null
+++ b/solutions/day1/part-1/temporalpractice/signals/ConsumeSignal.java
@@ -0,0 +1,4 @@
+package io.takima.temporalpractice.signals;
+
+public record ConsumeSignal(int amount) {
+}
diff --git a/solutions/day1/part-1/temporalpractice/signals/InventoryActivity.java b/solutions/day1/part-1/temporalpractice/signals/InventoryActivity.java
new file mode 100644
index 0000000..1645c76
--- /dev/null
+++ b/solutions/day1/part-1/temporalpractice/signals/InventoryActivity.java
@@ -0,0 +1,7 @@
+package io.takima.temporalpractice.signals;
+// TODO : remove comments when starting the mastering signals exercise on day 2
+//@ActivityInterface
+public interface InventoryActivity {
+    void reserve(ConsumeSignal input);
+
+}
diff --git a/solutions/day1/part-1/temporalpractice/signals/InventoryActivityImpl.java b/solutions/day1/part-1/temporalpractice/signals/InventoryActivityImpl.java
new file mode 100644
index 0000000..db1105d
--- /dev/null
+++ b/solutions/day1/part-1/temporalpractice/signals/InventoryActivityImpl.java
@@ -0,0 +1,26 @@
+package io.takima.temporalpractice.signals;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class InventoryActivityImpl implements InventoryActivity {
+    private static final Logger logger = LoggerFactory.getLogger(InventoryActivityImpl.class);
+    int counter;
+
+    public InventoryActivityImpl(int inventorySize){
+        this.counter = inventorySize;
+    }
+
+    @Override
+    public void reserve(ConsumeSignal input) {
+        int currentValue = counter;
+
+        try {
+            //Simulate async work
+            Thread.sleep(10);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+        counter = currentValue - 1;
+        logger.info("counter: "  + counter);
+    }
+}
diff --git a/solutions/day1/part-1/temporalpractice/signals/InventoryWorkflow.java b/solutions/day1/part-1/temporalpractice/signals/InventoryWorkflow.java
new file mode 100644
index 0000000..f7cfebd
--- /dev/null
+++ b/solutions/day1/part-1/temporalpractice/signals/InventoryWorkflow.java
@@ -0,0 +1,10 @@
+package io.takima.temporalpractice.signals;
+// TODO : remove comments when starting the mastering signals exercise on day 2
+//@WorkflowInterface
+public interface InventoryWorkflow {
+//    @WorkflowMethod
+    void run();
+//    @SignalMethod
+    void reserve(ConsumeSignal input);
+
+}
diff --git a/solutions/day1/part-1/temporalpractice/signals/MSMain.java b/solutions/day1/part-1/temporalpractice/signals/MSMain.java
new file mode 100644
index 0000000..61cdb4a
--- /dev/null
+++ b/solutions/day1/part-1/temporalpractice/signals/MSMain.java
@@ -0,0 +1,37 @@
+package io.takima.temporalpractice.signals;
+// TODO : remove comments when starting the mastering signals exercise on day 2
+//import io.temporal.client.WorkflowClient;
+//import io.temporal.client.WorkflowOptions;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+//import static io.takima.temporalpractice.temporal.TemporalUtils.*;
+//import static io.takima.temporalpractice.temporal.TemporalQueues.*;
+public class MSMain {
+
+    // Our inventory will contain 100 elements and we will send 100 signals, lets see how it goes
+    static int inventoryToDecrement = 100;
+
+    public static void main(String[] args) {
+//        var worker = FACTORY.newWorker(MASTERING_SIGNALS);
+//        worker.registerActivitiesImplementations(new InventoryActivityImpl(inventoryToDecrement));
+//        worker.registerWorkflowImplementationTypes(InventoryWorkflowImpl.class);
+
+//        FACTORY.start();
+
+//        var workflow = CLIENT.newWorkflowStub(
+//                InventoryWorkflow.class,
+//                WorkflowOptions.newBuilder().setTaskQueue(MASTERING_SIGNALS).setWorkflowId("inventory").build()
+//        );
+//        WorkflowClient.start(workflow::run);
+        try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
+            // Submit 100 tasks
+            for (int i = 1; i < inventoryToDecrement; i++) {
+                executor.submit(() -> {
+//                    workflow.reserve(new ConsumeSignal(1));
+                });
+            }
+        }
+    }
+}
diff --git a/src/main/java/io/takima/temporalpractice/bakery/MakeCookiesApp.java b/src/main/java/io/takima/temporalpractice/bakery/MakeCookiesApp.java
index e7c4d63..059f9d6 100644
--- a/src/main/java/io/takima/temporalpractice/bakery/MakeCookiesApp.java
+++ b/src/main/java/io/takima/temporalpractice/bakery/MakeCookiesApp.java
@@ -2,5 +2,6 @@ package io.takima.temporalpractice.bakery;
 
 public class MakeCookiesApp {
     public static void main(String[] args) {
+        // This app should execute the making of all cookies ordered
     }
 }
diff --git a/src/main/java/io/takima/temporalpractice/bakery/OrderCookiesApp.java b/src/main/java/io/takima/temporalpractice/bakery/OrderCookiesApp.java
index 9fb1fc1..c7bf115 100644
--- a/src/main/java/io/takima/temporalpractice/bakery/OrderCookiesApp.java
+++ b/src/main/java/io/takima/temporalpractice/bakery/OrderCookiesApp.java
@@ -2,5 +2,7 @@ package io.takima.temporalpractice.bakery;
 
 public class OrderCookiesApp {
     public static void main(String[] args) {
+        // This app simulates an order of cookies
+        // It should call the workflow which makes cookies
     }
 }
-- 
GitLab