From 17bd451964b91a28ab8c0efbb9a2542f9140cbe2 Mon Sep 17 00:00:00 2001
From: fsoldatos <fsoldatos@ubitech.eu>
Date: Thu, 4 Nov 2021 13:45:59 +0200
Subject: [PATCH] feat: streams implementation for automation service

---
 deploy_in_kubernetes.sh                       |   37 +-
 proto/automation.proto                        |   17 +-
 src/automation/Dockerfile                     |    1 +
 .../automation/AutomationConfiguration.java   |    9 +
 .../automation/AutomationGatewayImpl.java     |   30 +-
 .../automation/AutomationService.java         |    4 +-
 .../automation/AutomationServiceImpl.java     |   12 +-
 .../automation/ContextSubscriber.java         |   49 +
 .../automation/context/ContextGateway.java    |    4 +
 .../context/ContextGatewayImpl.java           |   45 +
 .../automation/context/ContextService.java    |    4 +
 .../context/ContextServiceImpl.java           |    8 +
 .../automation/context/model/Event.java       |   20 +
 .../context/model/EventTypeEnum.java          |    8 +
 .../automation/device/model/DeviceEvent.java  |   22 +
 .../automation/model/DeviceState.java         |    9 +-
 .../src/main/resources/application.yaml       |    2 +
 .../AutomationFunctionalServiceTest.java      |   58 +-
 .../automation/AutomationServiceTest.java     |   16 +-
 .../grpc/automation/Automation.java           | 1274 +++++++++++++++--
 .../grpc/automation/AutomationService.java    |    2 +-
 .../automation/AutomationServiceBean.java     |    4 +-
 .../automation/AutomationServiceClient.java   |    4 +-
 .../automation/AutomationServiceGrpc.java     |   74 +-
 .../MutinyAutomationServiceGrpc.java          |   24 +-
 .../target/kubernetes/kubernetes.yml          |   30 +-
 26 files changed, 1489 insertions(+), 278 deletions(-)
 create mode 120000 src/automation/Dockerfile
 create mode 100644 src/automation/src/main/java/eu/teraflow/automation/AutomationConfiguration.java
 create mode 100644 src/automation/src/main/java/eu/teraflow/automation/ContextSubscriber.java
 create mode 100644 src/automation/src/main/java/eu/teraflow/automation/context/model/Event.java
 create mode 100644 src/automation/src/main/java/eu/teraflow/automation/context/model/EventTypeEnum.java
 create mode 100644 src/automation/src/main/java/eu/teraflow/automation/device/model/DeviceEvent.java

diff --git a/deploy_in_kubernetes.sh b/deploy_in_kubernetes.sh
index 2abfecaf4..44cdb0243 100755
--- a/deploy_in_kubernetes.sh
+++ b/deploy_in_kubernetes.sh
@@ -10,7 +10,7 @@ REGISTRY_IMAGE=""
 #REGISTRY_IMAGE="http://my-container-registry.local/"
 
 # Set the list of components you want to build images for, and deploy.
-COMPONENTS="context device service compute monitoring centralizedattackdetector"
+COMPONENTS="context device automation service compute monitoring centralizedattackdetector"
 
 # Set the tag you want to use for your images.
 IMAGE_TAG="tf-dev"
@@ -18,7 +18,6 @@ IMAGE_TAG="tf-dev"
 # Set the name of the Kubernetes namespace to deploy to.
 K8S_NAMESPACE="tf-dev"
 
-
 ########################################################################################################################
 # Automated steps start here
 ########################################################################################################################
@@ -34,10 +33,10 @@ mkdir -p $TMP_MANIFESTS_FOLDER
 TMP_LOGS_FOLDER="$TMP_FOLDER/logs"
 mkdir -p $TMP_LOGS_FOLDER
 
-
 # Re-create the namespace to prevent being affected by garbage on it
 kubectl delete namespace $K8S_NAMESPACE
 kubectl create namespace $K8S_NAMESPACE
+printf "\n"
 
 for COMPONENT in $COMPONENTS; do
     echo "Processing '$COMPONENT' component..."
@@ -46,34 +45,44 @@ for COMPONENT in $COMPONENTS; do
 
     echo "  Building Docker image..."
     BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}.log"
-    docker build -t "$IMAGE_NAME" -f ./src/$COMPONENT/Dockerfile ./src/ > $BUILD_LOG
+
+    if [ "$COMPONENT" == "automation" ]; then
+        docker build -t "$IMAGE_NAME" -f ./src/"$COMPONENT"/Dockerfile ./src/"$COMPONENT"/ > "$BUILD_LOG"
+    else 
+        docker build -t "$IMAGE_NAME" -f ./src/"$COMPONENT"/Dockerfile ./src/ > "$BUILD_LOG"
+    fi
 
     if [ -n "$REGISTRY_IMAGE" ]; then
         echo "Pushing Docker image to '$REGISTRY_IMAGE'..."
 
         TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}.log"
-        docker tag "$IMAGE_NAME" "$IMAGE_URL" > $TAG_LOG
+        docker tag "$IMAGE_NAME" "$IMAGE_URL" > "$TAG_LOG"
 
         PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}.log"
         docker push "$IMAGE_URL" > "$PUSH_LOG"
     fi
 
-    echo "  Adapting manifest file..."
+    echo "  Adapting '$COMPONENT' manifest file..."
     MANIFEST="$TMP_MANIFESTS_FOLDER/${COMPONENT}service.yaml"
-    cp ./manifests/${COMPONENT}service.yaml $MANIFEST
+    cp ./manifests/"${COMPONENT}"service.yaml "$MANIFEST"
+    VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}:" "$MANIFEST" | cut -d ":" -f3)
+
     if [ -n "$REGISTRY_IMAGE" ]; then
-        sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT:latest#image: $IMAGE_URL#g" $MANIFEST
-        sed -E -i "s#imagePullPolicy: .*#imagePullPolicy: Always#g" $MANIFEST
+
+        sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST"
+        sed -E -i "s#imagePullPolicy: .*#imagePullPolicy: Always#g" "$MANIFEST"
+   
     else
-        sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT:latest#image: $IMAGE_NAME#g" $MANIFEST
-        sed -E -i "s#imagePullPolicy: .*#imagePullPolicy: Never#g" $MANIFEST
+        sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT:${VERSION}#image: $IMAGE_NAME#g" "$MANIFEST"
+        sed -E -i "s#imagePullPolicy: .*#imagePullPolicy: Never#g" "$MANIFEST"        
     fi
 
-    echo "  Deploying to Kubernetes..."
+    echo "  Deploying '$COMPONENT' component to Kubernetes..."
     DEPLOY_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}.log"
-    kubectl --namespace $K8S_NAMESPACE apply -f $MANIFEST > $DEPLOY_LOG
+    kubectl --namespace $K8S_NAMESPACE apply -f "$MANIFEST" > "$DEPLOY_LOG"
+    printf "\n"
 done
 
 kubectl --namespace $K8S_NAMESPACE get all
 
-echo "Done!"
+echo "Done!"
\ No newline at end of file
diff --git a/proto/automation.proto b/proto/automation.proto
index 9df2d0e29..6de1d51e2 100644
--- a/proto/automation.proto
+++ b/proto/automation.proto
@@ -10,7 +10,7 @@ service AutomationService {
   rpc ZtpAdd(DeviceRole) returns (DeviceRoleState) {}
   rpc ZtpUpdate(DeviceRole) returns (DeviceRoleState) {}
   rpc ZtpDelete(DeviceRole) returns (DeviceRoleState) {}
-  rpc ZtpDeleteAllByDeviceId(context.DeviceId) returns (DeviceRoleState) {}
+  rpc ZtpDeleteAll(Empty) returns (DeviceDeletionResult) {}
 }
 
 enum DeviceRoleType {
@@ -39,12 +39,17 @@ message DeviceRoleState {
   ZtpDeviceState devRoleState = 2;
 }
 
+message DeviceDeletionResult {
+  repeated bool deleted = 1;
+}
+
+message Empty {}
+
 enum ZtpDeviceState {
-  PLANNED  = 0;
-  POTENCIAL_AVAILABLE = 1;
-  POTENCIAL_BUSY = 2;
-  INSTALLED = 3;
-  PENDING_REMOVAL = 4;
+  ZTP_DEV_STATE_UNDEFINED = 0;
+  ZTP_DEV_STATE_CREATED  = 1;
+  ZTP_DEV_STATE_UPDATED  = 2;
+  ZTP_DEV_STATE_DELETED  = 3;
 }
 
 
diff --git a/src/automation/Dockerfile b/src/automation/Dockerfile
new file mode 120000
index 000000000..eec732273
--- /dev/null
+++ b/src/automation/Dockerfile
@@ -0,0 +1 @@
+src/main/docker/Dockerfile.multistage.jvm
\ No newline at end of file
diff --git a/src/automation/src/main/java/eu/teraflow/automation/AutomationConfiguration.java b/src/automation/src/main/java/eu/teraflow/automation/AutomationConfiguration.java
new file mode 100644
index 000000000..7d50b7d51
--- /dev/null
+++ b/src/automation/src/main/java/eu/teraflow/automation/AutomationConfiguration.java
@@ -0,0 +1,9 @@
+package eu.teraflow.automation;
+
+import io.smallrye.config.ConfigMapping;
+
+@ConfigMapping(prefix = "automation")
+public interface AutomationConfiguration {
+
+    boolean shouldSubscribeToContextComponent();
+}
diff --git a/src/automation/src/main/java/eu/teraflow/automation/AutomationGatewayImpl.java b/src/automation/src/main/java/eu/teraflow/automation/AutomationGatewayImpl.java
index 39c8ca6bb..8e9805156 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/AutomationGatewayImpl.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/AutomationGatewayImpl.java
@@ -4,9 +4,6 @@ import automation.Automation;
 import context.ContextOuterClass;
 import eu.teraflow.automation.device.model.DeviceId;
 import eu.teraflow.automation.device.model.Uuid;
-import eu.teraflow.automation.model.DeviceRole;
-import eu.teraflow.automation.model.DeviceRoleId;
-import eu.teraflow.automation.model.DeviceRoleType;
 import io.quarkus.grpc.GrpcService;
 import io.smallrye.mutiny.Uni;
 import javax.inject.Inject;
@@ -36,7 +33,7 @@ public class AutomationGatewayImpl implements AutomationGateway {
     @Override
     public Uni<Automation.DeviceRoleState> ztpAdd(Automation.DeviceRole request) {
 
-        automationService.ztpAdd(getDeviceRole(request));
+        automationService.addDevice(getDeviceId(request.getDevRoleId().getDevId()));
 
         return Uni.createFrom()
                 .item(
@@ -67,29 +64,14 @@ public class AutomationGatewayImpl implements AutomationGateway {
     }
 
     @Override
-    public Uni<Automation.DeviceRoleState> ztpDeleteAllByDeviceId(
-            ContextOuterClass.DeviceId request) {
-        return Uni.createFrom().item(() -> Automation.DeviceRoleState.newBuilder().build());
+    public Uni<Automation.DeviceDeletionResult> ztpDeleteAll(Automation.Empty empty) {
+        return Uni.createFrom().item(() -> Automation.DeviceDeletionResult.newBuilder().build());
     }
 
-    private DeviceRole getDeviceRole(Automation.DeviceRole deviceRole) {
-        final var OutDeviceId = deviceRole.getDevRoleId().getDevId().getDeviceUuid();
-
-        Uuid uuid = new Uuid(OutDeviceId.getUuid());
-        DeviceId deviceId = new DeviceId(uuid);
-
-        DeviceRoleId deviceRoleId = new DeviceRoleId(uuid, deviceId);
+    private DeviceId getDeviceId(ContextOuterClass.DeviceId serializedDeviceId) {
 
-        final var deviceRoleType = deviceRole.getDevRoleType();
+        Uuid uuid = new Uuid(serializedDeviceId.getDeviceUuid().getUuid());
 
-        if (deviceRoleType == Automation.DeviceRoleType.DEV_OPS) {
-            return new DeviceRole(deviceRoleId, DeviceRoleType.DEV_OPS);
-        } else if (deviceRoleType == Automation.DeviceRoleType.DEV_CONF) {
-            return new DeviceRole(deviceRoleId, DeviceRoleType.DEV_CONF);
-        } else if (deviceRoleType == Automation.DeviceRoleType.NONE) {
-            return new DeviceRole(deviceRoleId, DeviceRoleType.NONE);
-        } else {
-            return new DeviceRole(deviceRoleId, DeviceRoleType.PIPELINE_CONF);
-        }
+        return new DeviceId(uuid);
     }
 }
diff --git a/src/automation/src/main/java/eu/teraflow/automation/AutomationService.java b/src/automation/src/main/java/eu/teraflow/automation/AutomationService.java
index 2ff426597..1c76fc487 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/AutomationService.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/AutomationService.java
@@ -1,10 +1,10 @@
 package eu.teraflow.automation;
 
 import eu.teraflow.automation.device.Device;
-import eu.teraflow.automation.model.DeviceRole;
+import eu.teraflow.automation.device.model.DeviceId;
 import io.smallrye.mutiny.Uni;
 
 public interface AutomationService {
 
-    Uni<Device> ztpAdd(DeviceRole deviceRole);
+    Uni<Device> addDevice(DeviceId deviceId);
 }
diff --git a/src/automation/src/main/java/eu/teraflow/automation/AutomationServiceImpl.java b/src/automation/src/main/java/eu/teraflow/automation/AutomationServiceImpl.java
index ee6fa8768..fc62e77ec 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/AutomationServiceImpl.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/AutomationServiceImpl.java
@@ -3,8 +3,7 @@ package eu.teraflow.automation;
 import eu.teraflow.automation.context.ContextService;
 import eu.teraflow.automation.device.Device;
 import eu.teraflow.automation.device.DeviceService;
-import eu.teraflow.automation.device.model.DeviceOperationalStatus;
-import eu.teraflow.automation.model.DeviceRole;
+import eu.teraflow.automation.device.model.*;
 import io.smallrye.mutiny.Uni;
 import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
@@ -24,9 +23,9 @@ public class AutomationServiceImpl implements AutomationService {
     }
 
     @Override
-    public Uni<Device> ztpAdd(DeviceRole deviceRole) {
+    public Uni<Device> addDevice(DeviceId deviceId) {
 
-        final var deviceUni = contextService.getDevice(deviceRole.getDeviceRoleId().getDeviceId());
+        final var deviceUni = contextService.getDevice(deviceId);
 
         deviceUni
                 .subscribe()
@@ -37,9 +36,7 @@ public class AutomationServiceImpl implements AutomationService {
                                     .toString()
                                     .equals(DeviceOperationalStatus.ENABLED.toString()))) {
 
-                                final var initialConfig =
-                                        deviceService.getInitialConfiguration(
-                                                deviceRole.getDeviceRoleId().getDeviceId());
+                                final var initialConfig = deviceService.getInitialConfiguration(deviceId);
 
                                 device.setDeviceOperationalStatus(DeviceOperationalStatus.ENABLED);
 
@@ -49,7 +46,6 @@ public class AutomationServiceImpl implements AutomationService {
                                                 deviceConfig -> {
                                                     device.setDeviceConfiguration(deviceConfig);
                                                     deviceService.configureDevice(device);
-
                                                     LOGGER.infof("Received response %s", device);
                                                 });
                             }
diff --git a/src/automation/src/main/java/eu/teraflow/automation/ContextSubscriber.java b/src/automation/src/main/java/eu/teraflow/automation/ContextSubscriber.java
new file mode 100644
index 000000000..cedbce546
--- /dev/null
+++ b/src/automation/src/main/java/eu/teraflow/automation/ContextSubscriber.java
@@ -0,0 +1,49 @@
+package eu.teraflow.automation;
+
+import eu.teraflow.automation.context.ContextService;
+import eu.teraflow.automation.device.model.DeviceEvent;
+import io.quarkus.runtime.StartupEvent;
+import io.smallrye.mutiny.Multi;
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.event.Observes;
+import javax.inject.Inject;
+import org.jboss.logging.Logger;
+
+@ApplicationScoped
+public class ContextSubscriber {
+
+    private static final Logger LOGGER = Logger.getLogger(ContextSubscriber.class);
+
+    private final ContextService contextService;
+    private final AutomationService automationService;
+    private final AutomationConfiguration automationConfiguration;
+
+    @Inject
+    public ContextSubscriber(
+            ContextService contextService,
+            AutomationService automationService,
+            AutomationConfiguration automationConfiguration) {
+        this.contextService = contextService;
+        this.automationService = automationService;
+        this.automationConfiguration = automationConfiguration;
+    }
+
+    public void listenForDeviceEvents() {
+        Multi<DeviceEvent> deviceEventsMulti = contextService.getDeviceEvents();
+
+        deviceEventsMulti
+                .onItem()
+                .transformToUniAndConcatenate(
+                        deviceEvent -> automationService.addDevice(deviceEvent.getDeviceId()));
+    }
+
+    void onStart(@Observes StartupEvent ev) {
+
+        if (automationConfiguration.shouldSubscribeToContextComponent()) {
+            LOGGER.info("Listening for Device events...");
+            listenForDeviceEvents();
+        } else {
+            LOGGER.info("Not listening for Device events...");
+        }
+    }
+}
diff --git a/src/automation/src/main/java/eu/teraflow/automation/context/ContextGateway.java b/src/automation/src/main/java/eu/teraflow/automation/context/ContextGateway.java
index c27aec136..e08a706ed 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/context/ContextGateway.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/context/ContextGateway.java
@@ -1,10 +1,14 @@
 package eu.teraflow.automation.context;
 
 import eu.teraflow.automation.device.Device;
+import eu.teraflow.automation.device.model.DeviceEvent;
 import eu.teraflow.automation.device.model.DeviceId;
+import io.smallrye.mutiny.Multi;
 import io.smallrye.mutiny.Uni;
 
 public interface ContextGateway {
 
     Uni<Device> getDevice(DeviceId deviceId);
+
+    Multi<DeviceEvent> getDeviceEvents();
 }
diff --git a/src/automation/src/main/java/eu/teraflow/automation/context/ContextGatewayImpl.java b/src/automation/src/main/java/eu/teraflow/automation/context/ContextGatewayImpl.java
index bec35c9e5..d52638267 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/context/ContextGatewayImpl.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/context/ContextGatewayImpl.java
@@ -2,9 +2,12 @@ package eu.teraflow.automation.context;
 
 import context.ContextOuterClass;
 import context.ContextService;
+import eu.teraflow.automation.context.model.Event;
+import eu.teraflow.automation.context.model.EventTypeEnum;
 import eu.teraflow.automation.device.Device;
 import eu.teraflow.automation.device.model.*;
 import io.quarkus.grpc.GrpcClient;
+import io.smallrye.mutiny.Multi;
 import io.smallrye.mutiny.Uni;
 import javax.enterprise.context.ApplicationScoped;
 
@@ -13,6 +16,15 @@ public class ContextGatewayImpl implements ContextGateway {
 
     @GrpcClient ContextService delegate;
 
+    @Override
+    public Multi<DeviceEvent> getDeviceEvents() {
+
+        final var serializedEmpty = getSerializedEmpty();
+        final var deviceEventsMulti = delegate.getDeviceEvents(serializedEmpty);
+
+        return deviceEventsMulti.onItem().transform(this::getDeviceEvent);
+    }
+
     @Override
     public Uni<Device> getDevice(DeviceId deviceId) {
         final var serializedDeviceId = getSerializedDeviceId(deviceId);
@@ -21,6 +33,39 @@ public class ContextGatewayImpl implements ContextGateway {
         return serializedDeviceUni.onItem().transform(this::getDevice);
     }
 
+    private ContextOuterClass.Empty getSerializedEmpty() {
+
+        return ContextOuterClass.Empty.newBuilder().build();
+    }
+
+    private DeviceEvent getDeviceEvent(ContextOuterClass.DeviceEvent deviceEvent) {
+
+        final var serializedDeviceId = deviceEvent.getDeviceId();
+        final var deviceId = getDeviceId(serializedDeviceId);
+
+        final var serializedEvent = deviceEvent.getEvent();
+        final var event = getEvent(serializedEvent);
+
+        return new DeviceEvent(event, deviceId);
+    }
+
+    private Event getEvent(ContextOuterClass.Event event) {
+        return new Event(event.getTimestamp(), getEventType(event.getEventType()));
+    }
+
+    private EventTypeEnum getEventType(ContextOuterClass.EventTypeEnum eventType) {
+
+        if (eventType == ContextOuterClass.EventTypeEnum.EVENTTYPE_CREATE) {
+            return EventTypeEnum.CREATE;
+        } else if (eventType == ContextOuterClass.EventTypeEnum.EVENTTYPE_REMOVE) {
+            return EventTypeEnum.REMOVE;
+        } else if (eventType == ContextOuterClass.EventTypeEnum.EVENTTYPE_UPDATE) {
+            return EventTypeEnum.UPDATE;
+        } else {
+            return EventTypeEnum.UNDEFINED;
+        }
+    }
+
     private Device getDevice(ContextOuterClass.Device device) {
 
         final var deviceId = getDeviceId(device.getDeviceId());
diff --git a/src/automation/src/main/java/eu/teraflow/automation/context/ContextService.java b/src/automation/src/main/java/eu/teraflow/automation/context/ContextService.java
index b51a49a5f..2a2cd61af 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/context/ContextService.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/context/ContextService.java
@@ -1,10 +1,14 @@
 package eu.teraflow.automation.context;
 
 import eu.teraflow.automation.device.Device;
+import eu.teraflow.automation.device.model.DeviceEvent;
 import eu.teraflow.automation.device.model.DeviceId;
+import io.smallrye.mutiny.Multi;
 import io.smallrye.mutiny.Uni;
 
 public interface ContextService {
 
     Uni<Device> getDevice(DeviceId deviceId);
+
+    Multi<DeviceEvent> getDeviceEvents();
 }
diff --git a/src/automation/src/main/java/eu/teraflow/automation/context/ContextServiceImpl.java b/src/automation/src/main/java/eu/teraflow/automation/context/ContextServiceImpl.java
index 98a055a90..3277964e8 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/context/ContextServiceImpl.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/context/ContextServiceImpl.java
@@ -1,7 +1,9 @@
 package eu.teraflow.automation.context;
 
 import eu.teraflow.automation.device.Device;
+import eu.teraflow.automation.device.model.DeviceEvent;
 import eu.teraflow.automation.device.model.DeviceId;
+import io.smallrye.mutiny.Multi;
 import io.smallrye.mutiny.Uni;
 import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
@@ -21,4 +23,10 @@ public class ContextServiceImpl implements ContextService {
 
         return contextGateway.getDevice(deviceId);
     }
+
+    @Override
+    public Multi<DeviceEvent> getDeviceEvents() {
+
+        return contextGateway.getDeviceEvents();
+    }
 }
diff --git a/src/automation/src/main/java/eu/teraflow/automation/context/model/Event.java b/src/automation/src/main/java/eu/teraflow/automation/context/model/Event.java
new file mode 100644
index 000000000..fa09c7899
--- /dev/null
+++ b/src/automation/src/main/java/eu/teraflow/automation/context/model/Event.java
@@ -0,0 +1,20 @@
+package eu.teraflow.automation.context.model;
+
+public class Event {
+
+    private double timestamp;
+    private EventTypeEnum eventType;
+
+    public Event(double timestamp, EventTypeEnum eventType) {
+        this.timestamp = timestamp;
+        this.eventType = eventType;
+    }
+
+    public double getTimestamp() {
+        return timestamp;
+    }
+
+    public EventTypeEnum getEventTypeEnum() {
+        return eventType;
+    }
+}
diff --git a/src/automation/src/main/java/eu/teraflow/automation/context/model/EventTypeEnum.java b/src/automation/src/main/java/eu/teraflow/automation/context/model/EventTypeEnum.java
new file mode 100644
index 000000000..d29b29371
--- /dev/null
+++ b/src/automation/src/main/java/eu/teraflow/automation/context/model/EventTypeEnum.java
@@ -0,0 +1,8 @@
+package eu.teraflow.automation.context.model;
+
+public enum EventTypeEnum {
+    UNDEFINED,
+    CREATE,
+    UPDATE,
+    REMOVE
+}
diff --git a/src/automation/src/main/java/eu/teraflow/automation/device/model/DeviceEvent.java b/src/automation/src/main/java/eu/teraflow/automation/device/model/DeviceEvent.java
new file mode 100644
index 000000000..ef3f8ae76
--- /dev/null
+++ b/src/automation/src/main/java/eu/teraflow/automation/device/model/DeviceEvent.java
@@ -0,0 +1,22 @@
+package eu.teraflow.automation.device.model;
+
+import eu.teraflow.automation.context.model.Event;
+
+public class DeviceEvent {
+
+    private Event event;
+    private DeviceId deviceId;
+
+    public DeviceEvent(Event event, DeviceId deviceId) {
+        this.event = event;
+        this.deviceId = deviceId;
+    }
+
+    public Event getEvent() {
+        return event;
+    }
+
+    public DeviceId getDeviceId() {
+        return deviceId;
+    }
+}
diff --git a/src/automation/src/main/java/eu/teraflow/automation/model/DeviceState.java b/src/automation/src/main/java/eu/teraflow/automation/model/DeviceState.java
index 8660baa95..279faeb5d 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/model/DeviceState.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/model/DeviceState.java
@@ -1,9 +1,8 @@
 package eu.teraflow.automation.model;
 
 public enum DeviceState {
-    PLANNED,
-    POTENCIAL_AVAILABLE,
-    POTENCIAL_BUSY,
-    INSTALLED,
-    PENDING_REMOVAL
+    UNDEFINED,
+    CREATED,
+    UPDATED,
+    DELETED
 }
diff --git a/src/automation/src/main/resources/application.yaml b/src/automation/src/main/resources/application.yaml
index 2bacf507e..e559876bf 100644
--- a/src/automation/src/main/resources/application.yaml
+++ b/src/automation/src/main/resources/application.yaml
@@ -1,3 +1,5 @@
+automation:
+  should-subscribe-to-context-component: false
 quarkus:
   grpc:
     server:
diff --git a/src/automation/src/test/java/eu/teraflow/automation/AutomationFunctionalServiceTest.java b/src/automation/src/test/java/eu/teraflow/automation/AutomationFunctionalServiceTest.java
index 92f9dd3f4..81d568f25 100644
--- a/src/automation/src/test/java/eu/teraflow/automation/AutomationFunctionalServiceTest.java
+++ b/src/automation/src/test/java/eu/teraflow/automation/AutomationFunctionalServiceTest.java
@@ -8,9 +8,6 @@ import eu.teraflow.automation.context.ContextGateway;
 import eu.teraflow.automation.device.Device;
 import eu.teraflow.automation.device.DeviceGateway;
 import eu.teraflow.automation.device.model.*;
-import eu.teraflow.automation.model.DeviceRole;
-import eu.teraflow.automation.model.DeviceRoleId;
-import eu.teraflow.automation.model.DeviceRoleType;
 import io.quarkus.test.junit.QuarkusTest;
 import io.quarkus.test.junit.mockito.InjectMock;
 import io.smallrye.mutiny.Uni;
@@ -58,8 +55,8 @@ public class AutomationFunctionalServiceTest {
         DeviceId deviceId = new DeviceId(uuid);
         DeviceType deviceType = new DeviceType("cisco");
 
-        ConfigRule configRule1 = new ConfigRule(ConfigActionEnum.UNDEFINED, "001", "100");
-        ConfigRule configRule2 = new ConfigRule(ConfigActionEnum.SET, "002", "101");
+        ConfigRule configRule1 = new ConfigRule(ConfigActionEnum.UNDEFINED, "1", "1");
+        ConfigRule configRule2 = new ConfigRule(ConfigActionEnum.SET, "2", "2");
         List<ConfigRule> configRuleList = new ArrayList<>();
         configRuleList.add(configRule1);
         configRuleList.add(configRule2);
@@ -68,10 +65,6 @@ public class AutomationFunctionalServiceTest {
         Uni<DeviceConfig> expectedDeviceConfigUni = Uni.createFrom().item(expectedDeviceConfig);
         Uni<DeviceId> expectedDeviceId = Uni.createFrom().item(deviceId);
 
-        DeviceRoleId deviceRoleId = new DeviceRoleId(uuid, deviceId);
-
-        DeviceRole deviceRole = new DeviceRole(deviceRoleId, DeviceRoleType.DEV_CONF);
-
         Device device = new Device(deviceId, deviceType, DeviceOperationalStatus.DISABLED);
         Uni<Device> deviceUni = Uni.createFrom().item(device);
 
@@ -80,7 +73,7 @@ public class AutomationFunctionalServiceTest {
                 .thenReturn(expectedDeviceConfigUni);
         Mockito.when(deviceGateway.configureDevice(Mockito.any())).thenReturn(expectedDeviceId);
 
-        final var currentDevice = automationService.ztpAdd(deviceRole);
+        final var currentDevice = automationService.addDevice(deviceId);
 
         Assertions.assertThat(currentDevice).isNotNull();
         currentDevice
@@ -88,12 +81,21 @@ public class AutomationFunctionalServiceTest {
                 .with(
                         deviceConfig -> {
                             LOGGER.infof("Received response %s", deviceConfig);
+
                             assertThat(deviceConfig.getDeviceOperationalStatus().toString())
                                     .isEqualTo(device.getDeviceOperationalStatus().toString());
+
                             assertThat(deviceConfig.getDeviceConfig().toString()).isNotNull();
-                            assertThat(deviceConfig.getDeviceConfig().toString())
-                                    .isEqualTo(expectedDeviceConfig.toString());
-                            assertThat(deviceConfig.getDeviceId().getId()).isEqualTo(deviceId.getId());
+
+                            final var rulesList = deviceConfig.getDeviceConfig().getConfigRules();
+
+                            for (int i = 0; i < rulesList.size(); i++) {
+                                assertThat(rulesList.get(i).getResourceKey()).isEqualTo(String.valueOf(i + 1));
+                                assertThat(rulesList.get(i).getResourceValue()).isEqualTo(String.valueOf(i + 1));
+                            }
+
+                            assertThat(deviceConfig.getDeviceId().getId().getId())
+                                    .isEqualTo(deviceId.getId().getId());
                         });
     }
 
@@ -125,24 +127,20 @@ public class AutomationFunctionalServiceTest {
 
         List<ConfigRule> configRuleList = new ArrayList<>();
 
-        ConfigRule configRule1 =
+        ConfigRule expectedConfigRule =
                 new ConfigRule(ConfigActionEnum.UNDEFINED, "001", "already-configured");
-        configRuleList.add(configRule1);
+        configRuleList.add(expectedConfigRule);
 
         DeviceConfig expectedDeviceConfig = new DeviceConfig(configRuleList);
 
-        Uuid devRoleIdUuid = new Uuid(outDeviceRoleId.getDevRoleId().getUuid());
-        DeviceRoleId deviceRoleId = new DeviceRoleId(devRoleIdUuid, deviceId);
-
-        DeviceRole deviceRole = new DeviceRole(deviceRoleId, DeviceRoleType.PIPELINE_CONF);
-
         Device device =
                 new Device(deviceId, deviceType, expectedDeviceConfig, DeviceOperationalStatus.ENABLED);
 
         Uni<Device> deviceUni = Uni.createFrom().item(device);
+
         Mockito.when(contextGateway.getDevice(Mockito.any())).thenReturn(deviceUni);
 
-        final var currentDevice = automationService.ztpAdd(deviceRole);
+        final var currentDevice = automationService.addDevice(deviceId);
 
         Assertions.assertThat(currentDevice).isNotNull();
 
@@ -151,13 +149,23 @@ public class AutomationFunctionalServiceTest {
                 .with(
                         deviceConfig -> {
                             LOGGER.infof("Received response %s", deviceConfig);
+
                             assertThat(deviceConfig.getDeviceOperationalStatus().toString())
                                     .isEqualTo(device.getDeviceOperationalStatus().toString());
+
                             assertThat(deviceConfig.getDeviceConfig().toString()).isNotNull();
-                            assertThat(deviceConfig.getDeviceConfig().toString())
-                                    .isEqualTo(expectedDeviceConfig.toString());
-                            assertThat(deviceConfig.getDeviceId().getId().toString())
-                                    .isEqualTo(deviceId.getId().toString());
+
+                            final var rulesList = deviceConfig.getDeviceConfig().getConfigRules();
+
+                            for (ConfigRule configRule : rulesList) {
+                                assertThat(configRule.getResourceKey())
+                                        .isEqualTo(expectedConfigRule.getResourceKey());
+                                assertThat(configRule.getResourceValue())
+                                        .isEqualTo(expectedConfigRule.getResourceValue());
+                            }
+
+                            assertThat(deviceConfig.getDeviceId().getId().getId())
+                                    .isEqualTo(deviceId.getId().getId());
                         });
     }
 }
diff --git a/src/automation/src/test/java/eu/teraflow/automation/AutomationServiceTest.java b/src/automation/src/test/java/eu/teraflow/automation/AutomationServiceTest.java
index 51d6f850f..85e056b87 100644
--- a/src/automation/src/test/java/eu/teraflow/automation/AutomationServiceTest.java
+++ b/src/automation/src/test/java/eu/teraflow/automation/AutomationServiceTest.java
@@ -2,6 +2,7 @@ package eu.teraflow.automation;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
+import automation.Automation;
 import automation.Automation.DeviceRole;
 import automation.Automation.DeviceRoleId;
 import automation.AutomationService;
@@ -177,20 +178,15 @@ class AutomationServiceTest {
             throws ExecutionException, InterruptedException, TimeoutException {
 
         CompletableFuture<String> message = new CompletableFuture<>();
-
-        final var uuid =
-                Uuid.newBuilder()
-                        .setUuid(UUID.fromString("0f14d0ab-9605-4a62-a9e4-5ed26688389b").toString())
-                        .build();
-        final var deviceId = ContextOuterClass.DeviceId.newBuilder().setDeviceUuid(uuid).build();
+        final var empty = Automation.Empty.newBuilder().build();
 
         client
-                .ztpDeleteAllByDeviceId(deviceId)
+                .ztpDeleteAll(empty)
                 .subscribe()
                 .with(
-                        deviceRoleState -> {
-                            LOGGER.infof("Received response %s", deviceRoleState);
-                            message.complete(deviceRoleState.getDevRoleId().toString());
+                        deletionResult -> {
+                            LOGGER.infof("Received response %s", deletionResult);
+                            message.complete(deletionResult.toString());
                         });
         assertThat(message.get(5, TimeUnit.SECONDS)).isEmpty();
     }
diff --git a/src/automation/target/generated-sources/grpc/automation/Automation.java b/src/automation/target/generated-sources/grpc/automation/Automation.java
index c749d05a3..c4eb90a45 100644
--- a/src/automation/target/generated-sources/grpc/automation/Automation.java
+++ b/src/automation/target/generated-sources/grpc/automation/Automation.java
@@ -146,48 +146,40 @@ public final class Automation {
   public enum ZtpDeviceState
       implements com.google.protobuf.ProtocolMessageEnum {
     /**
-     * <code>PLANNED = 0;</code>
+     * <code>ZTP_DEV_STATE_UNDEFINED = 0;</code>
      */
-    PLANNED(0),
+    ZTP_DEV_STATE_UNDEFINED(0),
     /**
-     * <code>POTENCIAL_AVAILABLE = 1;</code>
+     * <code>ZTP_DEV_STATE_CREATED = 1;</code>
      */
-    POTENCIAL_AVAILABLE(1),
+    ZTP_DEV_STATE_CREATED(1),
     /**
-     * <code>POTENCIAL_BUSY = 2;</code>
+     * <code>ZTP_DEV_STATE_UPDATED = 2;</code>
      */
-    POTENCIAL_BUSY(2),
+    ZTP_DEV_STATE_UPDATED(2),
     /**
-     * <code>INSTALLED = 3;</code>
+     * <code>ZTP_DEV_STATE_DELETED = 3;</code>
      */
-    INSTALLED(3),
-    /**
-     * <code>PENDING_REMOVAL = 4;</code>
-     */
-    PENDING_REMOVAL(4),
+    ZTP_DEV_STATE_DELETED(3),
     UNRECOGNIZED(-1),
     ;
 
     /**
-     * <code>PLANNED = 0;</code>
-     */
-    public static final int PLANNED_VALUE = 0;
-    /**
-     * <code>POTENCIAL_AVAILABLE = 1;</code>
+     * <code>ZTP_DEV_STATE_UNDEFINED = 0;</code>
      */
-    public static final int POTENCIAL_AVAILABLE_VALUE = 1;
+    public static final int ZTP_DEV_STATE_UNDEFINED_VALUE = 0;
     /**
-     * <code>POTENCIAL_BUSY = 2;</code>
+     * <code>ZTP_DEV_STATE_CREATED = 1;</code>
      */
-    public static final int POTENCIAL_BUSY_VALUE = 2;
+    public static final int ZTP_DEV_STATE_CREATED_VALUE = 1;
     /**
-     * <code>INSTALLED = 3;</code>
+     * <code>ZTP_DEV_STATE_UPDATED = 2;</code>
      */
-    public static final int INSTALLED_VALUE = 3;
+    public static final int ZTP_DEV_STATE_UPDATED_VALUE = 2;
     /**
-     * <code>PENDING_REMOVAL = 4;</code>
+     * <code>ZTP_DEV_STATE_DELETED = 3;</code>
      */
-    public static final int PENDING_REMOVAL_VALUE = 4;
+    public static final int ZTP_DEV_STATE_DELETED_VALUE = 3;
 
 
     public final int getNumber() {
@@ -214,11 +206,10 @@ public final class Automation {
      */
     public static ZtpDeviceState forNumber(int value) {
       switch (value) {
-        case 0: return PLANNED;
-        case 1: return POTENCIAL_AVAILABLE;
-        case 2: return POTENCIAL_BUSY;
-        case 3: return INSTALLED;
-        case 4: return PENDING_REMOVAL;
+        case 0: return ZTP_DEV_STATE_UNDEFINED;
+        case 1: return ZTP_DEV_STATE_CREATED;
+        case 2: return ZTP_DEV_STATE_UPDATED;
+        case 3: return ZTP_DEV_STATE_DELETED;
         default: return null;
       }
     }
@@ -2809,7 +2800,7 @@ public final class Automation {
       if (devRoleId_ != null) {
         output.writeMessage(1, getDevRoleId());
       }
-      if (devRoleState_ != automation.Automation.ZtpDeviceState.PLANNED.getNumber()) {
+      if (devRoleState_ != automation.Automation.ZtpDeviceState.ZTP_DEV_STATE_UNDEFINED.getNumber()) {
         output.writeEnum(2, devRoleState_);
       }
       unknownFields.writeTo(output);
@@ -2825,7 +2816,7 @@ public final class Automation {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getDevRoleId());
       }
-      if (devRoleState_ != automation.Automation.ZtpDeviceState.PLANNED.getNumber()) {
+      if (devRoleState_ != automation.Automation.ZtpDeviceState.ZTP_DEV_STATE_UNDEFINED.getNumber()) {
         size += com.google.protobuf.CodedOutputStream
           .computeEnumSize(2, devRoleState_);
       }
@@ -3348,92 +3339,1145 @@ public final class Automation {
 
   }
 
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_automation_DeviceRoleId_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_automation_DeviceRoleId_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_automation_DeviceRole_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_automation_DeviceRole_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_automation_DeviceRoleList_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_automation_DeviceRoleList_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_automation_DeviceRoleState_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_automation_DeviceRoleState_fieldAccessorTable;
+  public interface DeviceDeletionResultOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:automation.DeviceDeletionResult)
+      com.google.protobuf.MessageOrBuilder {
 
-  public static com.google.protobuf.Descriptors.FileDescriptor
-      getDescriptor() {
-    return descriptor;
+    /**
+     * <code>repeated bool deleted = 1;</code>
+     * @return A list containing the deleted.
+     */
+    java.util.List<java.lang.Boolean> getDeletedList();
+    /**
+     * <code>repeated bool deleted = 1;</code>
+     * @return The count of deleted.
+     */
+    int getDeletedCount();
+    /**
+     * <code>repeated bool deleted = 1;</code>
+     * @param index The index of the element to return.
+     * @return The deleted at the given index.
+     */
+    boolean getDeleted(int index);
   }
-  private static  com.google.protobuf.Descriptors.FileDescriptor
-      descriptor;
-  static {
-    java.lang.String[] descriptorData = {
-      "\n\020automation.proto\022\nautomation\032\rcontext." +
-      "proto\"R\n\014DeviceRoleId\022 \n\tdevRoleId\030\001 \001(\013" +
-      "2\r.context.Uuid\022 \n\005devId\030\002 \001(\0132\021.context" +
-      ".DeviceId\"j\n\nDeviceRole\022+\n\tdevRoleId\030\001 \001" +
-      "(\0132\030.automation.DeviceRoleId\022/\n\013devRoleT" +
-      "ype\030\002 \001(\0162\032.automation.DeviceRoleType\"9\n" +
-      "\016DeviceRoleList\022\'\n\007devRole\030\001 \003(\0132\026.autom" +
-      "ation.DeviceRole\"p\n\017DeviceRoleState\022+\n\td" +
-      "evRoleId\030\001 \001(\0132\030.automation.DeviceRoleId" +
-      "\0220\n\014devRoleState\030\002 \001(\0162\032.automation.ZtpD" +
-      "eviceState*H\n\016DeviceRoleType\022\010\n\004NONE\020\000\022\013" +
-      "\n\007DEV_OPS\020\001\022\014\n\010DEV_CONF\020\002\022\021\n\rPIPELINE_CO" +
-      "NF\020\003*n\n\016ZtpDeviceState\022\013\n\007PLANNED\020\000\022\027\n\023P" +
-      "OTENCIAL_AVAILABLE\020\001\022\022\n\016POTENCIAL_BUSY\020\002" +
-      "\022\r\n\tINSTALLED\020\003\022\023\n\017PENDING_REMOVAL\020\0042\300\003\n" +
-      "\021AutomationService\022F\n\020ZtpGetDeviceRole\022\030" +
-      ".automation.DeviceRoleId\032\026.automation.De" +
-      "viceRole\"\000\022N\n\033ZtpGetDeviceRolesByDeviceI" +
-      "d\022\021.context.DeviceId\032\032.automation.Device" +
-      "RoleList\"\000\022?\n\006ZtpAdd\022\026.automation.Device" +
-      "Role\032\033.automation.DeviceRoleState\"\000\022B\n\tZ" +
-      "tpUpdate\022\026.automation.DeviceRole\032\033.autom" +
-      "ation.DeviceRoleState\"\000\022B\n\tZtpDelete\022\026.a" +
-      "utomation.DeviceRole\032\033.automation.Device" +
-      "RoleState\"\000\022J\n\026ZtpDeleteAllByDeviceId\022\021." +
-      "context.DeviceId\032\033.automation.DeviceRole" +
-      "State\"\000b\006proto3"
-    };
-    descriptor = com.google.protobuf.Descriptors.FileDescriptor
-      .internalBuildGeneratedFileFrom(descriptorData,
-        new com.google.protobuf.Descriptors.FileDescriptor[] {
-          context.ContextOuterClass.getDescriptor(),
-        });
-    internal_static_automation_DeviceRoleId_descriptor =
-      getDescriptor().getMessageTypes().get(0);
-    internal_static_automation_DeviceRoleId_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
-        internal_static_automation_DeviceRoleId_descriptor,
-        new java.lang.String[] { "DevRoleId", "DevId", });
-    internal_static_automation_DeviceRole_descriptor =
-      getDescriptor().getMessageTypes().get(1);
-    internal_static_automation_DeviceRole_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
-        internal_static_automation_DeviceRole_descriptor,
-        new java.lang.String[] { "DevRoleId", "DevRoleType", });
-    internal_static_automation_DeviceRoleList_descriptor =
-      getDescriptor().getMessageTypes().get(2);
-    internal_static_automation_DeviceRoleList_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
-        internal_static_automation_DeviceRoleList_descriptor,
-        new java.lang.String[] { "DevRole", });
-    internal_static_automation_DeviceRoleState_descriptor =
-      getDescriptor().getMessageTypes().get(3);
-    internal_static_automation_DeviceRoleState_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
-        internal_static_automation_DeviceRoleState_descriptor,
-        new java.lang.String[] { "DevRoleId", "DevRoleState", });
+  /**
+   * Protobuf type {@code automation.DeviceDeletionResult}
+   */
+  public static final class DeviceDeletionResult extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:automation.DeviceDeletionResult)
+      DeviceDeletionResultOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use DeviceDeletionResult.newBuilder() to construct.
+    private DeviceDeletionResult(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private DeviceDeletionResult() {
+      deleted_ = emptyBooleanList();
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new DeviceDeletionResult();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private DeviceDeletionResult(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 8: {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                deleted_ = newBooleanList();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              deleted_.addBoolean(input.readBool());
+              break;
+            }
+            case 10: {
+              int length = input.readRawVarint32();
+              int limit = input.pushLimit(length);
+              if (!((mutable_bitField0_ & 0x00000001) != 0) && input.getBytesUntilLimit() > 0) {
+                deleted_ = newBooleanList();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              while (input.getBytesUntilLimit() > 0) {
+                deleted_.addBoolean(input.readBool());
+              }
+              input.popLimit(limit);
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          deleted_.makeImmutable(); // C
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return automation.Automation.internal_static_automation_DeviceDeletionResult_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return automation.Automation.internal_static_automation_DeviceDeletionResult_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              automation.Automation.DeviceDeletionResult.class, automation.Automation.DeviceDeletionResult.Builder.class);
+    }
+
+    public static final int DELETED_FIELD_NUMBER = 1;
+    private com.google.protobuf.Internal.BooleanList deleted_;
+    /**
+     * <code>repeated bool deleted = 1;</code>
+     * @return A list containing the deleted.
+     */
+    @java.lang.Override
+    public java.util.List<java.lang.Boolean>
+        getDeletedList() {
+      return deleted_;
+    }
+    /**
+     * <code>repeated bool deleted = 1;</code>
+     * @return The count of deleted.
+     */
+    public int getDeletedCount() {
+      return deleted_.size();
+    }
+    /**
+     * <code>repeated bool deleted = 1;</code>
+     * @param index The index of the element to return.
+     * @return The deleted at the given index.
+     */
+    public boolean getDeleted(int index) {
+      return deleted_.getBoolean(index);
+    }
+    private int deletedMemoizedSerializedSize = -1;
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      getSerializedSize();
+      if (getDeletedList().size() > 0) {
+        output.writeUInt32NoTag(10);
+        output.writeUInt32NoTag(deletedMemoizedSerializedSize);
+      }
+      for (int i = 0; i < deleted_.size(); i++) {
+        output.writeBoolNoTag(deleted_.getBoolean(i));
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      {
+        int dataSize = 0;
+        dataSize = 1 * getDeletedList().size();
+        size += dataSize;
+        if (!getDeletedList().isEmpty()) {
+          size += 1;
+          size += com.google.protobuf.CodedOutputStream
+              .computeInt32SizeNoTag(dataSize);
+        }
+        deletedMemoizedSerializedSize = dataSize;
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof automation.Automation.DeviceDeletionResult)) {
+        return super.equals(obj);
+      }
+      automation.Automation.DeviceDeletionResult other = (automation.Automation.DeviceDeletionResult) obj;
+
+      if (!getDeletedList()
+          .equals(other.getDeletedList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (getDeletedCount() > 0) {
+        hash = (37 * hash) + DELETED_FIELD_NUMBER;
+        hash = (53 * hash) + getDeletedList().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static automation.Automation.DeviceDeletionResult parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static automation.Automation.DeviceDeletionResult parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static automation.Automation.DeviceDeletionResult parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static automation.Automation.DeviceDeletionResult parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static automation.Automation.DeviceDeletionResult parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static automation.Automation.DeviceDeletionResult parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static automation.Automation.DeviceDeletionResult parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static automation.Automation.DeviceDeletionResult parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static automation.Automation.DeviceDeletionResult parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static automation.Automation.DeviceDeletionResult parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static automation.Automation.DeviceDeletionResult parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static automation.Automation.DeviceDeletionResult parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(automation.Automation.DeviceDeletionResult prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code automation.DeviceDeletionResult}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:automation.DeviceDeletionResult)
+        automation.Automation.DeviceDeletionResultOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return automation.Automation.internal_static_automation_DeviceDeletionResult_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return automation.Automation.internal_static_automation_DeviceDeletionResult_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                automation.Automation.DeviceDeletionResult.class, automation.Automation.DeviceDeletionResult.Builder.class);
+      }
+
+      // Construct using automation.Automation.DeviceDeletionResult.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        deleted_ = emptyBooleanList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return automation.Automation.internal_static_automation_DeviceDeletionResult_descriptor;
+      }
+
+      @java.lang.Override
+      public automation.Automation.DeviceDeletionResult getDefaultInstanceForType() {
+        return automation.Automation.DeviceDeletionResult.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public automation.Automation.DeviceDeletionResult build() {
+        automation.Automation.DeviceDeletionResult result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public automation.Automation.DeviceDeletionResult buildPartial() {
+        automation.Automation.DeviceDeletionResult result = new automation.Automation.DeviceDeletionResult(this);
+        int from_bitField0_ = bitField0_;
+        if (((bitField0_ & 0x00000001) != 0)) {
+          deleted_.makeImmutable();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        }
+        result.deleted_ = deleted_;
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof automation.Automation.DeviceDeletionResult) {
+          return mergeFrom((automation.Automation.DeviceDeletionResult)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(automation.Automation.DeviceDeletionResult other) {
+        if (other == automation.Automation.DeviceDeletionResult.getDefaultInstance()) return this;
+        if (!other.deleted_.isEmpty()) {
+          if (deleted_.isEmpty()) {
+            deleted_ = other.deleted_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+          } else {
+            ensureDeletedIsMutable();
+            deleted_.addAll(other.deleted_);
+          }
+          onChanged();
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        automation.Automation.DeviceDeletionResult parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (automation.Automation.DeviceDeletionResult) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private com.google.protobuf.Internal.BooleanList deleted_ = emptyBooleanList();
+      private void ensureDeletedIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          deleted_ = mutableCopy(deleted_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+      /**
+       * <code>repeated bool deleted = 1;</code>
+       * @return A list containing the deleted.
+       */
+      public java.util.List<java.lang.Boolean>
+          getDeletedList() {
+        return ((bitField0_ & 0x00000001) != 0) ?
+                 java.util.Collections.unmodifiableList(deleted_) : deleted_;
+      }
+      /**
+       * <code>repeated bool deleted = 1;</code>
+       * @return The count of deleted.
+       */
+      public int getDeletedCount() {
+        return deleted_.size();
+      }
+      /**
+       * <code>repeated bool deleted = 1;</code>
+       * @param index The index of the element to return.
+       * @return The deleted at the given index.
+       */
+      public boolean getDeleted(int index) {
+        return deleted_.getBoolean(index);
+      }
+      /**
+       * <code>repeated bool deleted = 1;</code>
+       * @param index The index to set the value at.
+       * @param value The deleted to set.
+       * @return This builder for chaining.
+       */
+      public Builder setDeleted(
+          int index, boolean value) {
+        ensureDeletedIsMutable();
+        deleted_.setBoolean(index, value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated bool deleted = 1;</code>
+       * @param value The deleted to add.
+       * @return This builder for chaining.
+       */
+      public Builder addDeleted(boolean value) {
+        ensureDeletedIsMutable();
+        deleted_.addBoolean(value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated bool deleted = 1;</code>
+       * @param values The deleted to add.
+       * @return This builder for chaining.
+       */
+      public Builder addAllDeleted(
+          java.lang.Iterable<? extends java.lang.Boolean> values) {
+        ensureDeletedIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, deleted_);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated bool deleted = 1;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearDeleted() {
+        deleted_ = emptyBooleanList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        onChanged();
+        return this;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:automation.DeviceDeletionResult)
+    }
+
+    // @@protoc_insertion_point(class_scope:automation.DeviceDeletionResult)
+    private static final automation.Automation.DeviceDeletionResult DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new automation.Automation.DeviceDeletionResult();
+    }
+
+    public static automation.Automation.DeviceDeletionResult getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<DeviceDeletionResult>
+        PARSER = new com.google.protobuf.AbstractParser<DeviceDeletionResult>() {
+      @java.lang.Override
+      public DeviceDeletionResult parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new DeviceDeletionResult(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<DeviceDeletionResult> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<DeviceDeletionResult> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public automation.Automation.DeviceDeletionResult getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface EmptyOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:automation.Empty)
+      com.google.protobuf.MessageOrBuilder {
+  }
+  /**
+   * Protobuf type {@code automation.Empty}
+   */
+  public static final class Empty extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:automation.Empty)
+      EmptyOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use Empty.newBuilder() to construct.
+    private Empty(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private Empty() {
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new Empty();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private Empty(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return automation.Automation.internal_static_automation_Empty_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return automation.Automation.internal_static_automation_Empty_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              automation.Automation.Empty.class, automation.Automation.Empty.Builder.class);
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof automation.Automation.Empty)) {
+        return super.equals(obj);
+      }
+      automation.Automation.Empty other = (automation.Automation.Empty) obj;
+
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static automation.Automation.Empty parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static automation.Automation.Empty parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static automation.Automation.Empty parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static automation.Automation.Empty parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static automation.Automation.Empty parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static automation.Automation.Empty parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static automation.Automation.Empty parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static automation.Automation.Empty parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static automation.Automation.Empty parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static automation.Automation.Empty parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static automation.Automation.Empty parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static automation.Automation.Empty parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(automation.Automation.Empty prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code automation.Empty}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:automation.Empty)
+        automation.Automation.EmptyOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return automation.Automation.internal_static_automation_Empty_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return automation.Automation.internal_static_automation_Empty_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                automation.Automation.Empty.class, automation.Automation.Empty.Builder.class);
+      }
+
+      // Construct using automation.Automation.Empty.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return automation.Automation.internal_static_automation_Empty_descriptor;
+      }
+
+      @java.lang.Override
+      public automation.Automation.Empty getDefaultInstanceForType() {
+        return automation.Automation.Empty.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public automation.Automation.Empty build() {
+        automation.Automation.Empty result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public automation.Automation.Empty buildPartial() {
+        automation.Automation.Empty result = new automation.Automation.Empty(this);
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof automation.Automation.Empty) {
+          return mergeFrom((automation.Automation.Empty)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(automation.Automation.Empty other) {
+        if (other == automation.Automation.Empty.getDefaultInstance()) return this;
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        automation.Automation.Empty parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (automation.Automation.Empty) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:automation.Empty)
+    }
+
+    // @@protoc_insertion_point(class_scope:automation.Empty)
+    private static final automation.Automation.Empty DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new automation.Automation.Empty();
+    }
+
+    public static automation.Automation.Empty getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<Empty>
+        PARSER = new com.google.protobuf.AbstractParser<Empty>() {
+      @java.lang.Override
+      public Empty parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new Empty(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<Empty> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Empty> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public automation.Automation.Empty getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_automation_DeviceRoleId_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_automation_DeviceRoleId_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_automation_DeviceRole_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_automation_DeviceRole_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_automation_DeviceRoleList_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_automation_DeviceRoleList_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_automation_DeviceRoleState_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_automation_DeviceRoleState_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_automation_DeviceDeletionResult_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_automation_DeviceDeletionResult_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_automation_Empty_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_automation_Empty_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\020automation.proto\022\nautomation\032\rcontext." +
+      "proto\"R\n\014DeviceRoleId\022 \n\tdevRoleId\030\001 \001(\013" +
+      "2\r.context.Uuid\022 \n\005devId\030\002 \001(\0132\021.context" +
+      ".DeviceId\"j\n\nDeviceRole\022+\n\tdevRoleId\030\001 \001" +
+      "(\0132\030.automation.DeviceRoleId\022/\n\013devRoleT" +
+      "ype\030\002 \001(\0162\032.automation.DeviceRoleType\"9\n" +
+      "\016DeviceRoleList\022\'\n\007devRole\030\001 \003(\0132\026.autom" +
+      "ation.DeviceRole\"p\n\017DeviceRoleState\022+\n\td" +
+      "evRoleId\030\001 \001(\0132\030.automation.DeviceRoleId" +
+      "\0220\n\014devRoleState\030\002 \001(\0162\032.automation.ZtpD" +
+      "eviceState\"\'\n\024DeviceDeletionResult\022\017\n\007de" +
+      "leted\030\001 \003(\010\"\007\n\005Empty*H\n\016DeviceRoleType\022\010" +
+      "\n\004NONE\020\000\022\013\n\007DEV_OPS\020\001\022\014\n\010DEV_CONF\020\002\022\021\n\rP" +
+      "IPELINE_CONF\020\003*~\n\016ZtpDeviceState\022\033\n\027ZTP_" +
+      "DEV_STATE_UNDEFINED\020\000\022\031\n\025ZTP_DEV_STATE_C" +
+      "REATED\020\001\022\031\n\025ZTP_DEV_STATE_UPDATED\020\002\022\031\n\025Z" +
+      "TP_DEV_STATE_DELETED\020\0032\273\003\n\021AutomationSer" +
+      "vice\022F\n\020ZtpGetDeviceRole\022\030.automation.De" +
+      "viceRoleId\032\026.automation.DeviceRole\"\000\022N\n\033" +
+      "ZtpGetDeviceRolesByDeviceId\022\021.context.De" +
+      "viceId\032\032.automation.DeviceRoleList\"\000\022?\n\006" +
+      "ZtpAdd\022\026.automation.DeviceRole\032\033.automat" +
+      "ion.DeviceRoleState\"\000\022B\n\tZtpUpdate\022\026.aut" +
+      "omation.DeviceRole\032\033.automation.DeviceRo" +
+      "leState\"\000\022B\n\tZtpDelete\022\026.automation.Devi" +
+      "ceRole\032\033.automation.DeviceRoleState\"\000\022E\n" +
+      "\014ZtpDeleteAll\022\021.automation.Empty\032 .autom" +
+      "ation.DeviceDeletionResult\"\000b\006proto3"
+    };
+    descriptor = com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          context.ContextOuterClass.getDescriptor(),
+        });
+    internal_static_automation_DeviceRoleId_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_automation_DeviceRoleId_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_automation_DeviceRoleId_descriptor,
+        new java.lang.String[] { "DevRoleId", "DevId", });
+    internal_static_automation_DeviceRole_descriptor =
+      getDescriptor().getMessageTypes().get(1);
+    internal_static_automation_DeviceRole_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_automation_DeviceRole_descriptor,
+        new java.lang.String[] { "DevRoleId", "DevRoleType", });
+    internal_static_automation_DeviceRoleList_descriptor =
+      getDescriptor().getMessageTypes().get(2);
+    internal_static_automation_DeviceRoleList_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_automation_DeviceRoleList_descriptor,
+        new java.lang.String[] { "DevRole", });
+    internal_static_automation_DeviceRoleState_descriptor =
+      getDescriptor().getMessageTypes().get(3);
+    internal_static_automation_DeviceRoleState_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_automation_DeviceRoleState_descriptor,
+        new java.lang.String[] { "DevRoleId", "DevRoleState", });
+    internal_static_automation_DeviceDeletionResult_descriptor =
+      getDescriptor().getMessageTypes().get(4);
+    internal_static_automation_DeviceDeletionResult_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_automation_DeviceDeletionResult_descriptor,
+        new java.lang.String[] { "Deleted", });
+    internal_static_automation_Empty_descriptor =
+      getDescriptor().getMessageTypes().get(5);
+    internal_static_automation_Empty_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_automation_Empty_descriptor,
+        new java.lang.String[] { });
     context.ContextOuterClass.getDescriptor();
   }
 
diff --git a/src/automation/target/generated-sources/grpc/automation/AutomationService.java b/src/automation/target/generated-sources/grpc/automation/AutomationService.java
index 48120d611..9b772a499 100644
--- a/src/automation/target/generated-sources/grpc/automation/AutomationService.java
+++ b/src/automation/target/generated-sources/grpc/automation/AutomationService.java
@@ -18,7 +18,7 @@ public interface AutomationService extends MutinyService {
     
     io.smallrye.mutiny.Uni<automation.Automation.DeviceRoleState> ztpDelete(automation.Automation.DeviceRole request);
     
-    io.smallrye.mutiny.Uni<automation.Automation.DeviceRoleState> ztpDeleteAllByDeviceId(context.ContextOuterClass.DeviceId request);
+    io.smallrye.mutiny.Uni<automation.Automation.DeviceDeletionResult> ztpDeleteAll(automation.Automation.Empty request);
     
     
     
diff --git a/src/automation/target/generated-sources/grpc/automation/AutomationServiceBean.java b/src/automation/target/generated-sources/grpc/automation/AutomationServiceBean.java
index de0257c91..52b1425cf 100644
--- a/src/automation/target/generated-sources/grpc/automation/AutomationServiceBean.java
+++ b/src/automation/target/generated-sources/grpc/automation/AutomationServiceBean.java
@@ -56,9 +56,9 @@ public class AutomationServiceBean extends MutinyAutomationServiceGrpc.Automatio
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<automation.Automation.DeviceRoleState> ztpDeleteAllByDeviceId(context.ContextOuterClass.DeviceId request) {
+    public io.smallrye.mutiny.Uni<automation.Automation.DeviceDeletionResult> ztpDeleteAll(automation.Automation.Empty request) {
        try {
-         return delegate.ztpDeleteAllByDeviceId(request);
+         return delegate.ztpDeleteAll(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
diff --git a/src/automation/target/generated-sources/grpc/automation/AutomationServiceClient.java b/src/automation/target/generated-sources/grpc/automation/AutomationServiceClient.java
index 736b662c1..5dde73d5b 100644
--- a/src/automation/target/generated-sources/grpc/automation/AutomationServiceClient.java
+++ b/src/automation/target/generated-sources/grpc/automation/AutomationServiceClient.java
@@ -41,8 +41,8 @@ public class AutomationServiceClient implements AutomationService, MutinyClient<
        return stub.ztpDelete(request);
     }
     @Override
-    public io.smallrye.mutiny.Uni<automation.Automation.DeviceRoleState> ztpDeleteAllByDeviceId(context.ContextOuterClass.DeviceId request) {
-       return stub.ztpDeleteAllByDeviceId(request);
+    public io.smallrye.mutiny.Uni<automation.Automation.DeviceDeletionResult> ztpDeleteAll(automation.Automation.Empty request) {
+       return stub.ztpDeleteAll(request);
     }
 
 }
\ No newline at end of file
diff --git a/src/automation/target/generated-sources/grpc/automation/AutomationServiceGrpc.java b/src/automation/target/generated-sources/grpc/automation/AutomationServiceGrpc.java
index 7fd2b7594..9f8057966 100644
--- a/src/automation/target/generated-sources/grpc/automation/AutomationServiceGrpc.java
+++ b/src/automation/target/generated-sources/grpc/automation/AutomationServiceGrpc.java
@@ -169,35 +169,35 @@ public final class AutomationServiceGrpc {
     return getZtpDeleteMethod;
   }
 
-  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.DeviceId,
-      automation.Automation.DeviceRoleState> getZtpDeleteAllByDeviceIdMethod;
+  private static volatile io.grpc.MethodDescriptor<automation.Automation.Empty,
+      automation.Automation.DeviceDeletionResult> getZtpDeleteAllMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "ZtpDeleteAllByDeviceId",
-      requestType = context.ContextOuterClass.DeviceId.class,
-      responseType = automation.Automation.DeviceRoleState.class,
+      fullMethodName = SERVICE_NAME + '/' + "ZtpDeleteAll",
+      requestType = automation.Automation.Empty.class,
+      responseType = automation.Automation.DeviceDeletionResult.class,
       methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
-  public static io.grpc.MethodDescriptor<context.ContextOuterClass.DeviceId,
-      automation.Automation.DeviceRoleState> getZtpDeleteAllByDeviceIdMethod() {
-    io.grpc.MethodDescriptor<context.ContextOuterClass.DeviceId, automation.Automation.DeviceRoleState> getZtpDeleteAllByDeviceIdMethod;
-    if ((getZtpDeleteAllByDeviceIdMethod = AutomationServiceGrpc.getZtpDeleteAllByDeviceIdMethod) == null) {
+  public static io.grpc.MethodDescriptor<automation.Automation.Empty,
+      automation.Automation.DeviceDeletionResult> getZtpDeleteAllMethod() {
+    io.grpc.MethodDescriptor<automation.Automation.Empty, automation.Automation.DeviceDeletionResult> getZtpDeleteAllMethod;
+    if ((getZtpDeleteAllMethod = AutomationServiceGrpc.getZtpDeleteAllMethod) == null) {
       synchronized (AutomationServiceGrpc.class) {
-        if ((getZtpDeleteAllByDeviceIdMethod = AutomationServiceGrpc.getZtpDeleteAllByDeviceIdMethod) == null) {
-          AutomationServiceGrpc.getZtpDeleteAllByDeviceIdMethod = getZtpDeleteAllByDeviceIdMethod =
-              io.grpc.MethodDescriptor.<context.ContextOuterClass.DeviceId, automation.Automation.DeviceRoleState>newBuilder()
+        if ((getZtpDeleteAllMethod = AutomationServiceGrpc.getZtpDeleteAllMethod) == null) {
+          AutomationServiceGrpc.getZtpDeleteAllMethod = getZtpDeleteAllMethod =
+              io.grpc.MethodDescriptor.<automation.Automation.Empty, automation.Automation.DeviceDeletionResult>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
-              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "ZtpDeleteAllByDeviceId"))
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "ZtpDeleteAll"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  context.ContextOuterClass.DeviceId.getDefaultInstance()))
+                  automation.Automation.Empty.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  automation.Automation.DeviceRoleState.getDefaultInstance()))
-              .setSchemaDescriptor(new AutomationServiceMethodDescriptorSupplier("ZtpDeleteAllByDeviceId"))
+                  automation.Automation.DeviceDeletionResult.getDefaultInstance()))
+              .setSchemaDescriptor(new AutomationServiceMethodDescriptorSupplier("ZtpDeleteAll"))
               .build();
         }
       }
     }
-    return getZtpDeleteAllByDeviceIdMethod;
+    return getZtpDeleteAllMethod;
   }
 
   /**
@@ -285,9 +285,9 @@ public final class AutomationServiceGrpc {
 
     /**
      */
-    public void ztpDeleteAllByDeviceId(context.ContextOuterClass.DeviceId request,
-        io.grpc.stub.StreamObserver<automation.Automation.DeviceRoleState> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getZtpDeleteAllByDeviceIdMethod(), responseObserver);
+    public void ztpDeleteAll(automation.Automation.Empty request,
+        io.grpc.stub.StreamObserver<automation.Automation.DeviceDeletionResult> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getZtpDeleteAllMethod(), responseObserver);
     }
 
     @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
@@ -328,12 +328,12 @@ public final class AutomationServiceGrpc {
                 automation.Automation.DeviceRoleState>(
                   this, METHODID_ZTP_DELETE)))
           .addMethod(
-            getZtpDeleteAllByDeviceIdMethod(),
+            getZtpDeleteAllMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
               new MethodHandlers<
-                context.ContextOuterClass.DeviceId,
-                automation.Automation.DeviceRoleState>(
-                  this, METHODID_ZTP_DELETE_ALL_BY_DEVICE_ID)))
+                automation.Automation.Empty,
+                automation.Automation.DeviceDeletionResult>(
+                  this, METHODID_ZTP_DELETE_ALL)))
           .build();
     }
   }
@@ -394,10 +394,10 @@ public final class AutomationServiceGrpc {
 
     /**
      */
-    public void ztpDeleteAllByDeviceId(context.ContextOuterClass.DeviceId request,
-        io.grpc.stub.StreamObserver<automation.Automation.DeviceRoleState> responseObserver) {
+    public void ztpDeleteAll(automation.Automation.Empty request,
+        io.grpc.stub.StreamObserver<automation.Automation.DeviceDeletionResult> responseObserver) {
       io.grpc.stub.ClientCalls.asyncUnaryCall(
-          getChannel().newCall(getZtpDeleteAllByDeviceIdMethod(), getCallOptions()), request, responseObserver);
+          getChannel().newCall(getZtpDeleteAllMethod(), getCallOptions()), request, responseObserver);
     }
   }
 
@@ -452,9 +452,9 @@ public final class AutomationServiceGrpc {
 
     /**
      */
-    public automation.Automation.DeviceRoleState ztpDeleteAllByDeviceId(context.ContextOuterClass.DeviceId request) {
+    public automation.Automation.DeviceDeletionResult ztpDeleteAll(automation.Automation.Empty request) {
       return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getZtpDeleteAllByDeviceIdMethod(), getCallOptions(), request);
+          getChannel(), getZtpDeleteAllMethod(), getCallOptions(), request);
     }
   }
 
@@ -514,10 +514,10 @@ public final class AutomationServiceGrpc {
 
     /**
      */
-    public com.google.common.util.concurrent.ListenableFuture<automation.Automation.DeviceRoleState> ztpDeleteAllByDeviceId(
-        context.ContextOuterClass.DeviceId request) {
+    public com.google.common.util.concurrent.ListenableFuture<automation.Automation.DeviceDeletionResult> ztpDeleteAll(
+        automation.Automation.Empty request) {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
-          getChannel().newCall(getZtpDeleteAllByDeviceIdMethod(), getCallOptions()), request);
+          getChannel().newCall(getZtpDeleteAllMethod(), getCallOptions()), request);
     }
   }
 
@@ -526,7 +526,7 @@ public final class AutomationServiceGrpc {
   private static final int METHODID_ZTP_ADD = 2;
   private static final int METHODID_ZTP_UPDATE = 3;
   private static final int METHODID_ZTP_DELETE = 4;
-  private static final int METHODID_ZTP_DELETE_ALL_BY_DEVICE_ID = 5;
+  private static final int METHODID_ZTP_DELETE_ALL = 5;
 
   private static final class MethodHandlers<Req, Resp> implements
       io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
@@ -565,9 +565,9 @@ public final class AutomationServiceGrpc {
           serviceImpl.ztpDelete((automation.Automation.DeviceRole) request,
               (io.grpc.stub.StreamObserver<automation.Automation.DeviceRoleState>) responseObserver);
           break;
-        case METHODID_ZTP_DELETE_ALL_BY_DEVICE_ID:
-          serviceImpl.ztpDeleteAllByDeviceId((context.ContextOuterClass.DeviceId) request,
-              (io.grpc.stub.StreamObserver<automation.Automation.DeviceRoleState>) responseObserver);
+        case METHODID_ZTP_DELETE_ALL:
+          serviceImpl.ztpDeleteAll((automation.Automation.Empty) request,
+              (io.grpc.stub.StreamObserver<automation.Automation.DeviceDeletionResult>) responseObserver);
           break;
         default:
           throw new AssertionError();
@@ -635,7 +635,7 @@ public final class AutomationServiceGrpc {
               .addMethod(getZtpAddMethod())
               .addMethod(getZtpUpdateMethod())
               .addMethod(getZtpDeleteMethod())
-              .addMethod(getZtpDeleteAllByDeviceIdMethod())
+              .addMethod(getZtpDeleteAllMethod())
               .build();
         }
       }
diff --git a/src/automation/target/generated-sources/grpc/automation/MutinyAutomationServiceGrpc.java b/src/automation/target/generated-sources/grpc/automation/MutinyAutomationServiceGrpc.java
index 4b0e989a1..0783cbc96 100644
--- a/src/automation/target/generated-sources/grpc/automation/MutinyAutomationServiceGrpc.java
+++ b/src/automation/target/generated-sources/grpc/automation/MutinyAutomationServiceGrpc.java
@@ -61,8 +61,8 @@ public final class MutinyAutomationServiceGrpc implements io.quarkus.grpc.runtim
         }
 
         
-        public io.smallrye.mutiny.Uni<automation.Automation.DeviceRoleState> ztpDeleteAllByDeviceId(context.ContextOuterClass.DeviceId request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::ztpDeleteAllByDeviceId);
+        public io.smallrye.mutiny.Uni<automation.Automation.DeviceDeletionResult> ztpDeleteAll(automation.Automation.Empty request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::ztpDeleteAll);
         }
 
     }
@@ -108,7 +108,7 @@ public final class MutinyAutomationServiceGrpc implements io.quarkus.grpc.runtim
         }
 
         
-        public io.smallrye.mutiny.Uni<automation.Automation.DeviceRoleState> ztpDeleteAllByDeviceId(context.ContextOuterClass.DeviceId request) {
+        public io.smallrye.mutiny.Uni<automation.Automation.DeviceDeletionResult> ztpDeleteAll(automation.Automation.Empty request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
@@ -150,12 +150,12 @@ public final class MutinyAutomationServiceGrpc implements io.quarkus.grpc.runtim
                                             automation.Automation.DeviceRoleState>(
                                             this, METHODID_ZTP_DELETE, compression)))
                     .addMethod(
-                            automation.AutomationServiceGrpc.getZtpDeleteAllByDeviceIdMethod(),
+                            automation.AutomationServiceGrpc.getZtpDeleteAllMethod(),
                             asyncUnaryCall(
                                     new MethodHandlers<
-                                            context.ContextOuterClass.DeviceId,
-                                            automation.Automation.DeviceRoleState>(
-                                            this, METHODID_ZTP_DELETE_ALL_BY_DEVICE_ID, compression)))
+                                            automation.Automation.Empty,
+                                            automation.Automation.DeviceDeletionResult>(
+                                            this, METHODID_ZTP_DELETE_ALL, compression)))
                     .build();
         }
     }
@@ -165,7 +165,7 @@ public final class MutinyAutomationServiceGrpc implements io.quarkus.grpc.runtim
     private static final int METHODID_ZTP_ADD = 2;
     private static final int METHODID_ZTP_UPDATE = 3;
     private static final int METHODID_ZTP_DELETE = 4;
-    private static final int METHODID_ZTP_DELETE_ALL_BY_DEVICE_ID = 5;
+    private static final int METHODID_ZTP_DELETE_ALL = 5;
 
     private static final class MethodHandlers<Req, Resp> implements
             io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
@@ -216,11 +216,11 @@ public final class MutinyAutomationServiceGrpc implements io.quarkus.grpc.runtim
                             compression,
                             serviceImpl::ztpDelete);
                     break;
-                case METHODID_ZTP_DELETE_ALL_BY_DEVICE_ID:
-                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.DeviceId) request,
-                            (io.grpc.stub.StreamObserver<automation.Automation.DeviceRoleState>) responseObserver,
+                case METHODID_ZTP_DELETE_ALL:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((automation.Automation.Empty) request,
+                            (io.grpc.stub.StreamObserver<automation.Automation.DeviceDeletionResult>) responseObserver,
                             compression,
-                            serviceImpl::ztpDeleteAllByDeviceId);
+                            serviceImpl::ztpDeleteAll);
                     break;
                 default:
                     throw new java.lang.AssertionError();
diff --git a/src/automation/target/kubernetes/kubernetes.yml b/src/automation/target/kubernetes/kubernetes.yml
index 50f7e9771..c874443f6 100644
--- a/src/automation/target/kubernetes/kubernetes.yml
+++ b/src/automation/target/kubernetes/kubernetes.yml
@@ -3,8 +3,8 @@ apiVersion: v1
 kind: Service
 metadata:
   annotations:
-    app.quarkus.io/commit-id: 632af8e06563eb1a0efb8c52af80cfdc79b14f9a
-    app.quarkus.io/build-timestamp: 2021-11-03 - 14:35:52 +0000
+    app.quarkus.io/commit-id: 285c0ca58a5b847c5bceed002b5e0fc0dcb5a28a
+    app.quarkus.io/build-timestamp: 2021-11-11 - 13:46:51 +0000
   labels:
     app.kubernetes.io/name: automationservice
     app.kubernetes.io/version: 0.0.1
@@ -12,12 +12,12 @@ metadata:
   name: automationservice
 spec:
   ports:
-    - name: http
-      port: 8080
-      targetPort: 8080
     - name: grpc-server
       port: 9999
       targetPort: 9999
+    - name: http
+      port: 8080
+      targetPort: 8080
   selector:
     app.kubernetes.io/name: automationservice
     app.kubernetes.io/version: 0.0.1
@@ -27,28 +27,28 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   annotations:
-    app.quarkus.io/commit-id: 632af8e06563eb1a0efb8c52af80cfdc79b14f9a
-    app.quarkus.io/build-timestamp: 2021-11-03 - 14:35:52 +0000
+    app.quarkus.io/commit-id: 285c0ca58a5b847c5bceed002b5e0fc0dcb5a28a
+    app.quarkus.io/build-timestamp: 2021-11-11 - 13:46:51 +0000
   labels:
     app: automationservice
-    app.kubernetes.io/name: automationservice
     app.kubernetes.io/version: 0.0.1
+    app.kubernetes.io/name: automationservice
   name: automationservice
 spec:
   replicas: 1
   selector:
     matchLabels:
-      app.kubernetes.io/name: automationservice
       app.kubernetes.io/version: 0.0.1
+      app.kubernetes.io/name: automationservice
   template:
     metadata:
       annotations:
-        app.quarkus.io/commit-id: 632af8e06563eb1a0efb8c52af80cfdc79b14f9a
-        app.quarkus.io/build-timestamp: 2021-11-03 - 14:35:52 +0000
+        app.quarkus.io/commit-id: 285c0ca58a5b847c5bceed002b5e0fc0dcb5a28a
+        app.quarkus.io/build-timestamp: 2021-11-11 - 13:46:51 +0000
       labels:
         app: automationservice
-        app.kubernetes.io/name: automationservice
         app.kubernetes.io/version: 0.0.1
+        app.kubernetes.io/name: automationservice
     spec:
       containers:
         - env:
@@ -70,12 +70,12 @@ spec:
             timeoutSeconds: 10
           name: automationservice
           ports:
-            - containerPort: 8080
-              name: http
-              protocol: TCP
             - containerPort: 9999
               name: grpc-server
               protocol: TCP
+            - containerPort: 8080
+              name: http
+              protocol: TCP
           readinessProbe:
             failureThreshold: 3
             httpGet:
-- 
GitLab