You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flink.apache.org by xt...@apache.org on 2025/07/14 04:56:50 UTC

(flink-agents) branch main updated: [API][Java] agent java api (#62)

This is an automated email from the ASF dual-hosted git repository.

xtsong pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/flink-agents.git


The following commit(s) were added to refs/heads/main by this push:
     new 60dabfb  [API][Java] agent java api (#62)
60dabfb is described below

commit 60dabfba1eaa3c5ce5f22c9cac0e597797dff79b
Author: Hao Li <11...@users.noreply.github.com>
AuthorDate: Sun Jul 13 21:56:45 2025 -0700

    [API][Java] agent java api (#62)
---
 .gitignore                                         |   2 +
 .../java/org/apache/flink/agents/api/Action.java   |  51 ++++++++
 .../java/org/apache/flink/agents/api/Agent.java    |  28 ++++
 plan/pom.xml                                       |   6 +
 .../org/apache/flink/agents/plan/AgentPlan.java    |  55 ++++++++
 .../apache/flink/agents/plan/AgentPlanTest.java    | 141 +++++++++++++++++++++
 .../serializer/AgentPlanJsonSerializerTest.java    | 140 ++++++++++++--------
 pom.xml                                            |   6 +
 runtime/pom.xml                                    |   8 --
 9 files changed, 375 insertions(+), 62 deletions(-)

diff --git a/.gitignore b/.gitignore
index 421cbb6..b2d3bdd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
 .idea/*
 target/
+.vscode
 *.iml
 .DS_Store
 python/.idea/
@@ -7,5 +8,6 @@ python/flink_agents.egg-info/
 python/flink_agents/flink_agents.egg-info/
 python/build/
 python/dist
+python/uv.lock
 python/.DS_Store
 __pycache__
diff --git a/api/src/main/java/org/apache/flink/agents/api/Action.java b/api/src/main/java/org/apache/flink/agents/api/Action.java
new file mode 100644
index 0000000..c5fc7c1
--- /dev/null
+++ b/api/src/main/java/org/apache/flink/agents/api/Action.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.agents.api;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation for marking a method as an agent action.
+ *
+ * <p>This annotation specifies which event types the action should respond to. The annotated method
+ * will be triggered when any of the specified event types occur.
+ *
+ * <p>Example usage:
+ *
+ * <pre>{@code
+ * @Action(listenEvents = {InputEvent.class, CustomEvent.class})
+ * public void handleEvents(Event event) {
+ *     // Action logic here
+ * }
+ * }</pre>
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Action {
+    /**
+     * List of event types that this action should respond to. At least one event type must be
+     * specified.
+     *
+     * @return Array of Event classes that this action listens to
+     */
+    Class<? extends Event>[] listenEvents();
+}
diff --git a/api/src/main/java/org/apache/flink/agents/api/Agent.java b/api/src/main/java/org/apache/flink/agents/api/Agent.java
new file mode 100644
index 0000000..1f04d83
--- /dev/null
+++ b/api/src/main/java/org/apache/flink/agents/api/Agent.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.agents.api;
+
+/**
+ * Base class for defining agent logic. Currently, Agent is an empty interface, we may add
+ * interactive methods like addAction(), addModel() later.
+ */
+public abstract class Agent {
+    // Currently empty interface - may be extended with interactive methods
+    // like addAction(), addModel() in the future
+}
diff --git a/plan/pom.xml b/plan/pom.xml
index 6d1d69d..99fc3a3 100644
--- a/plan/pom.xml
+++ b/plan/pom.xml
@@ -44,6 +44,12 @@ under the License.
             <artifactId>pemja</artifactId>
             <version>${pemja.version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <version>${assertj.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
 </project>
\ No newline at end of file
diff --git a/plan/src/main/java/org/apache/flink/agents/plan/AgentPlan.java b/plan/src/main/java/org/apache/flink/agents/plan/AgentPlan.java
index da82b61..bdffee8 100644
--- a/plan/src/main/java/org/apache/flink/agents/plan/AgentPlan.java
+++ b/plan/src/main/java/org/apache/flink/agents/plan/AgentPlan.java
@@ -18,6 +18,8 @@
 
 package org.apache.flink.agents.plan;
 
+import org.apache.flink.agents.api.Agent;
+import org.apache.flink.agents.api.Event;
 import org.apache.flink.agents.plan.serializer.AgentPlanJsonDeserializer;
 import org.apache.flink.agents.plan.serializer.AgentPlanJsonSerializer;
 import org.apache.flink.shaded.jackson2.com.fasterxml.jackson.databind.ObjectMapper;
@@ -28,6 +30,9 @@ import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -49,6 +54,19 @@ public class AgentPlan implements Serializable {
         this.actionsByEvent = actionsByEvent;
     }
 
+    /**
+     * Constructor that creates an AgentPlan from an Agent instance by scanning for @Action
+     * annotations.
+     *
+     * @param agent the agent instance to scan for actions
+     * @throws Exception if there's an error creating actions from the agent
+     */
+    public AgentPlan(Agent agent) throws Exception {
+        this.actions = new HashMap<>();
+        this.actionsByEvent = new HashMap<>();
+        extractActionsFromAgent(agent);
+    }
+
     public Map<String, Action> getActions() {
         return actions;
     }
@@ -72,4 +90,41 @@ public class AgentPlan implements Serializable {
         this.actions = agentPlan.getActions();
         this.actionsByEvent = agentPlan.getActionsByEvent();
     }
+
+    private void extractActionsFromAgent(Agent agent) throws Exception {
+        // Scan the agent class for methods annotated with @Action
+        Class<?> agentClass = agent.getClass();
+        for (Method method : agentClass.getDeclaredMethods()) {
+            if (method.isAnnotationPresent(org.apache.flink.agents.api.Action.class)) {
+                org.apache.flink.agents.api.Action actionAnnotation =
+                        method.getAnnotation(org.apache.flink.agents.api.Action.class);
+
+                // Get the event types this action listens to
+                Class<? extends Event>[] listenEventTypes = actionAnnotation.listenEvents();
+
+                // Convert event types to string names
+                List<String> eventTypeNames = new ArrayList<>();
+                for (Class<? extends Event> eventType : listenEventTypes) {
+                    eventTypeNames.add(eventType.getName());
+                }
+
+                // Create a JavaFunction for this method
+                JavaFunction javaFunction =
+                        new JavaFunction(agentClass, method.getName(), method.getParameterTypes());
+
+                // Create an Action
+                Action action = new Action(method.getName(), javaFunction, eventTypeNames);
+
+                // Add to actions map
+                actions.put(action.getName(), action);
+
+                // Add to actionsByEvent map
+                for (String eventTypeName : eventTypeNames) {
+                    actionsByEvent
+                            .computeIfAbsent(eventTypeName, k -> new ArrayList<>())
+                            .add(action);
+                }
+            }
+        }
+    }
 }
diff --git a/plan/src/test/java/org/apache/flink/agents/plan/AgentPlanTest.java b/plan/src/test/java/org/apache/flink/agents/plan/AgentPlanTest.java
new file mode 100644
index 0000000..4196d39
--- /dev/null
+++ b/plan/src/test/java/org/apache/flink/agents/plan/AgentPlanTest.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.flink.agents.plan;
+
+import org.apache.flink.agents.api.Agent;
+import org.apache.flink.agents.api.Event;
+import org.apache.flink.agents.api.InputEvent;
+import org.apache.flink.agents.api.OutputEvent;
+import org.apache.flink.agents.api.context.RunnerContext;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/** Test for {@link AgentPlan} constructor that takes an Agent. */
+public class AgentPlanTest {
+
+    /** Test event class for testing. */
+    public static class TestEvent extends Event {
+        private final String data;
+
+        public TestEvent(String data) {
+            this.data = data;
+        }
+
+        public String getData() {
+            return data;
+        }
+    }
+
+    /** Test agent class with annotated methods. */
+    public static class TestAgent extends Agent {
+
+        @org.apache.flink.agents.api.Action(listenEvents = {InputEvent.class})
+        public void handleInputEvent(InputEvent event, RunnerContext context) {
+            // Test action implementation
+        }
+
+        @org.apache.flink.agents.api.Action(listenEvents = {TestEvent.class, OutputEvent.class})
+        public void handleMultipleEvents(Event event, RunnerContext context) {
+            // Test action implementation
+        }
+
+        // This method is not annotated, so it should not be included
+        public void nonAnnotatedMethod(Event event, RunnerContext context) {
+            // This should not be included in the agent plan
+        }
+    }
+
+    @Test
+    public void testConstructorWithAgent() throws Exception {
+        // Create an agent instance
+        TestAgent agent = new TestAgent();
+
+        // Create AgentPlan using the new constructor
+        AgentPlan agentPlan = new AgentPlan(agent);
+
+        // Verify that actions were collected correctly
+        assertThat(agentPlan.getActions().size()).isEqualTo(2);
+        assertThat(agentPlan.getActions()).containsKey("handleInputEvent");
+        assertThat(agentPlan.getActions()).containsKey("handleMultipleEvents");
+
+        // Verify action details for handleInputEvent
+        Action inputAction = agentPlan.getActions().get("handleInputEvent");
+        assertThat(inputAction).isNotNull();
+        assertThat(inputAction.getName()).isEqualTo("handleInputEvent");
+        assertThat(inputAction.getListenEventTypes())
+                .isEqualTo(List.of(InputEvent.class.getName()));
+        assertThat(inputAction.getExec()).isInstanceOf(JavaFunction.class);
+
+        // Check that the JavaFunction instance has the correct method/class/params
+        JavaFunction exec = (JavaFunction) inputAction.getExec();
+        assertThat(exec.getQualName()).isEqualTo(TestAgent.class.getName());
+        assertThat(exec.getMethodName()).isEqualTo("handleInputEvent");
+        assertThat(exec.getParameterTypes()).containsExactly(InputEvent.class, RunnerContext.class);
+
+        // Verify action details for handleMultipleEvents
+        Action multiAction = agentPlan.getActions().get("handleMultipleEvents");
+        assertThat(multiAction).isNotNull();
+        assertThat(multiAction.getName()).isEqualTo("handleMultipleEvents");
+        assertThat(multiAction.getListenEventTypes())
+                .isEqualTo(List.of(TestEvent.class.getName(), OutputEvent.class.getName()));
+        assertThat(multiAction.getExec()).isInstanceOf(JavaFunction.class);
+
+        // Verify actionsByEvent mapping
+        assertThat(agentPlan.getActionsByEvent().size()).isEqualTo(3);
+
+        // Check InputEvent mapping
+        List<Action> inputEventActions =
+                agentPlan.getActionsByEvent().get(InputEvent.class.getName());
+        assertThat(inputEventActions).isNotNull();
+        assertThat(inputEventActions.size()).isEqualTo(1);
+        assertThat(inputEventActions.get(0).getName()).isEqualTo("handleInputEvent");
+
+        // Check TestEvent mapping
+        List<Action> testEventActions =
+                agentPlan.getActionsByEvent().get(TestEvent.class.getName());
+        assertThat(testEventActions).isNotNull();
+        assertThat(testEventActions.size()).isEqualTo(1);
+        assertThat(testEventActions.get(0).getName()).isEqualTo("handleMultipleEvents");
+
+        // Check OutputEvent mapping
+        List<Action> outputEventActions =
+                agentPlan.getActionsByEvent().get(OutputEvent.class.getName());
+        assertThat(outputEventActions).isNotNull();
+        assertThat(outputEventActions.size()).isEqualTo(1);
+        assertThat(outputEventActions.get(0).getName()).isEqualTo("handleMultipleEvents");
+    }
+
+    @Test
+    public void testConstructorWithAgentNoActions() throws Exception {
+        // Create an agent with no annotated methods
+        Agent emptyAgent = new Agent() {
+                    // No annotated methods
+                };
+
+        // Create AgentPlan using the new constructor
+        AgentPlan agentPlan = new AgentPlan(emptyAgent);
+
+        // Verify that no actions were collected
+        assertThat(agentPlan.getActions().size()).isEqualTo(0);
+        assertThat(agentPlan.getActionsByEvent().size()).isEqualTo(0);
+    }
+}
diff --git a/plan/src/test/java/org/apache/flink/agents/plan/serializer/AgentPlanJsonSerializerTest.java b/plan/src/test/java/org/apache/flink/agents/plan/serializer/AgentPlanJsonSerializerTest.java
index d259f4f..2e3058c 100644
--- a/plan/src/test/java/org/apache/flink/agents/plan/serializer/AgentPlanJsonSerializerTest.java
+++ b/plan/src/test/java/org/apache/flink/agents/plan/serializer/AgentPlanJsonSerializerTest.java
@@ -18,6 +18,8 @@
 
 package org.apache.flink.agents.plan.serializer;
 
+import org.apache.flink.agents.api.Agent;
+import org.apache.flink.agents.api.Event;
 import org.apache.flink.agents.api.InputEvent;
 import org.apache.flink.agents.api.OutputEvent;
 import org.apache.flink.agents.api.context.RunnerContext;
@@ -31,10 +33,35 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.assertj.core.api.Assertions.assertThat;
 
 /** Test for {@link AgentPlanJsonSerializer}. */
 public class AgentPlanJsonSerializerTest {
+
+    /** Test Agent class with @Action annotated methods. */
+    public static class TestAgent extends Agent {
+
+        @org.apache.flink.agents.api.Action(listenEvents = {InputEvent.class})
+        public void handleInputEvent(InputEvent event, RunnerContext context) {
+            // Test action logic
+        }
+
+        @org.apache.flink.agents.api.Action(listenEvents = {OutputEvent.class})
+        public void processOutputEvent(OutputEvent event, RunnerContext context) {
+            // Test action logic
+        }
+
+        @org.apache.flink.agents.api.Action(listenEvents = {InputEvent.class, OutputEvent.class})
+        public void handleMultipleEvents(Event event, RunnerContext context) {
+            // Test action logic for multiple event types
+        }
+
+        // Non-annotated method should be ignored
+        public void regularMethod() {
+            // This should not be included in the AgentPlan
+        }
+    }
+
     @Test
     public void testSerializeAgentPlanWithActions() throws Exception {
         // Create a JavaFunction
@@ -58,27 +85,16 @@ public class AgentPlanJsonSerializerTest {
         String json = new ObjectMapper().writeValueAsString(agentPlan);
 
         // Verify the JSON contains the expected fields
-        assertTrue(json.contains("\"actions\":{"), "JSON should contain the actions field");
-        assertTrue(json.contains("\"testAction\":{"), "JSON should contain the action name");
-        assertTrue(json.contains("\"name\":\"testAction\""), "JSON should contain the action name");
-        assertTrue(json.contains("\"exec\":{"), "JSON should contain the exec field");
-        assertTrue(
-                json.contains("\"func_type\":\"JavaFunction\""),
-                "JSON should contain the function type");
-        assertTrue(
-                json.contains("\"qualname\":\"org.apache.flink.agents.plan.TestAction\""),
-                "JSON should contain the function's qualified name");
-        assertTrue(
-                json.contains("\"method_name\":\"legal\""), "JSON should contain the method name");
-        assertTrue(
-                json.contains("\"listen_event_types\":["),
-                "JSON should contain the listen event types");
-        assertTrue(
-                json.contains("\"org.apache.flink.agents.api.InputEvent\""),
-                "JSON should contain the event type class name");
-        assertTrue(
-                json.contains("\"actions_by_event\":{}"),
-                "JSON should contain empty event trigger actions");
+        assertThat(json).contains("\"actions\":{");
+        assertThat(json).contains("\"testAction\":{");
+        assertThat(json).contains("\"name\":\"testAction\"");
+        assertThat(json).contains("\"exec\":{");
+        assertThat(json).contains("\"func_type\":\"JavaFunction\"");
+        assertThat(json).contains("\"qualname\":\"org.apache.flink.agents.plan.TestAction\"");
+        assertThat(json).contains("\"method_name\":\"legal\"");
+        assertThat(json).contains("\"listen_event_types\":[");
+        assertThat(json).contains("\"org.apache.flink.agents.api.InputEvent\"");
+        assertThat(json).contains("\"actions_by_event\":{}");
     }
 
     @Test
@@ -104,16 +120,10 @@ public class AgentPlanJsonSerializerTest {
         String json = new ObjectMapper().writeValueAsString(agentPlan);
 
         // Verify the JSON contains the expected fields
-        assertTrue(json.contains("\"actions\":{}"), "JSON should contain empty actions");
-        assertTrue(
-                json.contains("\"actions_by_event\":{"),
-                "JSON should contain the event trigger actions field");
-        assertTrue(
-                json.contains("\"org.apache.flink.agents.api.InputEvent\":["),
-                "JSON should contain the event class name and an array of action names");
-        assertTrue(
-                json.contains("\"testAction\""),
-                "JSON should contain the action name in event triggers");
+        assertThat(json).contains("\"actions\":{}");
+        assertThat(json).contains("\"actions_by_event\":{");
+        assertThat(json).contains("\"org.apache.flink.agents.api.InputEvent\":[");
+        assertThat(json).contains("\"testAction\"");
     }
 
     @Test
@@ -151,24 +161,14 @@ public class AgentPlanJsonSerializerTest {
         String json = new ObjectMapper().writeValueAsString(agentPlan);
 
         // Verify the JSON contains the expected fields
-        assertTrue(json.contains("\"actions\":{"), "JSON should contain the actions field");
-        assertTrue(json.contains("\"action1\":{"), "JSON should contain the first action name");
-        assertTrue(json.contains("\"action2\":{"), "JSON should contain the second action name");
-        assertTrue(
-                json.contains("\"actions_by_event\":{"),
-                "JSON should contain the event trigger actions field");
-        assertTrue(
-                json.contains("\"org.apache.flink.agents.api.InputEvent\":["),
-                "JSON should contain the InputEvent class name and an array of action names");
-        assertTrue(
-                json.contains("\"org.apache.flink.agents.api.OutputEvent\":["),
-                "JSON should contain the OutputEvent class name and an array of action names");
-        assertTrue(
-                json.contains("\"action1\""),
-                "JSON should contain the first action name in event triggers");
-        assertTrue(
-                json.contains("\"action2\""),
-                "JSON should contain the second action name in event triggers");
+        assertThat(json).contains("\"actions\":{");
+        assertThat(json).contains("\"action1\":{");
+        assertThat(json).contains("\"action2\":{");
+        assertThat(json).contains("\"actions_by_event\":{");
+        assertThat(json).contains("\"org.apache.flink.agents.api.InputEvent\":[");
+        assertThat(json).contains("\"org.apache.flink.agents.api.OutputEvent\":[");
+        assertThat(json).contains("\"action1\"");
+        assertThat(json).contains("\"action2\"");
     }
 
     @Test
@@ -180,9 +180,41 @@ public class AgentPlanJsonSerializerTest {
         String json = new ObjectMapper().writeValueAsString(agentPlan);
 
         // Verify the JSON contains the expected fields
-        assertTrue(json.contains("\"actions\":{}"), "JSON should contain empty actions");
-        assertTrue(
-                json.contains("\"actions_by_event\":{}"),
-                "JSON should contain empty event trigger actions");
+        assertThat(json).contains("\"actions\":{}");
+        assertThat(json).contains("\"actions_by_event\":{}");
+    }
+
+    @Test
+    public void testSerializeAgentPlanCreatedFromAgent() throws Exception {
+        // Create a test agent
+        TestAgent agent = new TestAgent();
+
+        // Create AgentPlan from the agent
+        AgentPlan agentPlan = new AgentPlan(agent);
+
+        // Serialize the agent plan to JSON
+        String json = new ObjectMapper().writeValueAsString(agentPlan);
+
+        // Verify the JSON contains the expected fields
+        assertThat(json).contains("\"actions\":{");
+        assertThat(json).contains("\"actions_by_event\":{");
+
+        // Verify that the actions from @Action annotated methods are present
+        assertThat(json).contains("\"handleInputEvent\"");
+        assertThat(json).contains("\"processOutputEvent\"");
+        assertThat(json).contains("\"handleMultipleEvents\"");
+
+        // Verify event mappings
+        assertThat(json).contains("\"org.apache.flink.agents.api.InputEvent\"");
+        assertThat(json).contains("\"org.apache.flink.agents.api.OutputEvent\"");
+
+        // Verify function details
+        assertThat(json).contains("\"func_type\":\"JavaFunction\"");
+        assertThat(json)
+                .contains(
+                        "\"qualname\":\"org.apache.flink.agents.plan.serializer.AgentPlanJsonSerializerTest$TestAgent\"");
+
+        // Verify that regularMethod is not included (not annotated)
+        assertThat(json).doesNotContain("\"regularMethod\"");
     }
 }
diff --git a/pom.xml b/pom.xml
index 71fd697..f52f255 100644
--- a/pom.xml
+++ b/pom.xml
@@ -65,6 +65,12 @@ under the License.
             <version>${junit5.version}</version>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <version>${assertj.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
diff --git a/runtime/pom.xml b/runtime/pom.xml
index 3f69580..be95de6 100644
--- a/runtime/pom.xml
+++ b/runtime/pom.xml
@@ -119,14 +119,6 @@ under the License.
             <artifactId>log4j-slf4j-impl</artifactId>
             <version>${log4j2.version}</version>
         </dependency>
-
-        <!-- TEST -->
-        <dependency>
-            <groupId>org.assertj</groupId>
-            <artifactId>assertj-core</artifactId>
-            <version>${assertj.version}</version>
-            <scope>test</scope>
-        </dependency>
     </dependencies>
 
 </project>
\ No newline at end of file