From 1e070f3c23054ad36e2cb0807eb920c3afb18286 Mon Sep 17 00:00:00 2001 From: lahiruj Date: Sat, 4 Oct 2025 23:54:18 -0400 Subject: [PATCH 1/5] initial data models for experiment workloads --- .../init/07-parameter-sweep-modeling.sql | 32 ++++ .../service/db/entity/JobBatchEntity.java | 108 ++++++++++++++ .../service/db/entity/JobUnitEntity.java | 141 ++++++++++++++++++ .../service/db/repo/JobBatchRepo.java | 27 ++++ .../service/db/repo/JobUnitRepo.java | 28 ++++ .../handlers/AgentManagementHandler.java | 2 +- .../service/models/AgentLaunchRequest.java | 10 ++ .../service/models/JobBatchSpec.java | 60 ++++++++ .../service/models/JobUnitStatus.java | 23 +++ 9 files changed, 430 insertions(+), 1 deletion(-) create mode 100644 .devcontainer/database_scripts/init/07-parameter-sweep-modeling.sql create mode 100644 modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/JobBatchEntity.java create mode 100644 modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/JobUnitEntity.java create mode 100644 modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobBatchRepo.java create mode 100644 modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobUnitRepo.java create mode 100644 modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/JobBatchSpec.java create mode 100644 modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/JobUnitStatus.java diff --git a/.devcontainer/database_scripts/init/07-parameter-sweep-modeling.sql b/.devcontainer/database_scripts/init/07-parameter-sweep-modeling.sql new file mode 100644 index 0000000000..8bbe2e0372 --- /dev/null +++ b/.devcontainer/database_scripts/init/07-parameter-sweep-modeling.sql @@ -0,0 +1,32 @@ +USE `app_catalog`; + +-- Parent collection for one parameter sweep / batch +CREATE TABLE IF NOT EXISTS `JOB_BATCH` +( + `ID` VARCHAR(255) NOT NULL, + `EXPERIMENT_ID` VARCHAR(255) NOT NULL, + `CREATED_AT` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + `PAYLOAD_JSON` JSON NULL, -- original request payload + `COMMAND_TEMPLATE` TEXT NOT NULL, -- application_command (template) + PRIMARY KEY (`ID`), + KEY `IDX_BATCH_EXPERIMENT` (`EXPERIMENT_ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- Units of work (one per parameter combination) +CREATE TABLE IF NOT EXISTS `JOB_UNIT` +( + `ID` VARCHAR(255) NOT NULL, + `BATCH_ID` VARCHAR(255) NOT NULL, + `EXPERIMENT_ID` VARCHAR(255) NOT NULL, + `CREATED_AT` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + `RESOLVED_COMMAND` TEXT NOT NULL, -- fully expanded command to run + `STATUS` ENUM('PENDING','IN_PROGRESS','COMPLETED','FAILED') NOT NULL DEFAULT 'PENDING', + `AGENT_ID` VARCHAR(255) NULL, + `STARTED_AT` TIMESTAMP(6) NULL, + `COMPLETED_AT` TIMESTAMP(6) NULL, + PRIMARY KEY (`ID`), + KEY `IDX_UNIT_BATCH_STATUS_FIFO` (`BATCH_ID`, `STATUS`, `CREATED_AT`, `ID`), + KEY `IDX_UNIT_EXP_STATUS` (`EXPERIMENT_ID`, `STATUS`), + CONSTRAINT `FK_JOB_UNIT_BATCH` FOREIGN KEY (`BATCH_ID`) + REFERENCES `JOB_BATCH` (`ID`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; \ No newline at end of file diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/JobBatchEntity.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/JobBatchEntity.java new file mode 100644 index 0000000000..00c8f728f9 --- /dev/null +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/JobBatchEntity.java @@ -0,0 +1,108 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.airavata.agent.connection.service.db.entity; + +import com.fasterxml.jackson.databind.JsonNode; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.Lob; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Table; +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.type.SqlTypes; + +import java.time.Instant; +import java.util.List; + +@Entity +@Table(name = "JOB_BATCH") +public class JobBatchEntity { + + @Id + @Column(name = "ID", nullable = false) + private String id; + + @Column(name = "EXPERIMENT_ID", nullable = false) + private String experimentId; + + @Column(name = "CREATED_AT", updatable = false, insertable = false) + private Instant createdAt; + + @JdbcTypeCode(SqlTypes.JSON) + @Column(name = "PAYLOAD_JSON", columnDefinition = "json") + private JsonNode payloadJson; + + @Lob + @Column(name = "COMMAND_TEMPLATE", nullable = false) + private String commandTemplate; + + @OneToMany(mappedBy = "batch", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE) + private List units; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getExperimentId() { + return experimentId; + } + + public void setExperimentId(String experimentId) { + this.experimentId = experimentId; + } + + public Instant getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Instant createdAt) { + this.createdAt = createdAt; + } + + public JsonNode getPayloadJson() { + return payloadJson; + } + + public void setPayloadJson(JsonNode payloadJson) { + this.payloadJson = payloadJson; + } + + public String getCommandTemplate() { + return commandTemplate; + } + + public void setCommandTemplate(String commandTemplate) { + this.commandTemplate = commandTemplate; + } + + public List getUnits() { + return units; + } + + public void setUnits(List units) { + this.units = units; + } +} diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/JobUnitEntity.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/JobUnitEntity.java new file mode 100644 index 0000000000..1d379abccd --- /dev/null +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/JobUnitEntity.java @@ -0,0 +1,141 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.airavata.agent.connection.service.db.entity; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.FetchType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.Lob; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.Table; +import org.apache.airavata.agent.connection.service.models.JobUnitStatus; + +import java.time.Instant; + +@Entity +@Table(name = "JOB_UNIT") +public class JobUnitEntity { + + @Id + @Column(name = "ID", nullable = false) + private String id; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + @JoinColumn(name = "BATCH_ID", nullable = false) + private JobBatchEntity batch; + + @Column(name = "EXPERIMENT_ID", nullable = false) + private String experimentId; + + @Column(name = "CREATED_AT", updatable = false, insertable = false) + private Instant createdAt; + + @Lob + @Column(name = "RESOLVED_COMMAND", nullable = false) + private String resolvedCommand; + + @Enumerated(EnumType.STRING) + @Column(name = "STATUS", length = 16, nullable = false) + private JobUnitStatus status = JobUnitStatus.PENDING; + + @Column(name = "AGENT_ID") + private String agentId; + + @Column(name = "STARTED_AT") + private Instant startedAt; + + @Column(name = "COMPLETED_AT") + private Instant completedAt; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public JobBatchEntity getBatch() { + return batch; + } + + public void setBatch(JobBatchEntity batch) { + this.batch = batch; + } + + public String getExperimentId() { + return experimentId; + } + + public void setExperimentId(String experimentId) { + this.experimentId = experimentId; + } + + public Instant getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Instant createdAt) { + this.createdAt = createdAt; + } + + public String getResolvedCommand() { + return resolvedCommand; + } + + public void setResolvedCommand(String resolvedCommand) { + this.resolvedCommand = resolvedCommand; + } + + public JobUnitStatus getStatus() { + return status; + } + + public void setStatus(JobUnitStatus status) { + this.status = status; + } + + public String getAgentId() { + return agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + public Instant getStartedAt() { + return startedAt; + } + + public void setStartedAt(Instant startedAt) { + this.startedAt = startedAt; + } + + public Instant getCompletedAt() { + return completedAt; + } + + public void setCompletedAt(Instant completedAt) { + this.completedAt = completedAt; + } +} diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobBatchRepo.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobBatchRepo.java new file mode 100644 index 0000000000..719394f40c --- /dev/null +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobBatchRepo.java @@ -0,0 +1,27 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.airavata.agent.connection.service.db.repo; + +import org.apache.airavata.agent.connection.service.db.entity.JobBatchEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface JobBatchRepo extends JpaRepository { +} diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobUnitRepo.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobUnitRepo.java new file mode 100644 index 0000000000..02f9261352 --- /dev/null +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobUnitRepo.java @@ -0,0 +1,28 @@ + +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.airavata.agent.connection.service.db.repo; + +import org.apache.airavata.agent.connection.service.db.entity.JobUnitEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface JobUnitRepo extends JpaRepository { +} diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java index 409511c0db..5cdb5a179f 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java @@ -158,7 +158,7 @@ private String generateEnvName(List libraries, List pip) { public AgentLaunchResponse createAndLaunchExperiment(AgentLaunchRequest req) { try { - String agentId = "agent_" + UUID.randomUUID().toString(); + String agentId = "agent_" + UUID.randomUUID(); String envName = generateEnvName(req.getLibraries(), req.getPip()); LOGGER.info("Creating an Airavata Experiment for {} with agent id {}", req.getExperimentName(), agentId); ExperimentModel experiment = generateExperiment(req, agentId, envName); diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentLaunchRequest.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentLaunchRequest.java index 81b6c26631..a034d601fa 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentLaunchRequest.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentLaunchRequest.java @@ -39,6 +39,8 @@ public class AgentLaunchRequest { private int nodeCount = 1; private int memory = 2048; + private JobBatchSpec jobBatchSpec; + public String getExperimentName() { return experimentName; } @@ -138,4 +140,12 @@ public List getMounts() { public void setMounts(List mounts) { this.mounts = mounts; } + + public JobBatchSpec getJobBatchSpec() { + return jobBatchSpec; + } + + public void setJobBatchSpec(JobBatchSpec jobBatchSpec) { + this.jobBatchSpec = jobBatchSpec; + } } diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/JobBatchSpec.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/JobBatchSpec.java new file mode 100644 index 0000000000..bb2c3fbb87 --- /dev/null +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/JobBatchSpec.java @@ -0,0 +1,60 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.airavata.agent.connection.service.models; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.List; +import java.util.Map; + +public class JobBatchSpec { + + @JsonProperty("application_command") + private String applicationCommand; + + @JsonProperty("parameter_grid") + private Map> parameterGrid; + + @JsonProperty("input_files") + private List inputFiles; + + public String getApplicationCommand() { + return applicationCommand; + } + + public void setApplicationCommand(String applicationCommand) { + this.applicationCommand = applicationCommand; + } + + public Map> getParameterGrid() { + return parameterGrid; + } + + public void setParameterGrid(Map> parameterGrid) { + this.parameterGrid = parameterGrid; + } + + public List getInputFiles() { + return inputFiles; + } + + public void setInputFiles(List inputFiles) { + this.inputFiles = inputFiles; + } +} \ No newline at end of file diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/JobUnitStatus.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/JobUnitStatus.java new file mode 100644 index 0000000000..670978fe57 --- /dev/null +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/JobUnitStatus.java @@ -0,0 +1,23 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.airavata.agent.connection.service.models; + +public enum JobUnitStatus { + PENDING, IN_PROGRESS, COMPLETED, FAILED +} From dc8d9c64cd3e2d96477ac4201e91903bbd75524e Mon Sep 17 00:00:00 2001 From: lahiruj Date: Sun, 5 Oct 2025 14:14:15 -0400 Subject: [PATCH 2/5] job workload handling and persisting implementation --- .../service/config/AsyncConfig.java | 40 ++++++ .../handlers/AgentManagementHandler.java | 15 ++- .../service/handlers/JobBatchHandler.java | 72 ++++++++++ .../service/handlers/JobBatchWorker.java | 125 ++++++++++++++++++ .../service/models/AgentLaunchResponse.java | 12 +- 5 files changed, 258 insertions(+), 6 deletions(-) create mode 100644 modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/config/AsyncConfig.java create mode 100644 modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchHandler.java create mode 100644 modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchWorker.java diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/config/AsyncConfig.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/config/AsyncConfig.java new file mode 100644 index 0000000000..17e3989fde --- /dev/null +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/config/AsyncConfig.java @@ -0,0 +1,40 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.airavata.agent.connection.service.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +@EnableAsync +@Configuration +public class AsyncConfig { + + @Bean(name = "batchExecutor") + public ThreadPoolTaskExecutor batchExecutor() { + ThreadPoolTaskExecutor ex = new ThreadPoolTaskExecutor(); + ex.setThreadNamePrefix("batch-"); + ex.setCorePoolSize(4); + ex.setMaxPoolSize(8); + ex.setQueueCapacity(1000); + ex.initialize(); + return ex; + } +} diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java index 5cdb5a179f..0d1090297b 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java @@ -54,6 +54,7 @@ public class AgentManagementHandler { private static final Logger LOGGER = LoggerFactory.getLogger(AgentManagementHandler.class); private final AiravataService airavataService; private final ClusterApplicationConfig clusterApplicationConfig; + private final JobBatchHandler jobBatchHandler; @Value("${airavata.storageResourceId}") private String storageResourceId; @@ -64,9 +65,11 @@ public class AgentManagementHandler { @Value("${grpc.server.host}") private String grpcHost; - public AgentManagementHandler(AiravataService airavataService, ClusterApplicationConfig clusterApplicationConfig) { + public AgentManagementHandler(AiravataService airavataService, ClusterApplicationConfig clusterApplicationConfig, + JobBatchHandler jobBatchHandler) { this.airavataService = airavataService; this.clusterApplicationConfig = clusterApplicationConfig; + this.jobBatchHandler = jobBatchHandler; } public AgentTerminateResponse terminateExperiment(String experimentId) { @@ -167,10 +170,12 @@ public AgentLaunchResponse createAndLaunchExperiment(AgentLaunchRequest req) { .airavata() .createExperiment(UserContext.authzToken(), experiment.getGatewayId(), experiment); LOGGER.info("Launching the application, Id: {}, Name: {}", experimentId, experiment.getExperimentName()); - airavataService - .airavata() - .launchExperiment(UserContext.authzToken(), experimentId, experiment.getGatewayId()); - return new AgentLaunchResponse(agentId, experimentId, envName); + + // Handle job workload + String batchId = jobBatchHandler.handleJobWorkload(experimentId, req.getJobBatchSpec()); + + airavataService.airavata().launchExperiment(UserContext.authzToken(), experimentId, experiment.getGatewayId()); + return new AgentLaunchResponse(agentId, experimentId, envName, batchId); } catch (TException e) { LOGGER.error("Error while creating the experiment with the name: {}", req.getExperimentName(), e); throw new RuntimeException( diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchHandler.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchHandler.java new file mode 100644 index 0000000000..0c8e790b05 --- /dev/null +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchHandler.java @@ -0,0 +1,72 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.airavata.agent.connection.service.handlers; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.airavata.agent.connection.service.db.entity.JobBatchEntity; +import org.apache.airavata.agent.connection.service.db.repo.JobBatchRepo; +import org.apache.airavata.agent.connection.service.models.JobBatchSpec; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import java.util.UUID; + +@Service +public class JobBatchHandler { + + private static final Logger LOGGER = LoggerFactory.getLogger(JobBatchHandler.class); + + private final JobBatchWorker jobBatchWorker; + private final JobBatchRepo jobBatchRepo; + private final ObjectMapper objectMapper; + + public JobBatchHandler(JobBatchWorker jobBatchWorker, JobBatchRepo jobBatchRepo, ObjectMapper objectMapper) { + this.jobBatchWorker = jobBatchWorker; + this.jobBatchRepo = jobBatchRepo; + this.objectMapper = objectMapper; + } + + public String handleJobWorkload(String experimentId, JobBatchSpec spec) { + + String batchId = null; + if (spec != null) { + if (spec.getApplicationCommand() == null || spec.getApplicationCommand().isBlank()) { + LOGGER.warn("application_command is required for experiment with id: {}", experimentId); + throw new IllegalArgumentException("application_command is required for experiment with id: " + experimentId); + } + + if (spec.getParameterGrid() == null || spec.getParameterGrid().isEmpty()) { + LOGGER.warn("parameter_grid is required for experiment with id: {}", experimentId); + throw new IllegalArgumentException("parameter_grid is required for experiment with id: " + experimentId); + } + + batchId = UUID.randomUUID().toString(); + JobBatchEntity batch = new JobBatchEntity(); + batch.setId(batchId); + batch.setExperimentId(experimentId); + batch.setCommandTemplate(spec.getApplicationCommand()); + batch.setPayloadJson(objectMapper.valueToTree(spec)); + jobBatchRepo.save(batch); + + jobBatchWorker.expandAndPersistUnitsAsync(experimentId, batchId, spec.getApplicationCommand(), spec.getParameterGrid()); + } + return batchId; + } +} diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchWorker.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchWorker.java new file mode 100644 index 0000000000..ca8a97f37f --- /dev/null +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchWorker.java @@ -0,0 +1,125 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.airavata.agent.connection.service.handlers; + +import jakarta.transaction.Transactional; +import org.apache.airavata.agent.connection.service.db.entity.JobBatchEntity; +import org.apache.airavata.agent.connection.service.db.entity.JobUnitEntity; +import org.apache.airavata.agent.connection.service.db.repo.JobUnitRepo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +@Service("jobBatchWorker") +public class JobBatchWorker { + + private static final Logger LOGGER = LoggerFactory.getLogger(JobBatchWorker.class); + + private final JobUnitRepo jobUnitRepo; + + public JobBatchWorker(JobUnitRepo jobUnitRepo) { + this.jobUnitRepo = jobUnitRepo; + } + + /** + * Expands the parameter grid and persists JOB_UNIT rows in batch + */ + @Async("batchExecutor") + @Transactional(dontRollbackOn = Exception.class) + public void expandAndPersistUnitsAsync(String experimentId, String batchId, + String commandTemplate, Map> grid) { + + if (grid == null || grid.isEmpty()) { + return; + } + + List keys = new ArrayList<>(grid.keySet()); + Collections.sort(keys); + + List values = new ArrayList<>(keys.size()); + for (String k : keys) { + List vs = grid.get(k); + if (vs == null || vs.isEmpty()) { + LOGGER.warn("Parameter '{}' has empty value list; skipping batch {}", k, batchId); + return; + } + values.add(vs.toArray(new String[0])); + } + + final int chunkSize = 100; + List buffer = new ArrayList<>(chunkSize); + + int dims = values.size(); + int[] idx = new int[dims]; + boolean done = false; + + while (!done) { + String resolved = renderCommand(commandTemplate, keys, values, idx); + + JobUnitEntity jobUnit = new JobUnitEntity(); + jobUnit.setId(UUID.randomUUID().toString()); + jobUnit.setExperimentId(experimentId); + JobBatchEntity batchRef = new JobBatchEntity(); + batchRef.setId(batchId); + jobUnit.setBatch(batchRef); + jobUnit.setResolvedCommand(resolved); + buffer.add(jobUnit); + + if (buffer.size() >= chunkSize) { + jobUnitRepo.saveAll(buffer); + buffer.clear(); + } + + for (int d = dims - 1; d >= 0; d--) { + idx[d]++; + if (idx[d] < values.get(d).length) { + break; + } else { + idx[d] = 0; + if (d == 0) { + done = true; + } + } + } + } + + if (!buffer.isEmpty()) { + jobUnitRepo.saveAll(buffer); + } + + LOGGER.info("Batch {} expansion complete (experiment {}).", batchId, experimentId); + } + + + private static String renderCommand(String template, List keys, List values, int[] idx) { + String cmd = template; + for (int i = 0; i < keys.size(); i++) { + String placeholder = "{" + keys.get(i) + "}"; + cmd = cmd.replace(placeholder, values.get(i)[idx[i]]); + } + return cmd; + } +} diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentLaunchResponse.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentLaunchResponse.java index d3c6a8077d..ed5907b5da 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentLaunchResponse.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AgentLaunchResponse.java @@ -24,11 +24,13 @@ public class AgentLaunchResponse { private String experimentId; private String envName; private String processId; + private String batchId; - public AgentLaunchResponse(String agentId, String experimentId, String envName) { + public AgentLaunchResponse(String agentId, String experimentId, String envName, String batchId) { this.agentId = agentId; this.experimentId = experimentId; this.envName = envName; + this.batchId = batchId; } public String getAgentId() { @@ -62,4 +64,12 @@ public String getProcessId() { public void setProcessId(String processId) { this.processId = processId; } + + public String getBatchId() { + return batchId; + } + + public void setBatchId(String batchId) { + this.batchId = batchId; + } } From 928bb1b6e119c189f619672f32ae59aa06463f5d Mon Sep 17 00:00:00 2001 From: lahiruj Date: Sun, 5 Oct 2025 15:52:24 -0400 Subject: [PATCH 3/5] agent batch job assigning models --- .../init/07-parameter-sweep-modeling.sql | 15 +++- .../db/entity/AgentBatchAssignmentEntity.java | 76 +++++++++++++++++++ .../db/repo/AgentBatchAssignmentRepo.java | 29 +++++++ .../handlers/AgentManagementHandler.java | 2 +- .../service/handlers/JobBatchHandler.java | 14 +++- 5 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/AgentBatchAssignmentEntity.java create mode 100644 modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/AgentBatchAssignmentRepo.java diff --git a/.devcontainer/database_scripts/init/07-parameter-sweep-modeling.sql b/.devcontainer/database_scripts/init/07-parameter-sweep-modeling.sql index 8bbe2e0372..cfb8173deb 100644 --- a/.devcontainer/database_scripts/init/07-parameter-sweep-modeling.sql +++ b/.devcontainer/database_scripts/init/07-parameter-sweep-modeling.sql @@ -20,7 +20,7 @@ CREATE TABLE IF NOT EXISTS `JOB_UNIT` `EXPERIMENT_ID` VARCHAR(255) NOT NULL, `CREATED_AT` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), `RESOLVED_COMMAND` TEXT NOT NULL, -- fully expanded command to run - `STATUS` ENUM('PENDING','IN_PROGRESS','COMPLETED','FAILED') NOT NULL DEFAULT 'PENDING', + `STATUS` ENUM ('PENDING','IN_PROGRESS','COMPLETED','FAILED') NOT NULL DEFAULT 'PENDING', `AGENT_ID` VARCHAR(255) NULL, `STARTED_AT` TIMESTAMP(6) NULL, `COMPLETED_AT` TIMESTAMP(6) NULL, @@ -29,4 +29,17 @@ CREATE TABLE IF NOT EXISTS `JOB_UNIT` KEY `IDX_UNIT_EXP_STATUS` (`EXPERIMENT_ID`, `STATUS`), CONSTRAINT `FK_JOB_UNIT_BATCH` FOREIGN KEY (`BATCH_ID`) REFERENCES `JOB_BATCH` (`ID`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; + +-- Agent Batch Job assignment +CREATE TABLE IF NOT EXISTS `AGENT_BATCH_ASSIGNMENT` +( + `AGENT_ID` VARCHAR(255) NOT NULL, + `EXPERIMENT_ID` VARCHAR(255) NOT NULL, + `BATCH_ID` VARCHAR(255) NOT NULL, + `CREATED_AT` TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + PRIMARY KEY (`AGENT_ID`), + KEY `IDX_ASSIGN_BATCH` (`BATCH_ID`), + CONSTRAINT `FK_ASSIGN_BATCH` FOREIGN KEY (`BATCH_ID`) + REFERENCES `JOB_BATCH` (`ID`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; \ No newline at end of file diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/AgentBatchAssignmentEntity.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/AgentBatchAssignmentEntity.java new file mode 100644 index 0000000000..7e2a2a2611 --- /dev/null +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/AgentBatchAssignmentEntity.java @@ -0,0 +1,76 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.airavata.agent.connection.service.db.entity; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +import java.time.Instant; + +@Entity +@Table(name = "AGENT_BATCH_ASSIGNMENT") +public class AgentBatchAssignmentEntity { + + @Id + @Column(name = "AGENT_ID", nullable = false) + private String agentId; + + @Column(name = "EXPERIMENT_ID", nullable = false) + private String experimentId; + + @Column(name = "BATCH_ID", nullable = false) + private String batchId; + + @Column(name = "CREATED_AT", insertable = false, updatable = false) + private Instant createdAt; + + public String getAgentId() { + return agentId; + } + + public void setAgentId(String agentId) { + this.agentId = agentId; + } + + public String getExperimentId() { + return experimentId; + } + + public void setExperimentId(String experimentId) { + this.experimentId = experimentId; + } + + public String getBatchId() { + return batchId; + } + + public void setBatchId(String batchId) { + this.batchId = batchId; + } + + public Instant getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Instant createdAt) { + this.createdAt = createdAt; + } +} diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/AgentBatchAssignmentRepo.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/AgentBatchAssignmentRepo.java new file mode 100644 index 0000000000..5fec2fb706 --- /dev/null +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/AgentBatchAssignmentRepo.java @@ -0,0 +1,29 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.airavata.agent.connection.service.db.repo; + +import org.apache.airavata.agent.connection.service.db.entity.AgentBatchAssignmentEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface AgentBatchAssignmentRepo extends JpaRepository { + + Optional findByAgentId(String agentId); +} diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java index 0d1090297b..f6b55beb45 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentManagementHandler.java @@ -172,7 +172,7 @@ public AgentLaunchResponse createAndLaunchExperiment(AgentLaunchRequest req) { LOGGER.info("Launching the application, Id: {}, Name: {}", experimentId, experiment.getExperimentName()); // Handle job workload - String batchId = jobBatchHandler.handleJobWorkload(experimentId, req.getJobBatchSpec()); + String batchId = jobBatchHandler.handleJobWorkload(experimentId, agentId, req.getJobBatchSpec()); airavataService.airavata().launchExperiment(UserContext.authzToken(), experimentId, experiment.getGatewayId()); return new AgentLaunchResponse(agentId, experimentId, envName, batchId); diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchHandler.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchHandler.java index 0c8e790b05..157321dd82 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchHandler.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchHandler.java @@ -19,7 +19,9 @@ package org.apache.airavata.agent.connection.service.handlers; import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.airavata.agent.connection.service.db.entity.AgentBatchAssignmentEntity; import org.apache.airavata.agent.connection.service.db.entity.JobBatchEntity; +import org.apache.airavata.agent.connection.service.db.repo.AgentBatchAssignmentRepo; import org.apache.airavata.agent.connection.service.db.repo.JobBatchRepo; import org.apache.airavata.agent.connection.service.models.JobBatchSpec; import org.slf4j.Logger; @@ -35,15 +37,17 @@ public class JobBatchHandler { private final JobBatchWorker jobBatchWorker; private final JobBatchRepo jobBatchRepo; + private final AgentBatchAssignmentRepo agentJobAssignmentRepo; private final ObjectMapper objectMapper; - public JobBatchHandler(JobBatchWorker jobBatchWorker, JobBatchRepo jobBatchRepo, ObjectMapper objectMapper) { + public JobBatchHandler(JobBatchWorker jobBatchWorker, JobBatchRepo jobBatchRepo, AgentBatchAssignmentRepo agentJobAssignmentRepo, ObjectMapper objectMapper) { this.jobBatchWorker = jobBatchWorker; this.jobBatchRepo = jobBatchRepo; + this.agentJobAssignmentRepo = agentJobAssignmentRepo; this.objectMapper = objectMapper; } - public String handleJobWorkload(String experimentId, JobBatchSpec spec) { + public String handleJobWorkload(String experimentId, String agentId, JobBatchSpec spec) { String batchId = null; if (spec != null) { @@ -65,6 +69,12 @@ public String handleJobWorkload(String experimentId, JobBatchSpec spec) { batch.setPayloadJson(objectMapper.valueToTree(spec)); jobBatchRepo.save(batch); + AgentBatchAssignmentEntity assign = new AgentBatchAssignmentEntity(); + assign.setAgentId(agentId); + assign.setExperimentId(experimentId); + assign.setBatchId(batchId); + agentJobAssignmentRepo.save(assign); + jobBatchWorker.expandAndPersistUnitsAsync(experimentId, batchId, spec.getApplicationCommand(), spec.getParameterGrid()); } return batchId; From a31c44e6d288982c656eb759a684246f5de0fe55 Mon Sep 17 00:00:00 2001 From: lahiruj Date: Sun, 5 Oct 2025 21:52:27 -0400 Subject: [PATCH 4/5] agent pull batch job unit assignment implementation --- .../service/db/repo/JobUnitRepo.java | 36 +- .../handlers/AgentConnectionHandler.java | 41 + .../service/handlers/AgentWorkService.java | 63 + .../service/handlers/JobUnitAllocator.java | 66 + .../service/models/AssignResult.java | 47 + .../agent-framework/airavata-agent/agent.go | 125 +- .../protos/agent-communication.pb.go | 1423 +++++++++++------ .../protos/agent-communication_grpc.pb.go | 22 +- .../proto/agent-communication.proto | 28 + 9 files changed, 1377 insertions(+), 474 deletions(-) create mode 100644 modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentWorkService.java create mode 100644 modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobUnitAllocator.java create mode 100644 modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AssignResult.java diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobUnitRepo.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobUnitRepo.java index 02f9261352..5c8293af6a 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobUnitRepo.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobUnitRepo.java @@ -1,4 +1,3 @@ - /** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -21,8 +20,43 @@ import org.apache.airavata.agent.connection.service.db.entity.JobUnitEntity; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; @Repository public interface JobUnitRepo extends JpaRepository { + + @Query(value = """ + SELECT ID + FROM JOB_UNIT + WHERE BATCH_ID = :batchId AND STATUS = 'PENDING' + ORDER BY CREATED_AT, ID + FOR UPDATE SKIP LOCKED + LIMIT 1 + """, nativeQuery = true) + String lockNextPending(@Param("batchId") String batchId); + + @Modifying + @Query(value = """ + UPDATE JOB_UNIT SET STATUS='IN_PROGRESS', AGENT_ID=:agentId, STARTED_AT=CURRENT_TIMESTAMP(6) WHERE ID=:id + """, nativeQuery = true) + int markInProgress(@Param("id") String id, @Param("agentId") String agentId); + + @Query(value = "SELECT RESOLVED_COMMAND FROM JOB_UNIT WHERE ID=:id", nativeQuery = true) + String getResolvedCommand(@Param("id") String id); + + @Modifying + @Query(value = """ + UPDATE JOB_UNIT SET STATUS='COMPLETED', COMPLETED_AT=CURRENT_TIMESTAMP(6) WHERE ID=:id + """, nativeQuery = true) + int markCompleted(@Param("id") String id); + + @Query(value = """ + SELECT COUNT(*) + FROM JOB_UNIT + WHERE BATCH_ID = :batchId AND STATUS IN ('PENDING','IN_PROGRESS') + """, nativeQuery = true) + int countRemaining(@Param("batchId") String batchId); } diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentConnectionHandler.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentConnectionHandler.java index 56a8f54fce..693dc9345d 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentConnectionHandler.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentConnectionHandler.java @@ -57,6 +57,8 @@ public class AgentConnectionHandler extends AgentCommunicationServiceGrpc.AgentC private final Map PYTHON_EXECUTION_RESPONSE_CACHE = new ConcurrentHashMap<>(); private final Map TUNNEL_CREATION_RESPONSE_CACHE = new ConcurrentHashMap<>(); + private final AgentWorkService agentWorkService; + @Value("${airavata.tunnel.serverHost}") private String tunnelServerHost; @@ -69,6 +71,10 @@ public class AgentConnectionHandler extends AgentCommunicationServiceGrpc.AgentC @Value("${airavata.tunnel.serverToken}") private String tunnelServerToken; + public AgentConnectionHandler(AgentWorkService agentWorkService) { + this.agentWorkService = agentWorkService; + } + // response handling public AgentInfoResponse isAgentUp(String agentId) { if (AGENT_STREAM_MAPPING.containsKey(agentId) @@ -602,6 +608,33 @@ private void handlePythonExecutionResponse(PythonExecutionResponse executionResp PYTHON_EXECUTION_RESPONSE_CACHE.put(executionResponse.getExecutionId(), executionResponse); } + private void handleNextJobUnitRequest(String agentId, StreamObserver responseObserver) { + logger.info("Received next job unit request for agent id {}", agentId); + AssignResult assignResult = agentWorkService.assignNextForAgent(agentId); + + try { + if (assignResult instanceof AssignResult.Assigned assigned) { + responseObserver.onNext(ServerMessage.newBuilder().setAssignJobUnit(AssignJobUnit.newBuilder() + .setJobUnitId(assigned.jobUnitId()) + .setResolvedCommand(assigned.resolvedCommand()) + .build()).build()); + logger.info("Assigned job unit id {} to agent id {}", assigned.jobUnitId(), agentId); + + } else if (assignResult instanceof AssignResult.NoWork noWork) { + responseObserver.onNext(ServerMessage.newBuilder().setNoJobUnitAvailable(NoJobUnitAvailable.newBuilder() + .setReason(noWork.reason()) + .build()).build()); + logger.info("No job unit available for agent id {}, reason: {}", agentId, noWork.reason()); + } + } catch (Exception e) { + logger.error("Failed to send reply to agent {}", agentId, e); + } + } + + private void handleJobUnitCompletion(String jobUnitId) { + agentWorkService.markCompleted(jobUnitId); + } + // routing private Optional> getAgentStreamObserver(String agentId) { if (AGENT_STREAM_MAPPING.containsKey(agentId) @@ -659,6 +692,14 @@ public void onNext(AgentMessage request) { case ASYNCCOMMANDTERMINATERESPONSE -> { handleAsyncCommandTerminateResponse(request.getAsyncCommandTerminateResponse()); } + + case REQUESTNEXTJOBUNIT -> { + handleNextJobUnitRequest(request.getRequestNextJobUnit().getAgentId(), responseObserver); + } + + case JOBUNITCOMPLETED -> { + handleJobUnitCompletion(request.getJobUnitCompleted().getJobUnitId()); + } } } diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentWorkService.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentWorkService.java new file mode 100644 index 0000000000..0771ddaa4c --- /dev/null +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentWorkService.java @@ -0,0 +1,63 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.airavata.agent.connection.service.handlers; + +import org.apache.airavata.agent.connection.service.db.entity.AgentBatchAssignmentEntity; +import org.apache.airavata.agent.connection.service.db.repo.AgentBatchAssignmentRepo; +import org.apache.airavata.agent.connection.service.db.repo.JobUnitRepo; +import org.apache.airavata.agent.connection.service.models.AssignResult; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +public class AgentWorkService { + + private final AgentBatchAssignmentRepo assignmentRepo; + private final JobUnitAllocator allocator; + private final JobUnitRepo jobUnitRepo; + + public AgentWorkService(AgentBatchAssignmentRepo assignmentRepo, JobUnitAllocator allocator, JobUnitRepo jobUnitRepo) { + this.assignmentRepo = assignmentRepo; + this.allocator = allocator; + this.jobUnitRepo = jobUnitRepo; + } + + public AssignResult assignNextForAgent(String agentId) { + Optional absOp = assignmentRepo.findByAgentId(agentId); + if (absOp.isEmpty()) { + return AssignResult.noAssignment(); + } + + var batchId = absOp.get().getBatchId(); + Optional next = allocator.allocateNext(batchId, agentId); + if (next.isPresent()) { + JobUnitAllocator.JobUnitRow row = next.get(); + return AssignResult.assigned(row.id(), row.resolvedCommand()); + } + + int remaining = jobUnitRepo.countRemaining(batchId); + return (remaining == 0) ? AssignResult.emptyAllDone() : AssignResult.empty(); + } + + public void markCompleted(String jobUnitId) { + allocator.markCompleted(jobUnitId); + } +} + diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobUnitAllocator.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobUnitAllocator.java new file mode 100644 index 0000000000..fd8b48bb6b --- /dev/null +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobUnitAllocator.java @@ -0,0 +1,66 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.airavata.agent.connection.service.handlers; + +import jakarta.transaction.Transactional; +import org.apache.airavata.agent.connection.service.db.repo.JobUnitRepo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +public class JobUnitAllocator { + + private static final Logger LOGGER = LoggerFactory.getLogger(JobUnitAllocator.class); + + private final JobUnitRepo jobUnitRepo; + + public record JobUnitRow(String id, String resolvedCommand) { + } + + public JobUnitAllocator(JobUnitRepo jobUnitRepo) { + this.jobUnitRepo = jobUnitRepo; + } + + @Transactional + public Optional allocateNext(String batchId, String agentId) { + String id = jobUnitRepo.lockNextPending(batchId); + LOGGER.info("Job unit {} allocated to agent {}", id, agentId); + if (id == null) { + return Optional.empty(); + } + + if (jobUnitRepo.markInProgress(id, agentId) != 1) { + // If another agent grabbed the same job unit + LOGGER.warn("Job unit {} is already in progress by an agent", id); + return Optional.empty(); + } + + String cmd = jobUnitRepo.getResolvedCommand(id); + return Optional.of(new JobUnitRow(id, cmd)); + } + + @Transactional + public void markCompleted(String jobUnitId) { + int result = jobUnitRepo.markCompleted(jobUnitId); + LOGGER.info("Job unit {} marked as completed with result {}", jobUnitId, result); + } +} diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AssignResult.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AssignResult.java new file mode 100644 index 0000000000..1103a9c408 --- /dev/null +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AssignResult.java @@ -0,0 +1,47 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.airavata.agent.connection.service.models; + +public sealed interface AssignResult permits AssignResult.Assigned, AssignResult.NoWork { + + record Assigned(String jobUnitId, String resolvedCommand) implements AssignResult { + } + + record NoWork(String reason) implements AssignResult { + public static final String EMPTY = "EMPTY"; + public static final String EMPTY_ALL_DONE = "EMPTY_ALL_DONE"; + public static final String NO_ASSIGNMENT = "NO_ASSIGNMENT"; + } + + static Assigned assigned(String id, String cmd) { + return new Assigned(id, cmd); + } + + static NoWork empty() { + return new NoWork(NoWork.EMPTY); + } + + static NoWork emptyAllDone() { + return new NoWork(NoWork.EMPTY_ALL_DONE); + } + + static NoWork noAssignment() { + return new NoWork(NoWork.NO_ASSIGNMENT); + } +} \ No newline at end of file diff --git a/modules/agent-framework/airavata-agent/agent.go b/modules/agent-framework/airavata-agent/agent.go index 06cfe6d6a3..e1d270b47f 100644 --- a/modules/agent-framework/airavata-agent/agent.go +++ b/modules/agent-framework/airavata-agent/agent.go @@ -20,12 +20,14 @@ package main import ( protos "airavata-agent/protos" "context" + "errors" "flag" "io" "log" "os" "os/exec" "strings" + "time" "airavata-agent/pkg" @@ -37,6 +39,11 @@ type Stream = grpc.BidiStreamingClient[protos.AgentMessage, protos.ServerMessage var defaultLibs = []string{"python<3.12", "pip", "ipykernel", "git", "flask", "jupyter_client", "ttyd"} +const ( + noWorkBackoff = 3 * time.Second // sleep between polls when no work + maxEmptyReplies = 3 // exit after 3 consecutive empty replies +) + func main() { // Define flags with default empty values. @@ -144,9 +151,11 @@ func main() { } log.Printf("[agent.go] main() Connected to the server.\n") + requestNextJobUnit(stream, *agentId) + // start interceptor ch := make(chan struct{}) - go startInterceptor(stream, ch) + go startInterceptor(stream, ch, *agentId, *environ) <-ch @@ -156,7 +165,9 @@ func main() { } -func startInterceptor(stream Stream, grpcStreamChannel chan struct{}) { +func startInterceptor(stream Stream, grpcStreamChannel chan struct{}, agentId string, envName string) { + consecutiveEmpty := 0 + pollingJobEnabled := true for { in, err := stream.Recv() @@ -173,34 +184,34 @@ func startInterceptor(stream Stream, grpcStreamChannel chan struct{}) { case *protos.ServerMessage_EnvSetupRequest: log.Printf("[agent.go] Recived a env setup request\n") executionId := x.EnvSetupRequest.ExecutionId - envName := x.EnvSetupRequest.EnvName + envNameReq := x.EnvSetupRequest.EnvName envLibs := x.EnvSetupRequest.Libraries envPip := x.EnvSetupRequest.Pip - go pkg.CreateEnv(stream, executionId, envName, append(envLibs, defaultLibs...), envPip) + go pkg.CreateEnv(stream, executionId, envNameReq, append(envLibs, defaultLibs...), envPip) case *protos.ServerMessage_PythonExecutionRequest: log.Printf("[agent.go] Recived a python execution request\n") executionId := x.PythonExecutionRequest.ExecutionId - envName := x.PythonExecutionRequest.EnvName + envNameReq := x.PythonExecutionRequest.EnvName workingDir := x.PythonExecutionRequest.WorkingDir code := x.PythonExecutionRequest.Code - go pkg.ExecutePython(stream, executionId, envName, workingDir, code) + go pkg.ExecutePython(stream, executionId, envNameReq, workingDir, code) case *protos.ServerMessage_CommandExecutionRequest: log.Printf("[agent.go] Recived a shell execution request\n") executionId := x.CommandExecutionRequest.ExecutionId - envName := x.CommandExecutionRequest.EnvName + envNameReq := x.CommandExecutionRequest.EnvName workingDir := x.CommandExecutionRequest.WorkingDir execArgs := x.CommandExecutionRequest.Arguments - go pkg.ExecuteShell(stream, executionId, envName, workingDir, execArgs) + go pkg.ExecuteShell(stream, executionId, envNameReq, workingDir, execArgs) case *protos.ServerMessage_AsyncCommandExecutionRequest: log.Printf("[agent.go] Recived a async shell execution request\n") executionId := x.AsyncCommandExecutionRequest.ExecutionId - envName := x.AsyncCommandExecutionRequest.EnvName + envNameReq := x.AsyncCommandExecutionRequest.EnvName workingDir := x.AsyncCommandExecutionRequest.WorkingDir execArgs := x.AsyncCommandExecutionRequest.Arguments - go pkg.ExecuteShellAsync(stream, executionId, envName, workingDir, execArgs) + go pkg.ExecuteShellAsync(stream, executionId, envNameReq, workingDir, execArgs) case *protos.ServerMessage_AsyncCommandListRequest: log.Printf("[agent.go] Recived async shell list request\n") @@ -216,15 +227,15 @@ func startInterceptor(stream Stream, grpcStreamChannel chan struct{}) { case *protos.ServerMessage_JupyterExecutionRequest: log.Printf("[agent.go] Recived a jupyter execution request\n") executionId := x.JupyterExecutionRequest.ExecutionId - envName := x.JupyterExecutionRequest.EnvName + envNameReq := x.JupyterExecutionRequest.EnvName code := x.JupyterExecutionRequest.Code - go pkg.ExecuteJupyter(stream, executionId, envName, code) + go pkg.ExecuteJupyter(stream, executionId, envNameReq, code) case *protos.ServerMessage_KernelRestartRequest: log.Printf("[agent.go] Recived a kernel restart request\n") executionId := x.KernelRestartRequest.ExecutionId - envName := x.KernelRestartRequest.EnvName - go pkg.RestartKernel(stream, executionId, envName) + envNameReq := x.KernelRestartRequest.EnvName + go pkg.RestartKernel(stream, executionId, envNameReq) case *protos.ServerMessage_TunnelCreationRequest: log.Printf("[agent.go] Received a tunnel creation request\n") @@ -248,7 +259,93 @@ func startInterceptor(stream Stream, grpcStreamChannel chan struct{}) { } else { log.Printf("[agent.go] Closed tunnel: %s\n", tunnelId) } + + case *protos.ServerMessage_AssignJobUnit: + if !pollingJobEnabled { + // Shouldn't happen, but ignore if an agent is in interactive mode + break + } + + consecutiveEmpty = 0 // reset on actual work + ju := x.AssignJobUnit + log.Printf("[agent.go] Assigned job unit: %s\n", ju.JobUnitId) + + exitCode := runResolvedCommand(envName, ju.ResolvedCommand) + + _ = stream.Send(&protos.AgentMessage{ + Message: &protos.AgentMessage_JobUnitCompleted{ + JobUnitCompleted: &protos.JobUnitCompleted{ + JobUnitId: ju.JobUnitId, + ExitCode: int32(exitCode), + }, + }, + }) + requestNextJobUnit(stream, agentId) + + case *protos.ServerMessage_NoJobUnitAvailable: + reason := x.NoJobUnitAvailable.Reason + + // If the server says no batch jobs have assigned for the agent + if reason == "NO_ASSIGNMENT" { + if pollingJobEnabled { + log.Printf("[agent.go] No batch assignment for this agent; stopping job unit polling and staying in interactive mode.\n") + } + pollingJobEnabled = false + break + } + + // If polling is disabled, ignore no work messages + if !pollingJobEnabled { + break + } + + switch reason { + case "EMPTY", "EMPTY_ALL_DONE": + consecutiveEmpty++ + log.Printf("[agent.go] No job unit available (%d/%d): %s\n", consecutiveEmpty, maxEmptyReplies, reason) + + if consecutiveEmpty >= maxEmptyReplies { + log.Printf("[agent.go] No work after %d polls — shutting down agent (sweep complete).\n", maxEmptyReplies) + close(grpcStreamChannel) + return + } + + time.Sleep(noWorkBackoff) + requestNextJobUnit(stream, agentId) + + default: + // Unknown condition, retry without counting + time.Sleep(noWorkBackoff) + requestNextJobUnit(stream, agentId) + } } } } + +func requestNextJobUnit(stream Stream, agentId string) { + _ = stream.Send(&protos.AgentMessage{ + Message: &protos.AgentMessage_RequestNextJobUnit{ + RequestNextJobUnit: &protos.RequestNextJobUnit{ + AgentId: agentId, + }, + }, + }) +} + +func runResolvedCommand(envName string, resolved string) int { + log.Printf("[agent.go] Running job unit command: %s\n", resolved) + cmd := exec.Command("micromamba", "run", "-n", envName, "bash", "-lc", resolved) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + var ee *exec.ExitError + if errors.As(err, &ee) { + log.Printf("[agent.go] Command exited with code %d\n", ee.ExitCode()) + return ee.ExitCode() + } + log.Printf("[agent.go] Command failed to start/run: %v\n", err) + return 1 + } + return 0 +} diff --git a/modules/agent-framework/airavata-agent/protos/agent-communication.pb.go b/modules/agent-framework/airavata-agent/protos/agent-communication.pb.go index 4527355eac..85a4280797 100644 --- a/modules/agent-framework/airavata-agent/protos/agent-communication.pb.go +++ b/modules/agent-framework/airavata-agent/protos/agent-communication.pb.go @@ -1,25 +1,27 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.6 -// protoc v4.25.3 -// source: agent-communication.proto - +// // Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file +// or more contributor license agreements. See the NOTICE file // distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file +// regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at +// with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the +// KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.35.1 +// protoc v5.29.3 +// source: agent-communication.proto package protos @@ -28,7 +30,6 @@ import ( protoimpl "google.golang.org/protobuf/runtime/protoimpl" reflect "reflect" sync "sync" - unsafe "unsafe" ) const ( @@ -40,10 +41,11 @@ const ( // agent pinging the server type AgentPing struct { - state protoimpl.MessageState `protogen:"open.v1"` - AgentId string `protobuf:"bytes,1,opt,name=agentId,proto3" json:"agentId,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AgentId string `protobuf:"bytes,1,opt,name=agentId,proto3" json:"agentId,omitempty"` } func (x *AgentPing) Reset() { @@ -85,10 +87,11 @@ func (x *AgentPing) GetAgentId() string { // server requesting the agent to shutdown type ShutdownRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - AgentId string `protobuf:"bytes,1,opt,name=agentId,proto3" json:"agentId,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AgentId string `protobuf:"bytes,1,opt,name=agentId,proto3" json:"agentId,omitempty"` } func (x *ShutdownRequest) Reset() { @@ -130,14 +133,15 @@ func (x *ShutdownRequest) GetAgentId() string { // server requesting the agent to create a new agent subprocess type CreateAgentRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - AgentId string `protobuf:"bytes,2,opt,name=agentId,proto3" json:"agentId,omitempty"` - ContainerId string `protobuf:"bytes,3,opt,name=containerId,proto3" json:"containerId,omitempty"` - WorkingDir string `protobuf:"bytes,4,opt,name=workingDir,proto3" json:"workingDir,omitempty"` - Mounts []string `protobuf:"bytes,5,rep,name=mounts,proto3" json:"mounts,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + AgentId string `protobuf:"bytes,2,opt,name=agentId,proto3" json:"agentId,omitempty"` + ContainerId string `protobuf:"bytes,3,opt,name=containerId,proto3" json:"containerId,omitempty"` + WorkingDir string `protobuf:"bytes,4,opt,name=workingDir,proto3" json:"workingDir,omitempty"` + Mounts []string `protobuf:"bytes,5,rep,name=mounts,proto3" json:"mounts,omitempty"` } func (x *CreateAgentRequest) Reset() { @@ -206,12 +210,13 @@ func (x *CreateAgentRequest) GetMounts() []string { } type CreateAgentResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - AgentId string `protobuf:"bytes,2,opt,name=agentId,proto3" json:"agentId,omitempty"` - Status string `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + AgentId string `protobuf:"bytes,2,opt,name=agentId,proto3" json:"agentId,omitempty"` + Status string `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"` } func (x *CreateAgentResponse) Reset() { @@ -267,11 +272,12 @@ func (x *CreateAgentResponse) GetStatus() string { // server requesting the agent to terminate an agent subprocess type TerminateAgentRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - AgentId string `protobuf:"bytes,2,opt,name=agentId,proto3" json:"agentId,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + AgentId string `protobuf:"bytes,2,opt,name=agentId,proto3" json:"agentId,omitempty"` } func (x *TerminateAgentRequest) Reset() { @@ -319,12 +325,13 @@ func (x *TerminateAgentRequest) GetAgentId() string { } type TerminateAgentResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - AgentId string `protobuf:"bytes,2,opt,name=agentId,proto3" json:"agentId,omitempty"` - Status string `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + AgentId string `protobuf:"bytes,2,opt,name=agentId,proto3" json:"agentId,omitempty"` + Status string `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"` } func (x *TerminateAgentResponse) Reset() { @@ -380,13 +387,14 @@ func (x *TerminateAgentResponse) GetStatus() string { // server requesting the agent to setup an environment type EnvSetupRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - EnvName string `protobuf:"bytes,2,opt,name=envName,proto3" json:"envName,omitempty"` - Libraries []string `protobuf:"bytes,3,rep,name=libraries,proto3" json:"libraries,omitempty"` - Pip []string `protobuf:"bytes,4,rep,name=pip,proto3" json:"pip,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + EnvName string `protobuf:"bytes,2,opt,name=envName,proto3" json:"envName,omitempty"` + Libraries []string `protobuf:"bytes,3,rep,name=libraries,proto3" json:"libraries,omitempty"` + Pip []string `protobuf:"bytes,4,rep,name=pip,proto3" json:"pip,omitempty"` } func (x *EnvSetupRequest) Reset() { @@ -448,11 +456,12 @@ func (x *EnvSetupRequest) GetPip() []string { } type EnvSetupResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` } func (x *EnvSetupResponse) Reset() { @@ -501,13 +510,14 @@ func (x *EnvSetupResponse) GetStatus() string { // server requesting the agent to execute a shell command in the environment type CommandExecutionRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - EnvName string `protobuf:"bytes,2,opt,name=envName,proto3" json:"envName,omitempty"` - WorkingDir string `protobuf:"bytes,3,opt,name=workingDir,proto3" json:"workingDir,omitempty"` - Arguments []string `protobuf:"bytes,4,rep,name=arguments,proto3" json:"arguments,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + EnvName string `protobuf:"bytes,2,opt,name=envName,proto3" json:"envName,omitempty"` + WorkingDir string `protobuf:"bytes,3,opt,name=workingDir,proto3" json:"workingDir,omitempty"` + Arguments []string `protobuf:"bytes,4,rep,name=arguments,proto3" json:"arguments,omitempty"` } func (x *CommandExecutionRequest) Reset() { @@ -569,11 +579,12 @@ func (x *CommandExecutionRequest) GetArguments() []string { } type CommandExecutionResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - ResponseString string `protobuf:"bytes,2,opt,name=responseString,proto3" json:"responseString,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + ResponseString string `protobuf:"bytes,2,opt,name=responseString,proto3" json:"responseString,omitempty"` } func (x *CommandExecutionResponse) Reset() { @@ -621,13 +632,14 @@ func (x *CommandExecutionResponse) GetResponseString() string { } type AsyncCommandExecutionRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - EnvName string `protobuf:"bytes,2,opt,name=envName,proto3" json:"envName,omitempty"` - WorkingDir string `protobuf:"bytes,3,opt,name=workingDir,proto3" json:"workingDir,omitempty"` - Arguments []string `protobuf:"bytes,4,rep,name=arguments,proto3" json:"arguments,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + EnvName string `protobuf:"bytes,2,opt,name=envName,proto3" json:"envName,omitempty"` + WorkingDir string `protobuf:"bytes,3,opt,name=workingDir,proto3" json:"workingDir,omitempty"` + Arguments []string `protobuf:"bytes,4,rep,name=arguments,proto3" json:"arguments,omitempty"` } func (x *AsyncCommandExecutionRequest) Reset() { @@ -689,12 +701,13 @@ func (x *AsyncCommandExecutionRequest) GetArguments() []string { } type AsyncCommandExecutionResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - ProcessId int32 `protobuf:"varint,2,opt,name=processId,proto3" json:"processId,omitempty"` - ErrorMessage string `protobuf:"bytes,3,opt,name=errorMessage,proto3" json:"errorMessage,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + ProcessId int32 `protobuf:"varint,2,opt,name=processId,proto3" json:"processId,omitempty"` + ErrorMessage string `protobuf:"bytes,3,opt,name=errorMessage,proto3" json:"errorMessage,omitempty"` } func (x *AsyncCommandExecutionResponse) Reset() { @@ -749,10 +762,11 @@ func (x *AsyncCommandExecutionResponse) GetErrorMessage() string { } type AsyncCommandListRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` } func (x *AsyncCommandListRequest) Reset() { @@ -793,11 +807,12 @@ func (x *AsyncCommandListRequest) GetExecutionId() string { } type AsyncCommand struct { - state protoimpl.MessageState `protogen:"open.v1"` - ProcessId int32 `protobuf:"varint,1,opt,name=processId,proto3" json:"processId,omitempty"` - Arguments []string `protobuf:"bytes,4,rep,name=arguments,proto3" json:"arguments,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ProcessId int32 `protobuf:"varint,1,opt,name=processId,proto3" json:"processId,omitempty"` + Arguments []string `protobuf:"bytes,4,rep,name=arguments,proto3" json:"arguments,omitempty"` } func (x *AsyncCommand) Reset() { @@ -845,11 +860,12 @@ func (x *AsyncCommand) GetArguments() []string { } type AsyncCommandListResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - Commands []*AsyncCommand `protobuf:"bytes,2,rep,name=commands,proto3" json:"commands,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + Commands []*AsyncCommand `protobuf:"bytes,2,rep,name=commands,proto3" json:"commands,omitempty"` } func (x *AsyncCommandListResponse) Reset() { @@ -897,11 +913,12 @@ func (x *AsyncCommandListResponse) GetCommands() []*AsyncCommand { } type AsyncCommandTerminateRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - ProcessId int32 `protobuf:"varint,2,opt,name=processId,proto3" json:"processId,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + ProcessId int32 `protobuf:"varint,2,opt,name=processId,proto3" json:"processId,omitempty"` } func (x *AsyncCommandTerminateRequest) Reset() { @@ -949,11 +966,12 @@ func (x *AsyncCommandTerminateRequest) GetProcessId() int32 { } type AsyncCommandTerminateResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` } func (x *AsyncCommandTerminateResponse) Reset() { @@ -1002,13 +1020,14 @@ func (x *AsyncCommandTerminateResponse) GetStatus() string { // server requesting the agent to execute a python script in the environment type PythonExecutionRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - EnvName string `protobuf:"bytes,2,opt,name=envName,proto3" json:"envName,omitempty"` - WorkingDir string `protobuf:"bytes,3,opt,name=workingDir,proto3" json:"workingDir,omitempty"` - Code string `protobuf:"bytes,4,opt,name=code,proto3" json:"code,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + EnvName string `protobuf:"bytes,2,opt,name=envName,proto3" json:"envName,omitempty"` + WorkingDir string `protobuf:"bytes,3,opt,name=workingDir,proto3" json:"workingDir,omitempty"` + Code string `protobuf:"bytes,4,opt,name=code,proto3" json:"code,omitempty"` } func (x *PythonExecutionRequest) Reset() { @@ -1070,11 +1089,12 @@ func (x *PythonExecutionRequest) GetCode() string { } type PythonExecutionResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - ResponseString string `protobuf:"bytes,2,opt,name=responseString,proto3" json:"responseString,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + ResponseString string `protobuf:"bytes,2,opt,name=responseString,proto3" json:"responseString,omitempty"` } func (x *PythonExecutionResponse) Reset() { @@ -1123,12 +1143,13 @@ func (x *PythonExecutionResponse) GetResponseString() string { // server requesting the agent to execute a jupyter notebook cell in the environment type JupyterExecutionRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - EnvName string `protobuf:"bytes,2,opt,name=envName,proto3" json:"envName,omitempty"` - Code string `protobuf:"bytes,3,opt,name=code,proto3" json:"code,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + EnvName string `protobuf:"bytes,2,opt,name=envName,proto3" json:"envName,omitempty"` + Code string `protobuf:"bytes,3,opt,name=code,proto3" json:"code,omitempty"` } func (x *JupyterExecutionRequest) Reset() { @@ -1183,11 +1204,12 @@ func (x *JupyterExecutionRequest) GetCode() string { } type JupyterExecutionResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - ResponseString string `protobuf:"bytes,2,opt,name=responseString,proto3" json:"responseString,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + ResponseString string `protobuf:"bytes,2,opt,name=responseString,proto3" json:"responseString,omitempty"` } func (x *JupyterExecutionResponse) Reset() { @@ -1236,11 +1258,12 @@ func (x *JupyterExecutionResponse) GetResponseString() string { // server requesting the agent to restart a jupyter kernel type KernelRestartRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - EnvName string `protobuf:"bytes,2,opt,name=envName,proto3" json:"envName,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + EnvName string `protobuf:"bytes,2,opt,name=envName,proto3" json:"envName,omitempty"` } func (x *KernelRestartRequest) Reset() { @@ -1288,11 +1311,12 @@ func (x *KernelRestartRequest) GetEnvName() string { } type KernelRestartResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` } func (x *KernelRestartResponse) Reset() { @@ -1341,16 +1365,17 @@ func (x *KernelRestartResponse) GetStatus() string { // server requesting the agent to create a ssh tunnel type TunnelCreationRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - LocalPort int32 `protobuf:"varint,2,opt,name=localPort,proto3" json:"localPort,omitempty"` - LocalBindHost string `protobuf:"bytes,3,opt,name=localBindHost,proto3" json:"localBindHost,omitempty"` - TunnelServerHost string `protobuf:"bytes,4,opt,name=tunnelServerHost,proto3" json:"tunnelServerHost,omitempty"` - TunnelServerPort int32 `protobuf:"varint,5,opt,name=tunnelServerPort,proto3" json:"tunnelServerPort,omitempty"` - TunnelServerApiUrl string `protobuf:"bytes,6,opt,name=tunnelServerApiUrl,proto3" json:"tunnelServerApiUrl,omitempty"` - TunnelServerToken string `protobuf:"bytes,7,opt,name=tunnelServerToken,proto3" json:"tunnelServerToken,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + LocalPort int32 `protobuf:"varint,2,opt,name=localPort,proto3" json:"localPort,omitempty"` + LocalBindHost string `protobuf:"bytes,3,opt,name=localBindHost,proto3" json:"localBindHost,omitempty"` + TunnelServerHost string `protobuf:"bytes,4,opt,name=tunnelServerHost,proto3" json:"tunnelServerHost,omitempty"` + TunnelServerPort int32 `protobuf:"varint,5,opt,name=tunnelServerPort,proto3" json:"tunnelServerPort,omitempty"` + TunnelServerApiUrl string `protobuf:"bytes,6,opt,name=tunnelServerApiUrl,proto3" json:"tunnelServerApiUrl,omitempty"` + TunnelServerToken string `protobuf:"bytes,7,opt,name=tunnelServerToken,proto3" json:"tunnelServerToken,omitempty"` } func (x *TunnelCreationRequest) Reset() { @@ -1433,14 +1458,15 @@ func (x *TunnelCreationRequest) GetTunnelServerToken() string { } type TunnelCreationResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` - TunnelHost string `protobuf:"bytes,3,opt,name=tunnelHost,proto3" json:"tunnelHost,omitempty"` - TunnelPort int32 `protobuf:"varint,4,opt,name=tunnelPort,proto3" json:"tunnelPort,omitempty"` - TunnelId string `protobuf:"bytes,5,opt,name=tunnelId,proto3" json:"tunnelId,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` + TunnelHost string `protobuf:"bytes,3,opt,name=tunnelHost,proto3" json:"tunnelHost,omitempty"` + TunnelPort int32 `protobuf:"varint,4,opt,name=tunnelPort,proto3" json:"tunnelPort,omitempty"` + TunnelId string `protobuf:"bytes,5,opt,name=tunnelId,proto3" json:"tunnelId,omitempty"` } func (x *TunnelCreationResponse) Reset() { @@ -1510,11 +1536,12 @@ func (x *TunnelCreationResponse) GetTunnelId() string { // server requesting the agent to terminate a ssh tunnel type TunnelTerminationRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - TunnelId string `protobuf:"bytes,2,opt,name=tunnelId,proto3" json:"tunnelId,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + TunnelId string `protobuf:"bytes,2,opt,name=tunnelId,proto3" json:"tunnelId,omitempty"` } func (x *TunnelTerminationRequest) Reset() { @@ -1562,11 +1589,12 @@ func (x *TunnelTerminationRequest) GetTunnelId() string { } type TunnelTerminationResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` - Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` - unknownFields protoimpl.UnknownFields + state protoimpl.MessageState sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ExecutionId string `protobuf:"bytes,1,opt,name=executionId,proto3" json:"executionId,omitempty"` + Status string `protobuf:"bytes,2,opt,name=status,proto3" json:"status,omitempty"` } func (x *TunnelTerminationResponse) Reset() { @@ -1613,9 +1641,212 @@ func (x *TunnelTerminationResponse) GetStatus() string { return "" } +// Agent requesting the next job unit from the Job Workload +type RequestNextJobUnit struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + AgentId string `protobuf:"bytes,1,opt,name=agent_id,json=agentId,proto3" json:"agent_id,omitempty"` +} + +func (x *RequestNextJobUnit) Reset() { + *x = RequestNextJobUnit{} + mi := &file_agent_communication_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *RequestNextJobUnit) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RequestNextJobUnit) ProtoMessage() {} + +func (x *RequestNextJobUnit) ProtoReflect() protoreflect.Message { + mi := &file_agent_communication_proto_msgTypes[27] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RequestNextJobUnit.ProtoReflect.Descriptor instead. +func (*RequestNextJobUnit) Descriptor() ([]byte, []int) { + return file_agent_communication_proto_rawDescGZIP(), []int{27} +} + +func (x *RequestNextJobUnit) GetAgentId() string { + if x != nil { + return x.AgentId + } + return "" +} + +// Agent letting know the job unit is completed +type JobUnitCompleted struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + JobUnitId string `protobuf:"bytes,1,opt,name=job_unit_id,json=jobUnitId,proto3" json:"job_unit_id,omitempty"` + ExitCode int32 `protobuf:"varint,2,opt,name=exit_code,json=exitCode,proto3" json:"exit_code,omitempty"` +} + +func (x *JobUnitCompleted) Reset() { + *x = JobUnitCompleted{} + mi := &file_agent_communication_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JobUnitCompleted) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JobUnitCompleted) ProtoMessage() {} + +func (x *JobUnitCompleted) ProtoReflect() protoreflect.Message { + mi := &file_agent_communication_proto_msgTypes[28] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JobUnitCompleted.ProtoReflect.Descriptor instead. +func (*JobUnitCompleted) Descriptor() ([]byte, []int) { + return file_agent_communication_proto_rawDescGZIP(), []int{28} +} + +func (x *JobUnitCompleted) GetJobUnitId() string { + if x != nil { + return x.JobUnitId + } + return "" +} + +func (x *JobUnitCompleted) GetExitCode() int32 { + if x != nil { + return x.ExitCode + } + return 0 +} + +// Server assigning the job unit with the resolved command +type AssignJobUnit struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + JobUnitId string `protobuf:"bytes,1,opt,name=job_unit_id,json=jobUnitId,proto3" json:"job_unit_id,omitempty"` + ResolvedCommand string `protobuf:"bytes,2,opt,name=resolved_command,json=resolvedCommand,proto3" json:"resolved_command,omitempty"` +} + +func (x *AssignJobUnit) Reset() { + *x = AssignJobUnit{} + mi := &file_agent_communication_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AssignJobUnit) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AssignJobUnit) ProtoMessage() {} + +func (x *AssignJobUnit) ProtoReflect() protoreflect.Message { + mi := &file_agent_communication_proto_msgTypes[29] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AssignJobUnit.ProtoReflect.Descriptor instead. +func (*AssignJobUnit) Descriptor() ([]byte, []int) { + return file_agent_communication_proto_rawDescGZIP(), []int{29} +} + +func (x *AssignJobUnit) GetJobUnitId() string { + if x != nil { + return x.JobUnitId + } + return "" +} + +func (x *AssignJobUnit) GetResolvedCommand() string { + if x != nil { + return x.ResolvedCommand + } + return "" +} + +// Server indicating the agent that there are no job units to be consumed +type NoJobUnitAvailable struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Reason string `protobuf:"bytes,1,opt,name=reason,proto3" json:"reason,omitempty"` // "EMPTY" | "PREPARING" +} + +func (x *NoJobUnitAvailable) Reset() { + *x = NoJobUnitAvailable{} + mi := &file_agent_communication_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *NoJobUnitAvailable) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NoJobUnitAvailable) ProtoMessage() {} + +func (x *NoJobUnitAvailable) ProtoReflect() protoreflect.Message { + mi := &file_agent_communication_proto_msgTypes[30] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NoJobUnitAvailable.ProtoReflect.Descriptor instead. +func (*NoJobUnitAvailable) Descriptor() ([]byte, []int) { + return file_agent_communication_proto_rawDescGZIP(), []int{30} +} + +func (x *NoJobUnitAvailable) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + type AgentMessage struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to Message: + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Message: // // *AgentMessage_AgentPing // *AgentMessage_CreateAgentResponse @@ -1630,14 +1861,14 @@ type AgentMessage struct { // *AgentMessage_AsyncCommandExecutionResponse // *AgentMessage_AsyncCommandListResponse // *AgentMessage_AsyncCommandTerminateResponse - Message isAgentMessage_Message `protobuf_oneof:"message"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // *AgentMessage_RequestNextJobUnit + // *AgentMessage_JobUnitCompleted + Message isAgentMessage_Message `protobuf_oneof:"message"` } func (x *AgentMessage) Reset() { *x = AgentMessage{} - mi := &file_agent_communication_proto_msgTypes[27] + mi := &file_agent_communication_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1649,7 +1880,7 @@ func (x *AgentMessage) String() string { func (*AgentMessage) ProtoMessage() {} func (x *AgentMessage) ProtoReflect() protoreflect.Message { - mi := &file_agent_communication_proto_msgTypes[27] + mi := &file_agent_communication_proto_msgTypes[31] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1662,129 +1893,117 @@ func (x *AgentMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use AgentMessage.ProtoReflect.Descriptor instead. func (*AgentMessage) Descriptor() ([]byte, []int) { - return file_agent_communication_proto_rawDescGZIP(), []int{27} + return file_agent_communication_proto_rawDescGZIP(), []int{31} } -func (x *AgentMessage) GetMessage() isAgentMessage_Message { - if x != nil { - return x.Message +func (m *AgentMessage) GetMessage() isAgentMessage_Message { + if m != nil { + return m.Message } return nil } func (x *AgentMessage) GetAgentPing() *AgentPing { - if x != nil { - if x, ok := x.Message.(*AgentMessage_AgentPing); ok { - return x.AgentPing - } + if x, ok := x.GetMessage().(*AgentMessage_AgentPing); ok { + return x.AgentPing } return nil } func (x *AgentMessage) GetCreateAgentResponse() *CreateAgentResponse { - if x != nil { - if x, ok := x.Message.(*AgentMessage_CreateAgentResponse); ok { - return x.CreateAgentResponse - } + if x, ok := x.GetMessage().(*AgentMessage_CreateAgentResponse); ok { + return x.CreateAgentResponse } return nil } func (x *AgentMessage) GetTerminateAgentResponse() *TerminateAgentResponse { - if x != nil { - if x, ok := x.Message.(*AgentMessage_TerminateAgentResponse); ok { - return x.TerminateAgentResponse - } + if x, ok := x.GetMessage().(*AgentMessage_TerminateAgentResponse); ok { + return x.TerminateAgentResponse } return nil } func (x *AgentMessage) GetEnvSetupResponse() *EnvSetupResponse { - if x != nil { - if x, ok := x.Message.(*AgentMessage_EnvSetupResponse); ok { - return x.EnvSetupResponse - } + if x, ok := x.GetMessage().(*AgentMessage_EnvSetupResponse); ok { + return x.EnvSetupResponse } return nil } func (x *AgentMessage) GetCommandExecutionResponse() *CommandExecutionResponse { - if x != nil { - if x, ok := x.Message.(*AgentMessage_CommandExecutionResponse); ok { - return x.CommandExecutionResponse - } + if x, ok := x.GetMessage().(*AgentMessage_CommandExecutionResponse); ok { + return x.CommandExecutionResponse } return nil } func (x *AgentMessage) GetPythonExecutionResponse() *PythonExecutionResponse { - if x != nil { - if x, ok := x.Message.(*AgentMessage_PythonExecutionResponse); ok { - return x.PythonExecutionResponse - } + if x, ok := x.GetMessage().(*AgentMessage_PythonExecutionResponse); ok { + return x.PythonExecutionResponse } return nil } func (x *AgentMessage) GetJupyterExecutionResponse() *JupyterExecutionResponse { - if x != nil { - if x, ok := x.Message.(*AgentMessage_JupyterExecutionResponse); ok { - return x.JupyterExecutionResponse - } + if x, ok := x.GetMessage().(*AgentMessage_JupyterExecutionResponse); ok { + return x.JupyterExecutionResponse } return nil } func (x *AgentMessage) GetKernelRestartResponse() *KernelRestartResponse { - if x != nil { - if x, ok := x.Message.(*AgentMessage_KernelRestartResponse); ok { - return x.KernelRestartResponse - } + if x, ok := x.GetMessage().(*AgentMessage_KernelRestartResponse); ok { + return x.KernelRestartResponse } return nil } func (x *AgentMessage) GetTunnelCreationResponse() *TunnelCreationResponse { - if x != nil { - if x, ok := x.Message.(*AgentMessage_TunnelCreationResponse); ok { - return x.TunnelCreationResponse - } + if x, ok := x.GetMessage().(*AgentMessage_TunnelCreationResponse); ok { + return x.TunnelCreationResponse } return nil } func (x *AgentMessage) GetTunnelTerminationResponse() *TunnelTerminationResponse { - if x != nil { - if x, ok := x.Message.(*AgentMessage_TunnelTerminationResponse); ok { - return x.TunnelTerminationResponse - } + if x, ok := x.GetMessage().(*AgentMessage_TunnelTerminationResponse); ok { + return x.TunnelTerminationResponse } return nil } func (x *AgentMessage) GetAsyncCommandExecutionResponse() *AsyncCommandExecutionResponse { - if x != nil { - if x, ok := x.Message.(*AgentMessage_AsyncCommandExecutionResponse); ok { - return x.AsyncCommandExecutionResponse - } + if x, ok := x.GetMessage().(*AgentMessage_AsyncCommandExecutionResponse); ok { + return x.AsyncCommandExecutionResponse } return nil } func (x *AgentMessage) GetAsyncCommandListResponse() *AsyncCommandListResponse { - if x != nil { - if x, ok := x.Message.(*AgentMessage_AsyncCommandListResponse); ok { - return x.AsyncCommandListResponse - } + if x, ok := x.GetMessage().(*AgentMessage_AsyncCommandListResponse); ok { + return x.AsyncCommandListResponse } return nil } func (x *AgentMessage) GetAsyncCommandTerminateResponse() *AsyncCommandTerminateResponse { - if x != nil { - if x, ok := x.Message.(*AgentMessage_AsyncCommandTerminateResponse); ok { - return x.AsyncCommandTerminateResponse - } + if x, ok := x.GetMessage().(*AgentMessage_AsyncCommandTerminateResponse); ok { + return x.AsyncCommandTerminateResponse + } + return nil +} + +func (x *AgentMessage) GetRequestNextJobUnit() *RequestNextJobUnit { + if x, ok := x.GetMessage().(*AgentMessage_RequestNextJobUnit); ok { + return x.RequestNextJobUnit + } + return nil +} + +func (x *AgentMessage) GetJobUnitCompleted() *JobUnitCompleted { + if x, ok := x.GetMessage().(*AgentMessage_JobUnitCompleted); ok { + return x.JobUnitCompleted } return nil } @@ -1845,6 +2064,14 @@ type AgentMessage_AsyncCommandTerminateResponse struct { AsyncCommandTerminateResponse *AsyncCommandTerminateResponse `protobuf:"bytes,13,opt,name=asyncCommandTerminateResponse,proto3,oneof"` } +type AgentMessage_RequestNextJobUnit struct { + RequestNextJobUnit *RequestNextJobUnit `protobuf:"bytes,20,opt,name=requestNextJobUnit,proto3,oneof"` +} + +type AgentMessage_JobUnitCompleted struct { + JobUnitCompleted *JobUnitCompleted `protobuf:"bytes,21,opt,name=jobUnitCompleted,proto3,oneof"` +} + func (*AgentMessage_AgentPing) isAgentMessage_Message() {} func (*AgentMessage_CreateAgentResponse) isAgentMessage_Message() {} @@ -1871,9 +2098,16 @@ func (*AgentMessage_AsyncCommandListResponse) isAgentMessage_Message() {} func (*AgentMessage_AsyncCommandTerminateResponse) isAgentMessage_Message() {} +func (*AgentMessage_RequestNextJobUnit) isAgentMessage_Message() {} + +func (*AgentMessage_JobUnitCompleted) isAgentMessage_Message() {} + type ServerMessage struct { - state protoimpl.MessageState `protogen:"open.v1"` - // Types that are valid to be assigned to Message: + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Message: // // *ServerMessage_ShutdownRequest // *ServerMessage_CreateAgentRequest @@ -1888,14 +2122,14 @@ type ServerMessage struct { // *ServerMessage_AsyncCommandExecutionRequest // *ServerMessage_AsyncCommandListRequest // *ServerMessage_AsyncCommandTerminateRequest - Message isServerMessage_Message `protobuf_oneof:"message"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache + // *ServerMessage_AssignJobUnit + // *ServerMessage_NoJobUnitAvailable + Message isServerMessage_Message `protobuf_oneof:"message"` } func (x *ServerMessage) Reset() { *x = ServerMessage{} - mi := &file_agent_communication_proto_msgTypes[28] + mi := &file_agent_communication_proto_msgTypes[32] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1907,7 +2141,7 @@ func (x *ServerMessage) String() string { func (*ServerMessage) ProtoMessage() {} func (x *ServerMessage) ProtoReflect() protoreflect.Message { - mi := &file_agent_communication_proto_msgTypes[28] + mi := &file_agent_communication_proto_msgTypes[32] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1920,129 +2154,117 @@ func (x *ServerMessage) ProtoReflect() protoreflect.Message { // Deprecated: Use ServerMessage.ProtoReflect.Descriptor instead. func (*ServerMessage) Descriptor() ([]byte, []int) { - return file_agent_communication_proto_rawDescGZIP(), []int{28} + return file_agent_communication_proto_rawDescGZIP(), []int{32} } -func (x *ServerMessage) GetMessage() isServerMessage_Message { - if x != nil { - return x.Message +func (m *ServerMessage) GetMessage() isServerMessage_Message { + if m != nil { + return m.Message } return nil } func (x *ServerMessage) GetShutdownRequest() *ShutdownRequest { - if x != nil { - if x, ok := x.Message.(*ServerMessage_ShutdownRequest); ok { - return x.ShutdownRequest - } + if x, ok := x.GetMessage().(*ServerMessage_ShutdownRequest); ok { + return x.ShutdownRequest } return nil } func (x *ServerMessage) GetCreateAgentRequest() *CreateAgentRequest { - if x != nil { - if x, ok := x.Message.(*ServerMessage_CreateAgentRequest); ok { - return x.CreateAgentRequest - } + if x, ok := x.GetMessage().(*ServerMessage_CreateAgentRequest); ok { + return x.CreateAgentRequest } return nil } func (x *ServerMessage) GetTerminateAgentRequest() *TerminateAgentRequest { - if x != nil { - if x, ok := x.Message.(*ServerMessage_TerminateAgentRequest); ok { - return x.TerminateAgentRequest - } + if x, ok := x.GetMessage().(*ServerMessage_TerminateAgentRequest); ok { + return x.TerminateAgentRequest } return nil } func (x *ServerMessage) GetEnvSetupRequest() *EnvSetupRequest { - if x != nil { - if x, ok := x.Message.(*ServerMessage_EnvSetupRequest); ok { - return x.EnvSetupRequest - } + if x, ok := x.GetMessage().(*ServerMessage_EnvSetupRequest); ok { + return x.EnvSetupRequest } return nil } func (x *ServerMessage) GetCommandExecutionRequest() *CommandExecutionRequest { - if x != nil { - if x, ok := x.Message.(*ServerMessage_CommandExecutionRequest); ok { - return x.CommandExecutionRequest - } + if x, ok := x.GetMessage().(*ServerMessage_CommandExecutionRequest); ok { + return x.CommandExecutionRequest } return nil } func (x *ServerMessage) GetPythonExecutionRequest() *PythonExecutionRequest { - if x != nil { - if x, ok := x.Message.(*ServerMessage_PythonExecutionRequest); ok { - return x.PythonExecutionRequest - } + if x, ok := x.GetMessage().(*ServerMessage_PythonExecutionRequest); ok { + return x.PythonExecutionRequest } return nil } func (x *ServerMessage) GetJupyterExecutionRequest() *JupyterExecutionRequest { - if x != nil { - if x, ok := x.Message.(*ServerMessage_JupyterExecutionRequest); ok { - return x.JupyterExecutionRequest - } + if x, ok := x.GetMessage().(*ServerMessage_JupyterExecutionRequest); ok { + return x.JupyterExecutionRequest } return nil } func (x *ServerMessage) GetKernelRestartRequest() *KernelRestartRequest { - if x != nil { - if x, ok := x.Message.(*ServerMessage_KernelRestartRequest); ok { - return x.KernelRestartRequest - } + if x, ok := x.GetMessage().(*ServerMessage_KernelRestartRequest); ok { + return x.KernelRestartRequest } return nil } func (x *ServerMessage) GetTunnelCreationRequest() *TunnelCreationRequest { - if x != nil { - if x, ok := x.Message.(*ServerMessage_TunnelCreationRequest); ok { - return x.TunnelCreationRequest - } + if x, ok := x.GetMessage().(*ServerMessage_TunnelCreationRequest); ok { + return x.TunnelCreationRequest } return nil } func (x *ServerMessage) GetTunnelTerminationRequest() *TunnelTerminationRequest { - if x != nil { - if x, ok := x.Message.(*ServerMessage_TunnelTerminationRequest); ok { - return x.TunnelTerminationRequest - } + if x, ok := x.GetMessage().(*ServerMessage_TunnelTerminationRequest); ok { + return x.TunnelTerminationRequest } return nil } func (x *ServerMessage) GetAsyncCommandExecutionRequest() *AsyncCommandExecutionRequest { - if x != nil { - if x, ok := x.Message.(*ServerMessage_AsyncCommandExecutionRequest); ok { - return x.AsyncCommandExecutionRequest - } + if x, ok := x.GetMessage().(*ServerMessage_AsyncCommandExecutionRequest); ok { + return x.AsyncCommandExecutionRequest } return nil } func (x *ServerMessage) GetAsyncCommandListRequest() *AsyncCommandListRequest { - if x != nil { - if x, ok := x.Message.(*ServerMessage_AsyncCommandListRequest); ok { - return x.AsyncCommandListRequest - } + if x, ok := x.GetMessage().(*ServerMessage_AsyncCommandListRequest); ok { + return x.AsyncCommandListRequest } return nil } func (x *ServerMessage) GetAsyncCommandTerminateRequest() *AsyncCommandTerminateRequest { - if x != nil { - if x, ok := x.Message.(*ServerMessage_AsyncCommandTerminateRequest); ok { - return x.AsyncCommandTerminateRequest - } + if x, ok := x.GetMessage().(*ServerMessage_AsyncCommandTerminateRequest); ok { + return x.AsyncCommandTerminateRequest + } + return nil +} + +func (x *ServerMessage) GetAssignJobUnit() *AssignJobUnit { + if x, ok := x.GetMessage().(*ServerMessage_AssignJobUnit); ok { + return x.AssignJobUnit + } + return nil +} + +func (x *ServerMessage) GetNoJobUnitAvailable() *NoJobUnitAvailable { + if x, ok := x.GetMessage().(*ServerMessage_NoJobUnitAvailable); ok { + return x.NoJobUnitAvailable } return nil } @@ -2103,6 +2325,14 @@ type ServerMessage_AsyncCommandTerminateRequest struct { AsyncCommandTerminateRequest *AsyncCommandTerminateRequest `protobuf:"bytes,13,opt,name=asyncCommandTerminateRequest,proto3,oneof"` } +type ServerMessage_AssignJobUnit struct { + AssignJobUnit *AssignJobUnit `protobuf:"bytes,20,opt,name=assignJobUnit,proto3,oneof"` +} + +type ServerMessage_NoJobUnitAvailable struct { + NoJobUnitAvailable *NoJobUnitAvailable `protobuf:"bytes,21,opt,name=noJobUnitAvailable,proto3,oneof"` +} + func (*ServerMessage_ShutdownRequest) isServerMessage_Message() {} func (*ServerMessage_CreateAgentRequest) isServerMessage_Message() {} @@ -2129,173 +2359,455 @@ func (*ServerMessage_AsyncCommandListRequest) isServerMessage_Message() {} func (*ServerMessage_AsyncCommandTerminateRequest) isServerMessage_Message() {} +func (*ServerMessage_AssignJobUnit) isServerMessage_Message() {} + +func (*ServerMessage_NoJobUnitAvailable) isServerMessage_Message() {} + var File_agent_communication_proto protoreflect.FileDescriptor -const file_agent_communication_proto_rawDesc = "" + - "\n" + - "\x19agent-communication.proto\x12\x19org.apache.airavata.agent\"%\n" + - "\tAgentPing\x12\x18\n" + - "\aagentId\x18\x01 \x01(\tR\aagentId\"+\n" + - "\x0fShutdownRequest\x12\x18\n" + - "\aagentId\x18\x01 \x01(\tR\aagentId\"\xaa\x01\n" + - "\x12CreateAgentRequest\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" + - "\aagentId\x18\x02 \x01(\tR\aagentId\x12 \n" + - "\vcontainerId\x18\x03 \x01(\tR\vcontainerId\x12\x1e\n" + - "\n" + - "workingDir\x18\x04 \x01(\tR\n" + - "workingDir\x12\x16\n" + - "\x06mounts\x18\x05 \x03(\tR\x06mounts\"i\n" + - "\x13CreateAgentResponse\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" + - "\aagentId\x18\x02 \x01(\tR\aagentId\x12\x16\n" + - "\x06status\x18\x03 \x01(\tR\x06status\"S\n" + - "\x15TerminateAgentRequest\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" + - "\aagentId\x18\x02 \x01(\tR\aagentId\"l\n" + - "\x16TerminateAgentResponse\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" + - "\aagentId\x18\x02 \x01(\tR\aagentId\x12\x16\n" + - "\x06status\x18\x03 \x01(\tR\x06status\"}\n" + - "\x0fEnvSetupRequest\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" + - "\aenvName\x18\x02 \x01(\tR\aenvName\x12\x1c\n" + - "\tlibraries\x18\x03 \x03(\tR\tlibraries\x12\x10\n" + - "\x03pip\x18\x04 \x03(\tR\x03pip\"L\n" + - "\x10EnvSetupResponse\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x16\n" + - "\x06status\x18\x02 \x01(\tR\x06status\"\x93\x01\n" + - "\x17CommandExecutionRequest\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" + - "\aenvName\x18\x02 \x01(\tR\aenvName\x12\x1e\n" + - "\n" + - "workingDir\x18\x03 \x01(\tR\n" + - "workingDir\x12\x1c\n" + - "\targuments\x18\x04 \x03(\tR\targuments\"d\n" + - "\x18CommandExecutionResponse\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12&\n" + - "\x0eresponseString\x18\x02 \x01(\tR\x0eresponseString\"\x98\x01\n" + - "\x1cAsyncCommandExecutionRequest\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" + - "\aenvName\x18\x02 \x01(\tR\aenvName\x12\x1e\n" + - "\n" + - "workingDir\x18\x03 \x01(\tR\n" + - "workingDir\x12\x1c\n" + - "\targuments\x18\x04 \x03(\tR\targuments\"\x83\x01\n" + - "\x1dAsyncCommandExecutionResponse\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x1c\n" + - "\tprocessId\x18\x02 \x01(\x05R\tprocessId\x12\"\n" + - "\ferrorMessage\x18\x03 \x01(\tR\ferrorMessage\";\n" + - "\x17AsyncCommandListRequest\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\"J\n" + - "\fAsyncCommand\x12\x1c\n" + - "\tprocessId\x18\x01 \x01(\x05R\tprocessId\x12\x1c\n" + - "\targuments\x18\x04 \x03(\tR\targuments\"\x81\x01\n" + - "\x18AsyncCommandListResponse\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12C\n" + - "\bcommands\x18\x02 \x03(\v2'.org.apache.airavata.agent.AsyncCommandR\bcommands\"^\n" + - "\x1cAsyncCommandTerminateRequest\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x1c\n" + - "\tprocessId\x18\x02 \x01(\x05R\tprocessId\"Y\n" + - "\x1dAsyncCommandTerminateResponse\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x16\n" + - "\x06status\x18\x02 \x01(\tR\x06status\"\x88\x01\n" + - "\x16PythonExecutionRequest\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" + - "\aenvName\x18\x02 \x01(\tR\aenvName\x12\x1e\n" + - "\n" + - "workingDir\x18\x03 \x01(\tR\n" + - "workingDir\x12\x12\n" + - "\x04code\x18\x04 \x01(\tR\x04code\"c\n" + - "\x17PythonExecutionResponse\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12&\n" + - "\x0eresponseString\x18\x02 \x01(\tR\x0eresponseString\"i\n" + - "\x17JupyterExecutionRequest\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" + - "\aenvName\x18\x02 \x01(\tR\aenvName\x12\x12\n" + - "\x04code\x18\x03 \x01(\tR\x04code\"d\n" + - "\x18JupyterExecutionResponse\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12&\n" + - "\x0eresponseString\x18\x02 \x01(\tR\x0eresponseString\"R\n" + - "\x14KernelRestartRequest\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x18\n" + - "\aenvName\x18\x02 \x01(\tR\aenvName\"Q\n" + - "\x15KernelRestartResponse\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x16\n" + - "\x06status\x18\x02 \x01(\tR\x06status\"\xb3\x02\n" + - "\x15TunnelCreationRequest\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x1c\n" + - "\tlocalPort\x18\x02 \x01(\x05R\tlocalPort\x12$\n" + - "\rlocalBindHost\x18\x03 \x01(\tR\rlocalBindHost\x12*\n" + - "\x10tunnelServerHost\x18\x04 \x01(\tR\x10tunnelServerHost\x12*\n" + - "\x10tunnelServerPort\x18\x05 \x01(\x05R\x10tunnelServerPort\x12.\n" + - "\x12tunnelServerApiUrl\x18\x06 \x01(\tR\x12tunnelServerApiUrl\x12,\n" + - "\x11tunnelServerToken\x18\a \x01(\tR\x11tunnelServerToken\"\xae\x01\n" + - "\x16TunnelCreationResponse\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x16\n" + - "\x06status\x18\x02 \x01(\tR\x06status\x12\x1e\n" + - "\n" + - "tunnelHost\x18\x03 \x01(\tR\n" + - "tunnelHost\x12\x1e\n" + - "\n" + - "tunnelPort\x18\x04 \x01(\x05R\n" + - "tunnelPort\x12\x1a\n" + - "\btunnelId\x18\x05 \x01(\tR\btunnelId\"X\n" + - "\x18TunnelTerminationRequest\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x1a\n" + - "\btunnelId\x18\x02 \x01(\tR\btunnelId\"U\n" + - "\x19TunnelTerminationResponse\x12 \n" + - "\vexecutionId\x18\x01 \x01(\tR\vexecutionId\x12\x16\n" + - "\x06status\x18\x02 \x01(\tR\x06status\"\xa7\v\n" + - "\fAgentMessage\x12D\n" + - "\tagentPing\x18\x01 \x01(\v2$.org.apache.airavata.agent.AgentPingH\x00R\tagentPing\x12b\n" + - "\x13createAgentResponse\x18\x02 \x01(\v2..org.apache.airavata.agent.CreateAgentResponseH\x00R\x13createAgentResponse\x12k\n" + - "\x16terminateAgentResponse\x18\x03 \x01(\v21.org.apache.airavata.agent.TerminateAgentResponseH\x00R\x16terminateAgentResponse\x12Y\n" + - "\x10envSetupResponse\x18\x04 \x01(\v2+.org.apache.airavata.agent.EnvSetupResponseH\x00R\x10envSetupResponse\x12q\n" + - "\x18commandExecutionResponse\x18\x05 \x01(\v23.org.apache.airavata.agent.CommandExecutionResponseH\x00R\x18commandExecutionResponse\x12n\n" + - "\x17pythonExecutionResponse\x18\x06 \x01(\v22.org.apache.airavata.agent.PythonExecutionResponseH\x00R\x17pythonExecutionResponse\x12q\n" + - "\x18jupyterExecutionResponse\x18\a \x01(\v23.org.apache.airavata.agent.JupyterExecutionResponseH\x00R\x18jupyterExecutionResponse\x12h\n" + - "\x15kernelRestartResponse\x18\b \x01(\v20.org.apache.airavata.agent.KernelRestartResponseH\x00R\x15kernelRestartResponse\x12k\n" + - "\x16tunnelCreationResponse\x18\t \x01(\v21.org.apache.airavata.agent.TunnelCreationResponseH\x00R\x16tunnelCreationResponse\x12t\n" + - "\x19tunnelTerminationResponse\x18\n" + - " \x01(\v24.org.apache.airavata.agent.TunnelTerminationResponseH\x00R\x19tunnelTerminationResponse\x12\x80\x01\n" + - "\x1dasyncCommandExecutionResponse\x18\v \x01(\v28.org.apache.airavata.agent.AsyncCommandExecutionResponseH\x00R\x1dasyncCommandExecutionResponse\x12q\n" + - "\x18asyncCommandListResponse\x18\f \x01(\v23.org.apache.airavata.agent.AsyncCommandListResponseH\x00R\x18asyncCommandListResponse\x12\x80\x01\n" + - "\x1dasyncCommandTerminateResponse\x18\r \x01(\v28.org.apache.airavata.agent.AsyncCommandTerminateResponseH\x00R\x1dasyncCommandTerminateResponseB\t\n" + - "\amessage\"\x94\v\n" + - "\rServerMessage\x12V\n" + - "\x0fshutdownRequest\x18\x01 \x01(\v2*.org.apache.airavata.agent.ShutdownRequestH\x00R\x0fshutdownRequest\x12_\n" + - "\x12createAgentRequest\x18\x02 \x01(\v2-.org.apache.airavata.agent.CreateAgentRequestH\x00R\x12createAgentRequest\x12h\n" + - "\x15terminateAgentRequest\x18\x03 \x01(\v20.org.apache.airavata.agent.TerminateAgentRequestH\x00R\x15terminateAgentRequest\x12V\n" + - "\x0fenvSetupRequest\x18\x04 \x01(\v2*.org.apache.airavata.agent.EnvSetupRequestH\x00R\x0fenvSetupRequest\x12n\n" + - "\x17commandExecutionRequest\x18\x05 \x01(\v22.org.apache.airavata.agent.CommandExecutionRequestH\x00R\x17commandExecutionRequest\x12k\n" + - "\x16pythonExecutionRequest\x18\x06 \x01(\v21.org.apache.airavata.agent.PythonExecutionRequestH\x00R\x16pythonExecutionRequest\x12n\n" + - "\x17jupyterExecutionRequest\x18\a \x01(\v22.org.apache.airavata.agent.JupyterExecutionRequestH\x00R\x17jupyterExecutionRequest\x12e\n" + - "\x14kernelRestartRequest\x18\b \x01(\v2/.org.apache.airavata.agent.KernelRestartRequestH\x00R\x14kernelRestartRequest\x12h\n" + - "\x15tunnelCreationRequest\x18\t \x01(\v20.org.apache.airavata.agent.TunnelCreationRequestH\x00R\x15tunnelCreationRequest\x12q\n" + - "\x18tunnelTerminationRequest\x18\n" + - " \x01(\v23.org.apache.airavata.agent.TunnelTerminationRequestH\x00R\x18tunnelTerminationRequest\x12}\n" + - "\x1casyncCommandExecutionRequest\x18\v \x01(\v27.org.apache.airavata.agent.AsyncCommandExecutionRequestH\x00R\x1casyncCommandExecutionRequest\x12n\n" + - "\x17asyncCommandListRequest\x18\f \x01(\v22.org.apache.airavata.agent.AsyncCommandListRequestH\x00R\x17asyncCommandListRequest\x12}\n" + - "\x1casyncCommandTerminateRequest\x18\r \x01(\v27.org.apache.airavata.agent.AsyncCommandTerminateRequestH\x00R\x1casyncCommandTerminateRequestB\t\n" + - "\amessage2\x86\x01\n" + - "\x19AgentCommunicationService\x12i\n" + - "\x10createMessageBus\x12'.org.apache.airavata.agent.AgentMessage\x1a(.org.apache.airavata.agent.ServerMessage(\x010\x01B?\n" + - "\x19org.apache.airavata.agentB\x17AgentCommunicationProtoP\x01Z\aprotos/b\x06proto3" +var file_agent_communication_proto_rawDesc = []byte{ + 0x0a, 0x19, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2d, 0x63, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x6f, 0x72, 0x67, + 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, + 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x22, 0x25, 0x0a, 0x09, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x50, + 0x69, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x2b, 0x0a, + 0x0f, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x18, 0x0a, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0xaa, 0x01, 0x0a, 0x12, 0x43, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x20, 0x0a, + 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, + 0x1e, 0x0a, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x44, 0x69, 0x72, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x44, 0x69, 0x72, 0x12, + 0x16, 0x0a, 0x06, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x06, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x22, 0x69, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, + 0x12, 0x18, 0x0a, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x22, 0x53, 0x0a, 0x15, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x41, + 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, + 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x6c, 0x0a, 0x16, 0x54, 0x65, 0x72, 0x6d, 0x69, + 0x6e, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x16, 0x0a, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x7d, 0x0a, 0x0f, 0x45, 0x6e, 0x76, 0x53, 0x65, 0x74, 0x75, + 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, + 0x76, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x76, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, 0x65, + 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x6c, 0x69, 0x62, 0x72, 0x61, 0x72, 0x69, + 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x70, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x03, 0x70, 0x69, 0x70, 0x22, 0x4c, 0x0a, 0x10, 0x45, 0x6e, 0x76, 0x53, 0x65, 0x74, 0x75, 0x70, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x22, 0x93, 0x01, 0x0a, 0x17, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, + 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, + 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x76, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x65, 0x6e, 0x76, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x77, 0x6f, + 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x44, 0x69, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x44, 0x69, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x64, 0x0a, 0x18, 0x43, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x98, + 0x01, 0x0a, 0x1c, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x76, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x76, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x77, + 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x44, 0x69, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x44, 0x69, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, + 0x61, 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x83, 0x01, 0x0a, 0x1d, 0x41, 0x73, + 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1c, 0x0a, + 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0c, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, + 0x3b, 0x0a, 0x17, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4c, + 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x22, 0x4a, 0x0a, 0x0c, + 0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x1c, 0x0a, 0x09, + 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x72, + 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, + 0x72, 0x67, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x81, 0x01, 0x0a, 0x18, 0x41, 0x73, 0x79, + 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x43, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6f, 0x72, 0x67, 0x2e, + 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, + 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x5e, 0x0a, 0x1c, + 0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x65, 0x72, 0x6d, + 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, + 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1c, + 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x64, 0x22, 0x59, 0x0a, 0x1d, + 0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x65, 0x72, 0x6d, + 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, + 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x88, 0x01, 0x0a, 0x16, 0x50, 0x79, 0x74, 0x68, + 0x6f, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x76, 0x4e, 0x61, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x76, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1e, + 0x0a, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x44, 0x69, 0x72, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x44, 0x69, 0x72, 0x12, 0x12, + 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, + 0x64, 0x65, 0x22, 0x63, 0x0a, 0x17, 0x50, 0x79, 0x74, 0x68, 0x6f, 0x6e, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, + 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, + 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x69, 0x0a, 0x17, 0x4a, 0x75, 0x70, 0x79, 0x74, + 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x76, 0x4e, 0x61, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x76, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, + 0x64, 0x65, 0x22, 0x64, 0x0a, 0x18, 0x4a, 0x75, 0x70, 0x79, 0x74, 0x65, 0x72, 0x45, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, + 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, + 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x52, 0x0a, 0x14, 0x4b, 0x65, 0x72, 0x6e, + 0x65, 0x6c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x76, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x65, 0x6e, 0x76, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0x51, 0x0a, 0x15, + 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, + 0xb3, 0x02, 0x0a, 0x15, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x42, 0x69, 0x6e, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x42, 0x69, 0x6e, 0x64, 0x48, 0x6f, 0x73, 0x74, 0x12, + 0x2a, 0x0a, 0x10, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, + 0x6f, 0x73, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x74, 0x75, 0x6e, 0x6e, 0x65, + 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x10, 0x74, + 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x2e, 0x0a, 0x12, 0x74, 0x75, 0x6e, 0x6e, 0x65, + 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x70, 0x69, 0x55, 0x72, 0x6c, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x12, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x41, 0x70, 0x69, 0x55, 0x72, 0x6c, 0x12, 0x2c, 0x0a, 0x11, 0x74, 0x75, 0x6e, 0x6e, 0x65, + 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x11, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xae, 0x01, 0x0a, 0x16, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x75, + 0x6e, 0x6e, 0x65, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x75, + 0x6e, 0x6e, 0x65, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, + 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x75, + 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x75, + 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x22, 0x58, 0x0a, 0x18, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, + 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x20, 0x0a, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, + 0x22, 0x55, 0x0a, 0x19, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, + 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x2f, 0x0a, 0x12, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x4e, 0x65, 0x78, 0x74, 0x4a, 0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x19, 0x0a, + 0x08, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x4f, 0x0a, 0x10, 0x4a, 0x6f, 0x62, 0x55, + 0x6e, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0b, + 0x6a, 0x6f, 0x62, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x6a, 0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, + 0x65, 0x78, 0x69, 0x74, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x08, 0x65, 0x78, 0x69, 0x74, 0x43, 0x6f, 0x64, 0x65, 0x22, 0x5a, 0x0a, 0x0d, 0x41, 0x73, 0x73, + 0x69, 0x67, 0x6e, 0x4a, 0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x1e, 0x0a, 0x0b, 0x6a, 0x6f, + 0x62, 0x5f, 0x75, 0x6e, 0x69, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x6a, 0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, + 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x43, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x22, 0x2c, 0x0a, 0x12, 0x4e, 0x6f, 0x4a, 0x6f, 0x62, 0x55, 0x6e, + 0x69, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, + 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, + 0x73, 0x6f, 0x6e, 0x22, 0xe3, 0x0c, 0x0a, 0x0c, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, + 0x73, 0x61, 0x67, 0x65, 0x12, 0x44, 0x0a, 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x50, 0x69, 0x6e, + 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, + 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x50, 0x69, 0x6e, 0x67, 0x48, 0x00, 0x52, + 0x09, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x50, 0x69, 0x6e, 0x67, 0x12, 0x62, 0x0a, 0x13, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, + 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x13, 0x63, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, + 0x0a, 0x16, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, + 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, + 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x65, 0x72, 0x6d, 0x69, + 0x6e, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x48, 0x00, 0x52, 0x16, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x41, 0x67, + 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x10, 0x65, + 0x6e, 0x76, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, + 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x2e, 0x45, 0x6e, 0x76, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x48, 0x00, 0x52, 0x10, 0x65, 0x6e, 0x76, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x18, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, + 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, + 0x18, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6e, 0x0a, 0x17, 0x70, 0x79, 0x74, + 0x68, 0x6f, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x6f, 0x72, 0x67, + 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, + 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x50, 0x79, 0x74, 0x68, 0x6f, 0x6e, 0x45, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, + 0x52, 0x17, 0x70, 0x79, 0x74, 0x68, 0x6f, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x18, 0x6a, 0x75, 0x70, + 0x79, 0x74, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x6f, 0x72, + 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, + 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x4a, 0x75, 0x70, 0x79, 0x74, 0x65, 0x72, 0x45, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x48, 0x00, 0x52, 0x18, 0x6a, 0x75, 0x70, 0x79, 0x74, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x15, + 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x6f, 0x72, + 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, + 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x4b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x52, 0x65, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, + 0x15, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6b, 0x0a, 0x16, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, + 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x16, 0x74, 0x75, 0x6e, + 0x6e, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x74, 0x0a, 0x19, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, + 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, + 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x19, + 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x80, 0x01, 0x0a, 0x1d, 0x61, 0x73, + 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x38, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, + 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x73, + 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x1d, 0x61, + 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x18, + 0x61, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, + 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, + 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x73, 0x79, 0x6e, 0x63, + 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x48, 0x00, 0x52, 0x18, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x80, 0x01, 0x0a, 0x1d, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, + 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x48, 0x00, 0x52, 0x1d, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x12, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4e, 0x65, 0x78, + 0x74, 0x4a, 0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2d, + 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, + 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x4e, 0x65, 0x78, 0x74, 0x4a, 0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x48, 0x00, 0x52, + 0x12, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4e, 0x65, 0x78, 0x74, 0x4a, 0x6f, 0x62, 0x55, + 0x6e, 0x69, 0x74, 0x12, 0x59, 0x0a, 0x10, 0x6a, 0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x43, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, + 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, + 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x4a, 0x6f, 0x62, 0x55, 0x6e, 0x69, + 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x48, 0x00, 0x52, 0x10, 0x6a, 0x6f, + 0x62, 0x55, 0x6e, 0x69, 0x74, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x42, 0x09, + 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xc7, 0x0c, 0x0a, 0x0d, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x56, 0x0a, 0x0f, 0x73, + 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, + 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2e, 0x53, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x48, 0x00, 0x52, 0x0f, 0x73, 0x68, 0x75, 0x74, 0x64, 0x6f, 0x77, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x5f, 0x0a, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, + 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2d, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, + 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, + 0x52, 0x12, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x68, 0x0a, 0x15, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, + 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, + 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, + 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x15, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, + 0x74, 0x65, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x56, + 0x0a, 0x0f, 0x65, 0x6e, 0x76, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, + 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x45, 0x6e, 0x76, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x0f, 0x65, 0x6e, 0x76, 0x53, 0x65, 0x74, 0x75, 0x70, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x6e, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, + 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x17, 0x63, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x6b, 0x0a, 0x16, 0x70, 0x79, 0x74, 0x68, 0x6f, 0x6e, + 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, + 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2e, 0x50, 0x79, 0x74, 0x68, 0x6f, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x16, 0x70, 0x79, 0x74, + 0x68, 0x6f, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x6e, 0x0a, 0x17, 0x6a, 0x75, 0x70, 0x79, 0x74, 0x65, 0x72, 0x45, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, + 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, + 0x2e, 0x4a, 0x75, 0x70, 0x79, 0x74, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x17, 0x6a, 0x75, 0x70, 0x79, + 0x74, 0x65, 0x72, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x65, 0x0a, 0x14, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2f, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, + 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x4b, 0x65, + 0x72, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x48, 0x00, 0x52, 0x14, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x52, 0x65, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x68, 0x0a, 0x15, 0x74, 0x75, + 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x6f, 0x72, 0x67, 0x2e, + 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, + 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x15, 0x74, + 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x71, 0x0a, 0x18, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, + 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, + 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x18, 0x74, + 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x7d, 0x0a, 0x1c, 0x61, 0x73, 0x79, 0x6e, 0x63, + 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, + 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, + 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x1c, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x6e, 0x0a, 0x17, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, + 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, + 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x17, 0x61, + 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x7d, 0x0a, 0x1c, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x37, 0x2e, 0x6f, + 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, + 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x48, 0x00, 0x52, 0x1c, 0x61, 0x73, 0x79, 0x6e, 0x63, 0x43, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x50, 0x0a, 0x0d, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4a, + 0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x6f, + 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, + 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x73, 0x73, 0x69, 0x67, 0x6e, 0x4a, + 0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x61, 0x73, 0x73, 0x69, 0x67, 0x6e, + 0x4a, 0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x12, 0x5f, 0x0a, 0x12, 0x6e, 0x6f, 0x4a, 0x6f, 0x62, + 0x55, 0x6e, 0x69, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x15, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, + 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, + 0x4e, 0x6f, 0x4a, 0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, + 0x6c, 0x65, 0x48, 0x00, 0x52, 0x12, 0x6e, 0x6f, 0x4a, 0x6f, 0x62, 0x55, 0x6e, 0x69, 0x74, 0x41, + 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, + 0x61, 0x67, 0x65, 0x32, 0x86, 0x01, 0x0a, 0x19, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, + 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x12, 0x69, 0x0a, 0x10, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x42, 0x75, 0x73, 0x12, 0x27, 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, + 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, + 0x74, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x28, + 0x2e, 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, + 0x76, 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0x3f, 0x0a, 0x19, + 0x6f, 0x72, 0x67, 0x2e, 0x61, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2e, 0x61, 0x69, 0x72, 0x61, 0x76, + 0x61, 0x74, 0x61, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x42, 0x17, 0x41, 0x67, 0x65, 0x6e, 0x74, + 0x43, 0x6f, 0x6d, 0x6d, 0x75, 0x6e, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, + 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x07, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x73, 0x2f, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, +} var ( file_agent_communication_proto_rawDescOnce sync.Once - file_agent_communication_proto_rawDescData []byte + file_agent_communication_proto_rawDescData = file_agent_communication_proto_rawDesc ) func file_agent_communication_proto_rawDescGZIP() []byte { file_agent_communication_proto_rawDescOnce.Do(func() { - file_agent_communication_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_agent_communication_proto_rawDesc), len(file_agent_communication_proto_rawDesc))) + file_agent_communication_proto_rawDescData = protoimpl.X.CompressGZIP(file_agent_communication_proto_rawDescData) }) return file_agent_communication_proto_rawDescData } -var file_agent_communication_proto_msgTypes = make([]protoimpl.MessageInfo, 29) +var file_agent_communication_proto_msgTypes = make([]protoimpl.MessageInfo, 33) var file_agent_communication_proto_goTypes = []any{ (*AgentPing)(nil), // 0: org.apache.airavata.agent.AgentPing (*ShutdownRequest)(nil), // 1: org.apache.airavata.agent.ShutdownRequest @@ -2324,8 +2836,12 @@ var file_agent_communication_proto_goTypes = []any{ (*TunnelCreationResponse)(nil), // 24: org.apache.airavata.agent.TunnelCreationResponse (*TunnelTerminationRequest)(nil), // 25: org.apache.airavata.agent.TunnelTerminationRequest (*TunnelTerminationResponse)(nil), // 26: org.apache.airavata.agent.TunnelTerminationResponse - (*AgentMessage)(nil), // 27: org.apache.airavata.agent.AgentMessage - (*ServerMessage)(nil), // 28: org.apache.airavata.agent.ServerMessage + (*RequestNextJobUnit)(nil), // 27: org.apache.airavata.agent.RequestNextJobUnit + (*JobUnitCompleted)(nil), // 28: org.apache.airavata.agent.JobUnitCompleted + (*AssignJobUnit)(nil), // 29: org.apache.airavata.agent.AssignJobUnit + (*NoJobUnitAvailable)(nil), // 30: org.apache.airavata.agent.NoJobUnitAvailable + (*AgentMessage)(nil), // 31: org.apache.airavata.agent.AgentMessage + (*ServerMessage)(nil), // 32: org.apache.airavata.agent.ServerMessage } var file_agent_communication_proto_depIdxs = []int32{ 13, // 0: org.apache.airavata.agent.AsyncCommandListResponse.commands:type_name -> org.apache.airavata.agent.AsyncCommand @@ -2342,26 +2858,30 @@ var file_agent_communication_proto_depIdxs = []int32{ 11, // 11: org.apache.airavata.agent.AgentMessage.asyncCommandExecutionResponse:type_name -> org.apache.airavata.agent.AsyncCommandExecutionResponse 14, // 12: org.apache.airavata.agent.AgentMessage.asyncCommandListResponse:type_name -> org.apache.airavata.agent.AsyncCommandListResponse 16, // 13: org.apache.airavata.agent.AgentMessage.asyncCommandTerminateResponse:type_name -> org.apache.airavata.agent.AsyncCommandTerminateResponse - 1, // 14: org.apache.airavata.agent.ServerMessage.shutdownRequest:type_name -> org.apache.airavata.agent.ShutdownRequest - 2, // 15: org.apache.airavata.agent.ServerMessage.createAgentRequest:type_name -> org.apache.airavata.agent.CreateAgentRequest - 4, // 16: org.apache.airavata.agent.ServerMessage.terminateAgentRequest:type_name -> org.apache.airavata.agent.TerminateAgentRequest - 6, // 17: org.apache.airavata.agent.ServerMessage.envSetupRequest:type_name -> org.apache.airavata.agent.EnvSetupRequest - 8, // 18: org.apache.airavata.agent.ServerMessage.commandExecutionRequest:type_name -> org.apache.airavata.agent.CommandExecutionRequest - 17, // 19: org.apache.airavata.agent.ServerMessage.pythonExecutionRequest:type_name -> org.apache.airavata.agent.PythonExecutionRequest - 19, // 20: org.apache.airavata.agent.ServerMessage.jupyterExecutionRequest:type_name -> org.apache.airavata.agent.JupyterExecutionRequest - 21, // 21: org.apache.airavata.agent.ServerMessage.kernelRestartRequest:type_name -> org.apache.airavata.agent.KernelRestartRequest - 23, // 22: org.apache.airavata.agent.ServerMessage.tunnelCreationRequest:type_name -> org.apache.airavata.agent.TunnelCreationRequest - 25, // 23: org.apache.airavata.agent.ServerMessage.tunnelTerminationRequest:type_name -> org.apache.airavata.agent.TunnelTerminationRequest - 10, // 24: org.apache.airavata.agent.ServerMessage.asyncCommandExecutionRequest:type_name -> org.apache.airavata.agent.AsyncCommandExecutionRequest - 12, // 25: org.apache.airavata.agent.ServerMessage.asyncCommandListRequest:type_name -> org.apache.airavata.agent.AsyncCommandListRequest - 15, // 26: org.apache.airavata.agent.ServerMessage.asyncCommandTerminateRequest:type_name -> org.apache.airavata.agent.AsyncCommandTerminateRequest - 27, // 27: org.apache.airavata.agent.AgentCommunicationService.createMessageBus:input_type -> org.apache.airavata.agent.AgentMessage - 28, // 28: org.apache.airavata.agent.AgentCommunicationService.createMessageBus:output_type -> org.apache.airavata.agent.ServerMessage - 28, // [28:29] is the sub-list for method output_type - 27, // [27:28] is the sub-list for method input_type - 27, // [27:27] is the sub-list for extension type_name - 27, // [27:27] is the sub-list for extension extendee - 0, // [0:27] is the sub-list for field type_name + 27, // 14: org.apache.airavata.agent.AgentMessage.requestNextJobUnit:type_name -> org.apache.airavata.agent.RequestNextJobUnit + 28, // 15: org.apache.airavata.agent.AgentMessage.jobUnitCompleted:type_name -> org.apache.airavata.agent.JobUnitCompleted + 1, // 16: org.apache.airavata.agent.ServerMessage.shutdownRequest:type_name -> org.apache.airavata.agent.ShutdownRequest + 2, // 17: org.apache.airavata.agent.ServerMessage.createAgentRequest:type_name -> org.apache.airavata.agent.CreateAgentRequest + 4, // 18: org.apache.airavata.agent.ServerMessage.terminateAgentRequest:type_name -> org.apache.airavata.agent.TerminateAgentRequest + 6, // 19: org.apache.airavata.agent.ServerMessage.envSetupRequest:type_name -> org.apache.airavata.agent.EnvSetupRequest + 8, // 20: org.apache.airavata.agent.ServerMessage.commandExecutionRequest:type_name -> org.apache.airavata.agent.CommandExecutionRequest + 17, // 21: org.apache.airavata.agent.ServerMessage.pythonExecutionRequest:type_name -> org.apache.airavata.agent.PythonExecutionRequest + 19, // 22: org.apache.airavata.agent.ServerMessage.jupyterExecutionRequest:type_name -> org.apache.airavata.agent.JupyterExecutionRequest + 21, // 23: org.apache.airavata.agent.ServerMessage.kernelRestartRequest:type_name -> org.apache.airavata.agent.KernelRestartRequest + 23, // 24: org.apache.airavata.agent.ServerMessage.tunnelCreationRequest:type_name -> org.apache.airavata.agent.TunnelCreationRequest + 25, // 25: org.apache.airavata.agent.ServerMessage.tunnelTerminationRequest:type_name -> org.apache.airavata.agent.TunnelTerminationRequest + 10, // 26: org.apache.airavata.agent.ServerMessage.asyncCommandExecutionRequest:type_name -> org.apache.airavata.agent.AsyncCommandExecutionRequest + 12, // 27: org.apache.airavata.agent.ServerMessage.asyncCommandListRequest:type_name -> org.apache.airavata.agent.AsyncCommandListRequest + 15, // 28: org.apache.airavata.agent.ServerMessage.asyncCommandTerminateRequest:type_name -> org.apache.airavata.agent.AsyncCommandTerminateRequest + 29, // 29: org.apache.airavata.agent.ServerMessage.assignJobUnit:type_name -> org.apache.airavata.agent.AssignJobUnit + 30, // 30: org.apache.airavata.agent.ServerMessage.noJobUnitAvailable:type_name -> org.apache.airavata.agent.NoJobUnitAvailable + 31, // 31: org.apache.airavata.agent.AgentCommunicationService.createMessageBus:input_type -> org.apache.airavata.agent.AgentMessage + 32, // 32: org.apache.airavata.agent.AgentCommunicationService.createMessageBus:output_type -> org.apache.airavata.agent.ServerMessage + 32, // [32:33] is the sub-list for method output_type + 31, // [31:32] is the sub-list for method input_type + 31, // [31:31] is the sub-list for extension type_name + 31, // [31:31] is the sub-list for extension extendee + 0, // [0:31] is the sub-list for field type_name } func init() { file_agent_communication_proto_init() } @@ -2369,7 +2889,7 @@ func file_agent_communication_proto_init() { if File_agent_communication_proto != nil { return } - file_agent_communication_proto_msgTypes[27].OneofWrappers = []any{ + file_agent_communication_proto_msgTypes[31].OneofWrappers = []any{ (*AgentMessage_AgentPing)(nil), (*AgentMessage_CreateAgentResponse)(nil), (*AgentMessage_TerminateAgentResponse)(nil), @@ -2383,8 +2903,10 @@ func file_agent_communication_proto_init() { (*AgentMessage_AsyncCommandExecutionResponse)(nil), (*AgentMessage_AsyncCommandListResponse)(nil), (*AgentMessage_AsyncCommandTerminateResponse)(nil), + (*AgentMessage_RequestNextJobUnit)(nil), + (*AgentMessage_JobUnitCompleted)(nil), } - file_agent_communication_proto_msgTypes[28].OneofWrappers = []any{ + file_agent_communication_proto_msgTypes[32].OneofWrappers = []any{ (*ServerMessage_ShutdownRequest)(nil), (*ServerMessage_CreateAgentRequest)(nil), (*ServerMessage_TerminateAgentRequest)(nil), @@ -2398,14 +2920,16 @@ func file_agent_communication_proto_init() { (*ServerMessage_AsyncCommandExecutionRequest)(nil), (*ServerMessage_AsyncCommandListRequest)(nil), (*ServerMessage_AsyncCommandTerminateRequest)(nil), + (*ServerMessage_AssignJobUnit)(nil), + (*ServerMessage_NoJobUnitAvailable)(nil), } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_agent_communication_proto_rawDesc), len(file_agent_communication_proto_rawDesc)), + RawDescriptor: file_agent_communication_proto_rawDesc, NumEnums: 0, - NumMessages: 29, + NumMessages: 33, NumExtensions: 0, NumServices: 1, }, @@ -2414,6 +2938,7 @@ func file_agent_communication_proto_init() { MessageInfos: file_agent_communication_proto_msgTypes, }.Build() File_agent_communication_proto = out.File + file_agent_communication_proto_rawDesc = nil file_agent_communication_proto_goTypes = nil file_agent_communication_proto_depIdxs = nil } diff --git a/modules/agent-framework/airavata-agent/protos/agent-communication_grpc.pb.go b/modules/agent-framework/airavata-agent/protos/agent-communication_grpc.pb.go index cb3b6f99f4..fbf393bf7d 100644 --- a/modules/agent-framework/airavata-agent/protos/agent-communication_grpc.pb.go +++ b/modules/agent-framework/airavata-agent/protos/agent-communication_grpc.pb.go @@ -1,25 +1,27 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.5.1 -// - protoc v4.25.3 -// source: agent-communication.proto - +// // Licensed to the Apache Software Foundation (ASF) under one -// or more contributor license agreements. See the NOTICE file +// or more contributor license agreements. See the NOTICE file // distributed with this work for additional information -// regarding copyright ownership. The ASF licenses this file +// regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance -// with the License. You may obtain a copy of the License at +// with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -// KIND, either express or implied. See the License for the +// KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. +// + +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.5.1 +// - protoc v5.29.3 +// source: agent-communication.proto package protos diff --git a/modules/agent-framework/proto/agent-communication.proto b/modules/agent-framework/proto/agent-communication.proto index 9e1dd82542..16baa82a54 100644 --- a/modules/agent-framework/proto/agent-communication.proto +++ b/modules/agent-framework/proto/agent-communication.proto @@ -189,6 +189,28 @@ message TunnelTerminationResponse { string status = 2; } +// Agent requesting the next job unit from the Job Workload +message RequestNextJobUnit { + string agent_id = 1; +} + +// Agent letting know the job unit is completed +message JobUnitCompleted { + string job_unit_id = 1; + int32 exit_code = 2; +} + +// Server assigning the job unit with the resolved command +message AssignJobUnit { + string job_unit_id = 1; + string resolved_command = 2; +} + +// Server indicating the agent that there are no job units to be consumed +message NoJobUnitAvailable { + string reason = 1; // EMPTY, EMPTY_ALL_DONE, NO_ASSIGNMENT +} + message AgentMessage { oneof message { AgentPing agentPing = 1; @@ -204,6 +226,9 @@ message AgentMessage { AsyncCommandExecutionResponse asyncCommandExecutionResponse = 11; AsyncCommandListResponse asyncCommandListResponse = 12; AsyncCommandTerminateResponse asyncCommandTerminateResponse = 13; + + RequestNextJobUnit requestNextJobUnit = 20; + JobUnitCompleted jobUnitCompleted = 21; } } @@ -222,5 +247,8 @@ message ServerMessage { AsyncCommandExecutionRequest asyncCommandExecutionRequest = 11; AsyncCommandListRequest asyncCommandListRequest = 12; AsyncCommandTerminateRequest asyncCommandTerminateRequest = 13; + + AssignJobUnit assignJobUnit = 20; + NoJobUnitAvailable noJobUnitAvailable = 21; } } From 41bd5215afe361246ad905effcfbc42cab33acb7 Mon Sep 17 00:00:00 2001 From: lahiruj Date: Fri, 7 Nov 2025 18:29:32 -0500 Subject: [PATCH 5/5] apply spotless styles --- .../service/config/AsyncConfig.java | 35 ++++++----- .../db/entity/AgentBatchAssignmentEntity.java | 36 +++++------ .../service/db/entity/JobBatchEntity.java | 40 ++++++------ .../service/db/entity/JobUnitEntity.java | 38 +++++------ .../db/repo/AgentBatchAssignmentRepo.java | 38 +++++------ .../service/db/repo/JobBatchRepo.java | 38 +++++------ .../service/db/repo/JobUnitRepo.java | 63 +++++++++++-------- .../handlers/AgentConnectionHandler.java | 18 +++--- .../handlers/AgentManagementHandler.java | 10 ++- .../service/handlers/AgentWorkService.java | 42 ++++++------- .../service/handlers/JobBatchHandler.java | 56 ++++++++++------- .../service/handlers/JobBatchWorker.java | 51 ++++++++------- .../service/handlers/JobUnitAllocator.java | 41 ++++++------ .../service/models/AssignResult.java | 40 ++++++------ .../service/models/JobBatchSpec.java | 38 +++++------ .../service/models/JobUnitStatus.java | 40 ++++++------ 16 files changed, 328 insertions(+), 296 deletions(-) diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/config/AsyncConfig.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/config/AsyncConfig.java index 17e3989fde..1b7d8a548b 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/config/AsyncConfig.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/config/AsyncConfig.java @@ -1,21 +1,22 @@ /** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ package org.apache.airavata.agent.connection.service.config; import org.springframework.context.annotation.Bean; diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/AgentBatchAssignmentEntity.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/AgentBatchAssignmentEntity.java index 7e2a2a2611..48f8641219 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/AgentBatchAssignmentEntity.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/AgentBatchAssignmentEntity.java @@ -1,28 +1,28 @@ /** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ package org.apache.airavata.agent.connection.service.db.entity; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Table; - import java.time.Instant; @Entity diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/JobBatchEntity.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/JobBatchEntity.java index 00c8f728f9..a1d03a2ff3 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/JobBatchEntity.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/JobBatchEntity.java @@ -1,21 +1,22 @@ /** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ package org.apache.airavata.agent.connection.service.db.entity; import com.fasterxml.jackson.databind.JsonNode; @@ -27,11 +28,10 @@ import jakarta.persistence.Lob; import jakarta.persistence.OneToMany; import jakarta.persistence.Table; -import org.hibernate.annotations.JdbcTypeCode; -import org.hibernate.type.SqlTypes; - import java.time.Instant; import java.util.List; +import org.hibernate.annotations.JdbcTypeCode; +import org.hibernate.type.SqlTypes; @Entity @Table(name = "JOB_BATCH") diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/JobUnitEntity.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/JobUnitEntity.java index 1d379abccd..6fd45ed264 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/JobUnitEntity.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/entity/JobUnitEntity.java @@ -1,21 +1,22 @@ /** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ package org.apache.airavata.agent.connection.service.db.entity; import jakarta.persistence.Column; @@ -28,9 +29,8 @@ import jakarta.persistence.Lob; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; -import org.apache.airavata.agent.connection.service.models.JobUnitStatus; - import java.time.Instant; +import org.apache.airavata.agent.connection.service.models.JobUnitStatus; @Entity @Table(name = "JOB_UNIT") diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/AgentBatchAssignmentRepo.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/AgentBatchAssignmentRepo.java index 5fec2fb706..6118d7e1a5 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/AgentBatchAssignmentRepo.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/AgentBatchAssignmentRepo.java @@ -1,28 +1,28 @@ /** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ package org.apache.airavata.agent.connection.service.db.repo; +import java.util.Optional; import org.apache.airavata.agent.connection.service.db.entity.AgentBatchAssignmentEntity; import org.springframework.data.jpa.repository.JpaRepository; -import java.util.Optional; - public interface AgentBatchAssignmentRepo extends JpaRepository { Optional findByAgentId(String agentId); diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobBatchRepo.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobBatchRepo.java index 719394f40c..5f1f92268f 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobBatchRepo.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobBatchRepo.java @@ -1,21 +1,22 @@ /** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ package org.apache.airavata.agent.connection.service.db.repo; import org.apache.airavata.agent.connection.service.db.entity.JobBatchEntity; @@ -23,5 +24,4 @@ import org.springframework.stereotype.Repository; @Repository -public interface JobBatchRepo extends JpaRepository { -} +public interface JobBatchRepo extends JpaRepository {} diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobUnitRepo.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobUnitRepo.java index 5c8293af6a..0a4841fcef 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobUnitRepo.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/db/repo/JobUnitRepo.java @@ -1,21 +1,22 @@ /** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ package org.apache.airavata.agent.connection.service.db.repo; import org.apache.airavata.agent.connection.service.db.entity.JobUnitEntity; @@ -28,35 +29,47 @@ @Repository public interface JobUnitRepo extends JpaRepository { - @Query(value = """ + @Query( + value = + """ SELECT ID FROM JOB_UNIT WHERE BATCH_ID = :batchId AND STATUS = 'PENDING' ORDER BY CREATED_AT, ID FOR UPDATE SKIP LOCKED LIMIT 1 - """, nativeQuery = true) + """, + nativeQuery = true) String lockNextPending(@Param("batchId") String batchId); @Modifying - @Query(value = """ + @Query( + value = + """ UPDATE JOB_UNIT SET STATUS='IN_PROGRESS', AGENT_ID=:agentId, STARTED_AT=CURRENT_TIMESTAMP(6) WHERE ID=:id - """, nativeQuery = true) + """, + nativeQuery = true) int markInProgress(@Param("id") String id, @Param("agentId") String agentId); @Query(value = "SELECT RESOLVED_COMMAND FROM JOB_UNIT WHERE ID=:id", nativeQuery = true) String getResolvedCommand(@Param("id") String id); @Modifying - @Query(value = """ + @Query( + value = + """ UPDATE JOB_UNIT SET STATUS='COMPLETED', COMPLETED_AT=CURRENT_TIMESTAMP(6) WHERE ID=:id - """, nativeQuery = true) + """, + nativeQuery = true) int markCompleted(@Param("id") String id); - @Query(value = """ + @Query( + value = + """ SELECT COUNT(*) FROM JOB_UNIT WHERE BATCH_ID = :batchId AND STATUS IN ('PENDING','IN_PROGRESS') - """, nativeQuery = true) + """, + nativeQuery = true) int countRemaining(@Param("batchId") String batchId); } diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentConnectionHandler.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentConnectionHandler.java index 693dc9345d..84be8ac95f 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentConnectionHandler.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/AgentConnectionHandler.java @@ -614,16 +614,20 @@ private void handleNextJobUnitRequest(String agentId, StreamObserver - * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ package org.apache.airavata.agent.connection.service.handlers; +import java.util.Optional; import org.apache.airavata.agent.connection.service.db.entity.AgentBatchAssignmentEntity; import org.apache.airavata.agent.connection.service.db.repo.AgentBatchAssignmentRepo; import org.apache.airavata.agent.connection.service.db.repo.JobUnitRepo; import org.apache.airavata.agent.connection.service.models.AssignResult; import org.springframework.stereotype.Service; -import java.util.Optional; - @Service public class AgentWorkService { @@ -33,7 +33,8 @@ public class AgentWorkService { private final JobUnitAllocator allocator; private final JobUnitRepo jobUnitRepo; - public AgentWorkService(AgentBatchAssignmentRepo assignmentRepo, JobUnitAllocator allocator, JobUnitRepo jobUnitRepo) { + public AgentWorkService( + AgentBatchAssignmentRepo assignmentRepo, JobUnitAllocator allocator, JobUnitRepo jobUnitRepo) { this.assignmentRepo = assignmentRepo; this.allocator = allocator; this.jobUnitRepo = jobUnitRepo; @@ -60,4 +61,3 @@ public void markCompleted(String jobUnitId) { allocator.markCompleted(jobUnitId); } } - diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchHandler.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchHandler.java index 157321dd82..8a181b0d62 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchHandler.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchHandler.java @@ -1,24 +1,26 @@ /** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ package org.apache.airavata.agent.connection.service.handlers; import com.fasterxml.jackson.databind.ObjectMapper; +import java.util.UUID; import org.apache.airavata.agent.connection.service.db.entity.AgentBatchAssignmentEntity; import org.apache.airavata.agent.connection.service.db.entity.JobBatchEntity; import org.apache.airavata.agent.connection.service.db.repo.AgentBatchAssignmentRepo; @@ -28,8 +30,6 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; -import java.util.UUID; - @Service public class JobBatchHandler { @@ -40,7 +40,11 @@ public class JobBatchHandler { private final AgentBatchAssignmentRepo agentJobAssignmentRepo; private final ObjectMapper objectMapper; - public JobBatchHandler(JobBatchWorker jobBatchWorker, JobBatchRepo jobBatchRepo, AgentBatchAssignmentRepo agentJobAssignmentRepo, ObjectMapper objectMapper) { + public JobBatchHandler( + JobBatchWorker jobBatchWorker, + JobBatchRepo jobBatchRepo, + AgentBatchAssignmentRepo agentJobAssignmentRepo, + ObjectMapper objectMapper) { this.jobBatchWorker = jobBatchWorker; this.jobBatchRepo = jobBatchRepo; this.agentJobAssignmentRepo = agentJobAssignmentRepo; @@ -51,14 +55,17 @@ public String handleJobWorkload(String experimentId, String agentId, JobBatchSpe String batchId = null; if (spec != null) { - if (spec.getApplicationCommand() == null || spec.getApplicationCommand().isBlank()) { + if (spec.getApplicationCommand() == null + || spec.getApplicationCommand().isBlank()) { LOGGER.warn("application_command is required for experiment with id: {}", experimentId); - throw new IllegalArgumentException("application_command is required for experiment with id: " + experimentId); + throw new IllegalArgumentException( + "application_command is required for experiment with id: " + experimentId); } if (spec.getParameterGrid() == null || spec.getParameterGrid().isEmpty()) { LOGGER.warn("parameter_grid is required for experiment with id: {}", experimentId); - throw new IllegalArgumentException("parameter_grid is required for experiment with id: " + experimentId); + throw new IllegalArgumentException( + "parameter_grid is required for experiment with id: " + experimentId); } batchId = UUID.randomUUID().toString(); @@ -75,7 +82,8 @@ public String handleJobWorkload(String experimentId, String agentId, JobBatchSpe assign.setBatchId(batchId); agentJobAssignmentRepo.save(assign); - jobBatchWorker.expandAndPersistUnitsAsync(experimentId, batchId, spec.getApplicationCommand(), spec.getParameterGrid()); + jobBatchWorker.expandAndPersistUnitsAsync( + experimentId, batchId, spec.getApplicationCommand(), spec.getParameterGrid()); } return batchId; } diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchWorker.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchWorker.java index ca8a97f37f..db6246a414 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchWorker.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobBatchWorker.java @@ -1,24 +1,30 @@ /** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ package org.apache.airavata.agent.connection.service.handlers; import jakarta.transaction.Transactional; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.UUID; import org.apache.airavata.agent.connection.service.db.entity.JobBatchEntity; import org.apache.airavata.agent.connection.service.db.entity.JobUnitEntity; import org.apache.airavata.agent.connection.service.db.repo.JobUnitRepo; @@ -27,12 +33,6 @@ import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.UUID; - @Service("jobBatchWorker") public class JobBatchWorker { @@ -49,8 +49,8 @@ public JobBatchWorker(JobUnitRepo jobUnitRepo) { */ @Async("batchExecutor") @Transactional(dontRollbackOn = Exception.class) - public void expandAndPersistUnitsAsync(String experimentId, String batchId, - String commandTemplate, Map> grid) { + public void expandAndPersistUnitsAsync( + String experimentId, String batchId, String commandTemplate, Map> grid) { if (grid == null || grid.isEmpty()) { return; @@ -113,7 +113,6 @@ public void expandAndPersistUnitsAsync(String experimentId, String batchId, LOGGER.info("Batch {} expansion complete (experiment {}).", batchId, experimentId); } - private static String renderCommand(String template, List keys, List values, int[] idx) { String cmd = template; for (int i = 0; i < keys.size(); i++) { diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobUnitAllocator.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobUnitAllocator.java index fd8b48bb6b..9e196172ec 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobUnitAllocator.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/handlers/JobUnitAllocator.java @@ -1,31 +1,31 @@ /** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ package org.apache.airavata.agent.connection.service.handlers; import jakarta.transaction.Transactional; +import java.util.Optional; import org.apache.airavata.agent.connection.service.db.repo.JobUnitRepo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; -import java.util.Optional; - @Service public class JobUnitAllocator { @@ -33,8 +33,7 @@ public class JobUnitAllocator { private final JobUnitRepo jobUnitRepo; - public record JobUnitRow(String id, String resolvedCommand) { - } + public record JobUnitRow(String id, String resolvedCommand) {} public JobUnitAllocator(JobUnitRepo jobUnitRepo) { this.jobUnitRepo = jobUnitRepo; diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AssignResult.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AssignResult.java index 1103a9c408..9616bea8ad 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AssignResult.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/AssignResult.java @@ -1,27 +1,27 @@ /** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ package org.apache.airavata.agent.connection.service.models; public sealed interface AssignResult permits AssignResult.Assigned, AssignResult.NoWork { - record Assigned(String jobUnitId, String resolvedCommand) implements AssignResult { - } + record Assigned(String jobUnitId, String resolvedCommand) implements AssignResult {} record NoWork(String reason) implements AssignResult { public static final String EMPTY = "EMPTY"; @@ -44,4 +44,4 @@ static NoWork emptyAllDone() { static NoWork noAssignment() { return new NoWork(NoWork.NO_ASSIGNMENT); } -} \ No newline at end of file +} diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/JobBatchSpec.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/JobBatchSpec.java index bb2c3fbb87..0517af9f3d 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/JobBatchSpec.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/JobBatchSpec.java @@ -1,25 +1,25 @@ /** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ package org.apache.airavata.agent.connection.service.models; import com.fasterxml.jackson.annotation.JsonProperty; - import java.util.List; import java.util.Map; @@ -57,4 +57,4 @@ public List getInputFiles() { public void setInputFiles(List inputFiles) { this.inputFiles = inputFiles; } -} \ No newline at end of file +} diff --git a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/JobUnitStatus.java b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/JobUnitStatus.java index 670978fe57..881fef6019 100644 --- a/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/JobUnitStatus.java +++ b/modules/agent-framework/agent-service/src/main/java/org/apache/airavata/agent/connection/service/models/JobUnitStatus.java @@ -1,23 +1,27 @@ /** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - *

- * http://www.apache.org/licenses/LICENSE-2.0 - *

- * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ +* +* Licensed to the Apache Software Foundation (ASF) under one +* or more contributor license agreements. See the NOTICE file +* distributed with this work for additional information +* regarding copyright ownership. The ASF licenses this file +* to you under the Apache License, Version 2.0 (the +* "License"); you may not use this file except in compliance +* with the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, +* software distributed under the License is distributed on an +* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +* KIND, either express or implied. See the License for the +* specific language governing permissions and limitations +* under the License. +*/ package org.apache.airavata.agent.connection.service.models; public enum JobUnitStatus { - PENDING, IN_PROGRESS, COMPLETED, FAILED + PENDING, + IN_PROGRESS, + COMPLETED, + FAILED }