This is an automated email from the ASF dual-hosted git repository. yasith pushed a commit to branch airavata-rest-api in repository https://gitbox.apache.org/repos/asf/airavata.git
commit cc9db881cd51ffe2409583598c44630dc4aaff4c Author: yasithdev <[email protected]> AuthorDate: Thu Nov 20 13:55:26 2025 -0600 initial rest api implementation --- modules/airavata-rest-api/pom.xml | 122 ++++++++++ .../airavata/restapi/RestApiApplication.java | 34 +++ .../airavata/restapi/RestApiConfiguration.java | 53 +++++ .../apache/airavata/restapi/config/WebConfig.java | 40 ++++ .../controller/ComputeResourceController.java | 246 +++++++++++++++++++ .../controller/StorageResourceController.java | 137 +++++++++++ .../apache/airavata/restapi/dto/BatchQueueDTO.java | 146 ++++++++++++ .../airavata/restapi/dto/ComputeResourceDTO.java | 175 ++++++++++++++ .../airavata/restapi/dto/ResourceNameDTO.java | 55 +++++ .../airavata/restapi/dto/StorageResourceDTO.java | 83 +++++++ .../airavata/restapi/service/ResourceService.java | 262 +++++++++++++++++++++ .../src/main/resources/application.properties | 5 + .../src/main/resources/log4j2.xml | 38 +++ pom.xml | 1 + 14 files changed, 1397 insertions(+) diff --git a/modules/airavata-rest-api/pom.xml b/modules/airavata-rest-api/pom.xml new file mode 100644 index 0000000000..a1ba49be12 --- /dev/null +++ b/modules/airavata-rest-api/pom.xml @@ -0,0 +1,122 @@ +<!-- +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. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.airavata</groupId> + <artifactId>airavata</artifactId> + <version>0.21-SNAPSHOT</version> + <relativePath>../../../pom.xml</relativePath> + </parent> + + <artifactId>airavata-rest-api</artifactId> + <name>Airavata REST API</name> + + <properties> + <rest.api.dist.name>apache-airavata-rest-api-${project.version}</rest.api.dist.name> + </properties> + + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + <exclusions> + <exclusion> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-logging</artifactId> + </exclusion> + <exclusion> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + </exclusion> + <exclusion> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-core</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-log4j2</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + </dependency> + <dependency> + <groupId>jakarta.annotation</groupId> + <artifactId>jakarta.annotation-api</artifactId> + </dependency> + <dependency> + <groupId>org.apache.airavata</groupId> + <artifactId>airavata-api</artifactId> + <version>${project.version}</version> + <exclusions> + <exclusion> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + </exclusion> + <exclusion> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-core</artifactId> + </exclusion> + <exclusion> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + </exclusion> + </exclusions> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <release>17</release> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <systemPropertyVariables> + <log4j2.configurationFile>src/main/resources/log4j2.xml</log4j2.configurationFile> + </systemPropertyVariables> + </configuration> + </plugin> + </plugins> + <resources> + <resource> + <directory>src/main/resources</directory> + </resource> + </resources> + </build> + +</project> + + diff --git a/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/RestApiApplication.java b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/RestApiApplication.java new file mode 100644 index 0000000000..1dbfeae112 --- /dev/null +++ b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/RestApiApplication.java @@ -0,0 +1,34 @@ +/** +* +* 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.restapi; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.context.properties.EnableConfigurationProperties; + +@SpringBootApplication +@EnableConfigurationProperties(RestApiConfiguration.class) +public class RestApiApplication { + public static void main(String[] args) { + SpringApplication.run(RestApiApplication.class, args); + } +} + + diff --git a/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/RestApiConfiguration.java b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/RestApiConfiguration.java new file mode 100644 index 0000000000..ee24e01f4f --- /dev/null +++ b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/RestApiConfiguration.java @@ -0,0 +1,53 @@ +/** +* +* 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.restapi; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +@Component +@ConfigurationProperties +public class RestApiConfiguration { + + @Value("${rest.api.server.port:8080}") + private int serverPort; + + @Value("${rest.api.server.host:0.0.0.0}") + private String serverHost; + + public int getServerPort() { + return serverPort; + } + + public void setServerPort(int serverPort) { + this.serverPort = serverPort; + } + + public String getServerHost() { + return serverHost; + } + + public void setServerHost(String serverHost) { + this.serverHost = serverHost; + } +} + + diff --git a/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/config/WebConfig.java b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/config/WebConfig.java new file mode 100644 index 0000000000..70f99addac --- /dev/null +++ b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/config/WebConfig.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.restapi.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class WebConfig implements WebMvcConfigurer { + + @Override + public void addCorsMappings(CorsRegistry registry) { + registry.addMapping("/api/**") + .allowedOrigins("*") + .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") + .allowedHeaders("*") + .allowCredentials(false); + } +} + + + diff --git a/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/controller/ComputeResourceController.java b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/controller/ComputeResourceController.java new file mode 100644 index 0000000000..b8877f83e0 --- /dev/null +++ b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/controller/ComputeResourceController.java @@ -0,0 +1,246 @@ +/** +* +* 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.restapi.controller; + +import java.util.List; +import java.util.Map; + +import org.apache.airavata.registry.cpi.AppCatalogException; +import org.apache.airavata.restapi.dto.BatchQueueDTO; +import org.apache.airavata.restapi.dto.ComputeResourceDTO; +import org.apache.airavata.restapi.service.ResourceService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/api/v1/compute-resources") +public class ComputeResourceController { + + private static final Logger logger = LoggerFactory.getLogger(ComputeResourceController.class); + private final ResourceService resourceService; + + public ComputeResourceController(ResourceService resourceService) { + this.resourceService = resourceService; + } + + @PostMapping + public ResponseEntity<?> registerComputeResource(@RequestBody ComputeResourceDTO dto) { + try { + String resourceId = resourceService.registerComputeResource(dto); + return ResponseEntity.status(HttpStatus.CREATED).body(Map.of("computeResourceId", resourceId)); + } catch (AppCatalogException e) { + logger.error("Error registering compute resource", e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Map.of("error", e.getMessage())); + } catch (Exception e) { + logger.error("Unexpected error registering compute resource", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("error", "Internal server error")); + } + } + + @GetMapping + public ResponseEntity<?> getAllComputeResourceNames() { + try { + List<Map<String, String>> resources = resourceService.getAllComputeResourceNames(); + return ResponseEntity.ok(resources); + } catch (AppCatalogException e) { + logger.error("Error getting compute resources", e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Map.of("error", e.getMessage())); + } catch (Exception e) { + logger.error("Unexpected error getting compute resources", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("error", "Internal server error")); + } + } + + @GetMapping("/{id}") + public ResponseEntity<?> getComputeResource(@PathVariable String id) { + try { + ComputeResourceDTO resource = resourceService.getComputeResource(id); + return ResponseEntity.ok(resource); + } catch (AppCatalogException e) { + logger.error("Error getting compute resource: " + id, e); + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Map.of("error", e.getMessage())); + } catch (Exception e) { + logger.error("Unexpected error getting compute resource: " + id, e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("error", "Internal server error")); + } + } + + @PutMapping("/{id}") + public ResponseEntity<?> updateComputeResource(@PathVariable String id, @RequestBody ComputeResourceDTO dto) { + try { + boolean updated = resourceService.updateComputeResource(id, dto); + if (updated) { + return ResponseEntity.ok(Map.of("message", "Compute resource updated successfully")); + } else { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Map.of("error", "Compute resource not found")); + } + } catch (AppCatalogException e) { + logger.error("Error updating compute resource: " + id, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Map.of("error", e.getMessage())); + } catch (Exception e) { + logger.error("Unexpected error updating compute resource: " + id, e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("error", "Internal server error")); + } + } + + @DeleteMapping("/{id}") + public ResponseEntity<?> deleteComputeResource(@PathVariable String id) { + try { + boolean deleted = resourceService.deleteComputeResource(id); + if (deleted) { + return ResponseEntity.ok(Map.of("message", "Compute resource deleted successfully")); + } else { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Map.of("error", "Compute resource not found")); + } + } catch (AppCatalogException e) { + logger.error("Error deleting compute resource: " + id, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Map.of("error", e.getMessage())); + } catch (Exception e) { + logger.error("Unexpected error deleting compute resource: " + id, e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("error", "Internal server error")); + } + } + + @GetMapping("/{id}/queues") + public ResponseEntity<?> getBatchQueues(@PathVariable String id) { + try { + ComputeResourceDTO resource = resourceService.getComputeResource(id); + return ResponseEntity.ok(resource.getBatchQueues()); + } catch (AppCatalogException e) { + logger.error("Error getting batch queues for compute resource: " + id, e); + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Map.of("error", e.getMessage())); + } catch (Exception e) { + logger.error("Unexpected error getting batch queues for compute resource: " + id, e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("error", "Internal server error")); + } + } + + @PostMapping("/{id}/queues") + public ResponseEntity<?> addBatchQueue(@PathVariable String id, @RequestBody BatchQueueDTO queueDTO) { + try { + ComputeResourceDTO resource = resourceService.getComputeResource(id); + if (resource.getBatchQueues() == null) { + resource.setBatchQueues(new java.util.ArrayList<>()); + } + resource.getBatchQueues().add(queueDTO); + boolean updated = resourceService.updateComputeResource(id, resource); + if (updated) { + return ResponseEntity.status(HttpStatus.CREATED) + .body(Map.of("message", "Batch queue added successfully")); + } else { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Map.of("error", "Compute resource not found")); + } + } catch (AppCatalogException e) { + logger.error("Error adding batch queue to compute resource: " + id, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Map.of("error", e.getMessage())); + } catch (Exception e) { + logger.error("Unexpected error adding batch queue to compute resource: " + id, e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("error", "Internal server error")); + } + } + + @PutMapping("/{id}/queues/{queueName}") + public ResponseEntity<?> updateBatchQueue(@PathVariable String id, @PathVariable String queueName, + @RequestBody BatchQueueDTO queueDTO) { + try { + ComputeResourceDTO resource = resourceService.getComputeResource(id); + if (resource.getBatchQueues() != null) { + for (int i = 0; i < resource.getBatchQueues().size(); i++) { + if (resource.getBatchQueues().get(i).getQueueName().equals(queueName)) { + resource.getBatchQueues().set(i, queueDTO); + boolean updated = resourceService.updateComputeResource(id, resource); + if (updated) { + return ResponseEntity.ok(Map.of("message", "Batch queue updated successfully")); + } else { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Map.of("error", "Compute resource not found")); + } + } + } + } + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Map.of("error", "Batch queue not found")); + } catch (AppCatalogException e) { + logger.error("Error updating batch queue: " + queueName + " for compute resource: " + id, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Map.of("error", e.getMessage())); + } catch (Exception e) { + logger.error("Unexpected error updating batch queue: " + queueName + " for compute resource: " + id, e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("error", "Internal server error")); + } + } + + @DeleteMapping("/{id}/queues/{queueName}") + public ResponseEntity<?> deleteBatchQueue(@PathVariable String id, @PathVariable String queueName) { + try { + ComputeResourceDTO resource = resourceService.getComputeResource(id); + if (resource.getBatchQueues() != null) { + boolean removed = resource.getBatchQueues().removeIf(q -> q.getQueueName().equals(queueName)); + if (removed) { + boolean updated = resourceService.updateComputeResource(id, resource); + if (updated) { + return ResponseEntity.ok(Map.of("message", "Batch queue deleted successfully")); + } else { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Map.of("error", "Compute resource not found")); + } + } + } + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Map.of("error", "Batch queue not found")); + } catch (AppCatalogException e) { + logger.error("Error deleting batch queue: " + queueName + " from compute resource: " + id, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Map.of("error", e.getMessage())); + } catch (Exception e) { + logger.error("Unexpected error deleting batch queue: " + queueName + " from compute resource: " + id, e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("error", "Internal server error")); + } + } +} diff --git a/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/controller/StorageResourceController.java b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/controller/StorageResourceController.java new file mode 100644 index 0000000000..b64dc6f873 --- /dev/null +++ b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/controller/StorageResourceController.java @@ -0,0 +1,137 @@ +/** +* +* 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.restapi.controller; + +import org.apache.airavata.restapi.dto.StorageResourceDTO; +import org.apache.airavata.restapi.service.ResourceService; +import org.apache.airavata.service.exception.AppCatalogException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/api/v1/storage-resources") +public class StorageResourceController { + + private static final Logger logger = LoggerFactory.getLogger(StorageResourceController.class); + private final ResourceService resourceService; + + public StorageResourceController(ResourceService resourceService) { + this.resourceService = resourceService; + } + + @PostMapping + public ResponseEntity<?> registerStorageResource(@RequestBody StorageResourceDTO dto) { + try { + String resourceId = resourceService.registerStorageResource(dto); + return ResponseEntity.status(HttpStatus.CREATED).body(Map.of("storageResourceId", resourceId)); + } catch (AppCatalogException e) { + logger.error("Error registering storage resource", e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Map.of("error", e.getMessage())); + } catch (Exception e) { + logger.error("Unexpected error registering storage resource", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("error", "Internal server error")); + } + } + + @GetMapping + public ResponseEntity<?> getAllStorageResourceNames() { + try { + List<Map<String, String>> resources = resourceService.getAllStorageResourceNames(); + return ResponseEntity.ok(resources); + } catch (AppCatalogException e) { + logger.error("Error getting storage resources", e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Map.of("error", e.getMessage())); + } catch (Exception e) { + logger.error("Unexpected error getting storage resources", e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("error", "Internal server error")); + } + } + + @GetMapping("/{id}") + public ResponseEntity<?> getStorageResource(@PathVariable String id) { + try { + StorageResourceDTO resource = resourceService.getStorageResource(id); + return ResponseEntity.ok(resource); + } catch (AppCatalogException e) { + logger.error("Error getting storage resource: " + id, e); + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Map.of("error", e.getMessage())); + } catch (Exception e) { + logger.error("Unexpected error getting storage resource: " + id, e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("error", "Internal server error")); + } + } + + @PutMapping("/{id}") + public ResponseEntity<?> updateStorageResource(@PathVariable String id, @RequestBody StorageResourceDTO dto) { + try { + boolean updated = resourceService.updateStorageResource(id, dto); + if (updated) { + return ResponseEntity.ok(Map.of("message", "Storage resource updated successfully")); + } else { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Map.of("error", "Storage resource not found")); + } + } catch (AppCatalogException e) { + logger.error("Error updating storage resource: " + id, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Map.of("error", e.getMessage())); + } catch (Exception e) { + logger.error("Unexpected error updating storage resource: " + id, e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("error", "Internal server error")); + } + } + + @DeleteMapping("/{id}") + public ResponseEntity<?> deleteStorageResource(@PathVariable String id) { + try { + boolean deleted = resourceService.deleteStorageResource(id); + if (deleted) { + return ResponseEntity.ok(Map.of("message", "Storage resource deleted successfully")); + } else { + return ResponseEntity.status(HttpStatus.NOT_FOUND) + .body(Map.of("error", "Storage resource not found")); + } + } catch (AppCatalogException e) { + logger.error("Error deleting storage resource: " + id, e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST) + .body(Map.of("error", e.getMessage())); + } catch (Exception e) { + logger.error("Unexpected error deleting storage resource: " + id, e); + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) + .body(Map.of("error", "Internal server error")); + } + } +} + + + diff --git a/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/dto/BatchQueueDTO.java b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/dto/BatchQueueDTO.java new file mode 100644 index 0000000000..2e1099a199 --- /dev/null +++ b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/dto/BatchQueueDTO.java @@ -0,0 +1,146 @@ +/** +* +* 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.restapi.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public class BatchQueueDTO { + private String queueName; + private String queueDescription; + private Integer maxRunTime; + private Integer maxNodes; + private Integer maxProcessors; + private Integer maxJobsInQueue; + private Integer maxMemory; + private Integer cpuPerNode; + private Integer defaultNodeCount; + private Integer defaultCPUCount; + private Integer defaultWalltime; + private String queueSpecificMacros; + private Boolean isDefaultQueue; + + public String getQueueName() { + return queueName; + } + + public void setQueueName(String queueName) { + this.queueName = queueName; + } + + public String getQueueDescription() { + return queueDescription; + } + + public void setQueueDescription(String queueDescription) { + this.queueDescription = queueDescription; + } + + public Integer getMaxRunTime() { + return maxRunTime; + } + + public void setMaxRunTime(Integer maxRunTime) { + this.maxRunTime = maxRunTime; + } + + public Integer getMaxNodes() { + return maxNodes; + } + + public void setMaxNodes(Integer maxNodes) { + this.maxNodes = maxNodes; + } + + public Integer getMaxProcessors() { + return maxProcessors; + } + + public void setMaxProcessors(Integer maxProcessors) { + this.maxProcessors = maxProcessors; + } + + public Integer getMaxJobsInQueue() { + return maxJobsInQueue; + } + + public void setMaxJobsInQueue(Integer maxJobsInQueue) { + this.maxJobsInQueue = maxJobsInQueue; + } + + public Integer getMaxMemory() { + return maxMemory; + } + + public void setMaxMemory(Integer maxMemory) { + this.maxMemory = maxMemory; + } + + public Integer getCpuPerNode() { + return cpuPerNode; + } + + public void setCpuPerNode(Integer cpuPerNode) { + this.cpuPerNode = cpuPerNode; + } + + public Integer getDefaultNodeCount() { + return defaultNodeCount; + } + + public void setDefaultNodeCount(Integer defaultNodeCount) { + this.defaultNodeCount = defaultNodeCount; + } + + public Integer getDefaultCPUCount() { + return defaultCPUCount; + } + + public void setDefaultCPUCount(Integer defaultCPUCount) { + this.defaultCPUCount = defaultCPUCount; + } + + public Integer getDefaultWalltime() { + return defaultWalltime; + } + + public void setDefaultWalltime(Integer defaultWalltime) { + this.defaultWalltime = defaultWalltime; + } + + public String getQueueSpecificMacros() { + return queueSpecificMacros; + } + + public void setQueueSpecificMacros(String queueSpecificMacros) { + this.queueSpecificMacros = queueSpecificMacros; + } + + public Boolean getIsDefaultQueue() { + return isDefaultQueue; + } + + public void setIsDefaultQueue(Boolean isDefaultQueue) { + this.isDefaultQueue = isDefaultQueue; + } +} + + + diff --git a/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/dto/ComputeResourceDTO.java b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/dto/ComputeResourceDTO.java new file mode 100644 index 0000000000..805c906a2d --- /dev/null +++ b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/dto/ComputeResourceDTO.java @@ -0,0 +1,175 @@ +/** +* +* 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.restapi.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import java.util.List; +import java.util.Map; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public class ComputeResourceDTO { + private String computeResourceId; + private String hostName; + private List<String> hostAliases; + private List<String> ipAddresses; + private String resourceDescription; + private Boolean enabled; + private List<BatchQueueDTO> batchQueues; + private Map<String, String> fileSystems; + private Integer maxMemoryPerNode; + private Boolean gatewayUsageReporting; + private String gatewayUsageModuleLoadCommand; + private String gatewayUsageExecutable; + private Integer cpusPerNode; + private Integer defaultNodeCount; + private Integer defaultCPUCount; + private Integer defaultWalltime; + + public String getComputeResourceId() { + return computeResourceId; + } + + public void setComputeResourceId(String computeResourceId) { + this.computeResourceId = computeResourceId; + } + + public String getHostName() { + return hostName; + } + + public void setHostName(String hostName) { + this.hostName = hostName; + } + + public List<String> getHostAliases() { + return hostAliases; + } + + public void setHostAliases(List<String> hostAliases) { + this.hostAliases = hostAliases; + } + + public List<String> getIpAddresses() { + return ipAddresses; + } + + public void setIpAddresses(List<String> ipAddresses) { + this.ipAddresses = ipAddresses; + } + + public String getResourceDescription() { + return resourceDescription; + } + + public void setResourceDescription(String resourceDescription) { + this.resourceDescription = resourceDescription; + } + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public List<BatchQueueDTO> getBatchQueues() { + return batchQueues; + } + + public void setBatchQueues(List<BatchQueueDTO> batchQueues) { + this.batchQueues = batchQueues; + } + + public Map<String, String> getFileSystems() { + return fileSystems; + } + + public void setFileSystems(Map<String, String> fileSystems) { + this.fileSystems = fileSystems; + } + + public Integer getMaxMemoryPerNode() { + return maxMemoryPerNode; + } + + public void setMaxMemoryPerNode(Integer maxMemoryPerNode) { + this.maxMemoryPerNode = maxMemoryPerNode; + } + + public Boolean getGatewayUsageReporting() { + return gatewayUsageReporting; + } + + public void setGatewayUsageReporting(Boolean gatewayUsageReporting) { + this.gatewayUsageReporting = gatewayUsageReporting; + } + + public String getGatewayUsageModuleLoadCommand() { + return gatewayUsageModuleLoadCommand; + } + + public void setGatewayUsageModuleLoadCommand(String gatewayUsageModuleLoadCommand) { + this.gatewayUsageModuleLoadCommand = gatewayUsageModuleLoadCommand; + } + + public String getGatewayUsageExecutable() { + return gatewayUsageExecutable; + } + + public void setGatewayUsageExecutable(String gatewayUsageExecutable) { + this.gatewayUsageExecutable = gatewayUsageExecutable; + } + + public Integer getCpusPerNode() { + return cpusPerNode; + } + + public void setCpusPerNode(Integer cpusPerNode) { + this.cpusPerNode = cpusPerNode; + } + + public Integer getDefaultNodeCount() { + return defaultNodeCount; + } + + public void setDefaultNodeCount(Integer defaultNodeCount) { + this.defaultNodeCount = defaultNodeCount; + } + + public Integer getDefaultCPUCount() { + return defaultCPUCount; + } + + public void setDefaultCPUCount(Integer defaultCPUCount) { + this.defaultCPUCount = defaultCPUCount; + } + + public Integer getDefaultWalltime() { + return defaultWalltime; + } + + public void setDefaultWalltime(Integer defaultWalltime) { + this.defaultWalltime = defaultWalltime; + } +} + + + diff --git a/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/dto/ResourceNameDTO.java b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/dto/ResourceNameDTO.java new file mode 100644 index 0000000000..c3b180fda8 --- /dev/null +++ b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/dto/ResourceNameDTO.java @@ -0,0 +1,55 @@ +/** +* +* 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.restapi.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public class ResourceNameDTO { + private String id; + private String name; + + public ResourceNameDTO() { + } + + public ResourceNameDTO(String id, String name) { + this.id = id; + this.name = name; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} + + + diff --git a/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/dto/StorageResourceDTO.java b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/dto/StorageResourceDTO.java new file mode 100644 index 0000000000..4a769f6f7c --- /dev/null +++ b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/dto/StorageResourceDTO.java @@ -0,0 +1,83 @@ +/** +* +* 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.restapi.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; + +@JsonInclude(JsonInclude.Include.NON_NULL) +public class StorageResourceDTO { + private String storageResourceId; + private String hostName; + private String storageResourceDescription; + private Boolean enabled; + private Long creationTime; + private Long updateTime; + + public String getStorageResourceId() { + return storageResourceId; + } + + public void setStorageResourceId(String storageResourceId) { + this.storageResourceId = storageResourceId; + } + + public String getHostName() { + return hostName; + } + + public void setHostName(String hostName) { + this.hostName = hostName; + } + + public String getStorageResourceDescription() { + return storageResourceDescription; + } + + public void setStorageResourceDescription(String storageResourceDescription) { + this.storageResourceDescription = storageResourceDescription; + } + + public Boolean getEnabled() { + return enabled; + } + + public void setEnabled(Boolean enabled) { + this.enabled = enabled; + } + + public Long getCreationTime() { + return creationTime; + } + + public void setCreationTime(Long creationTime) { + this.creationTime = creationTime; + } + + public Long getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Long updateTime) { + this.updateTime = updateTime; + } +} + + + diff --git a/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/service/ResourceService.java b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/service/ResourceService.java new file mode 100644 index 0000000000..a0409f47d2 --- /dev/null +++ b/modules/airavata-rest-api/src/main/java/org/apache/airavata/restapi/service/ResourceService.java @@ -0,0 +1,262 @@ +/** +* +* 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.restapi.service; + +import org.apache.airavata.model.appcatalog.computeresource.BatchQueue; +import org.apache.airavata.model.appcatalog.computeresource.ComputeResourceDescription; +import org.apache.airavata.model.appcatalog.storageresource.StorageResourceDescription; +import org.apache.airavata.restapi.dto.BatchQueueDTO; +import org.apache.airavata.restapi.dto.ComputeResourceDTO; +import org.apache.airavata.restapi.dto.StorageResourceDTO; +import org.apache.airavata.service.AiravataService; +import org.apache.airavata.service.exception.AppCatalogException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@Service +public class ResourceService { + + private static final Logger logger = LoggerFactory.getLogger(ResourceService.class); + private final AiravataService airavataService; + + public ResourceService() { + this.airavataService = new AiravataService(); + } + + // Compute Resource methods + public String registerComputeResource(ComputeResourceDTO dto) throws AppCatalogException { + ComputeResourceDescription description = convertToComputeResourceDescription(dto); + return airavataService.registerComputeResource(description); + } + + public ComputeResourceDTO getComputeResource(String computeResourceId) throws AppCatalogException { + ComputeResourceDescription description = airavataService.getComputeResource(computeResourceId); + return convertToComputeResourceDTO(description); + } + + public boolean updateComputeResource(String computeResourceId, ComputeResourceDTO dto) throws AppCatalogException { + ComputeResourceDescription description = convertToComputeResourceDescription(dto); + return airavataService.updateComputeResource(computeResourceId, description); + } + + public boolean deleteComputeResource(String computeResourceId) throws AppCatalogException { + return airavataService.deleteComputeResource(computeResourceId); + } + + public List<Map<String, String>> getAllComputeResourceNames() throws AppCatalogException { + Map<String, String> names = airavataService.getAllComputeResourceNames(); + return names.entrySet().stream() + .map(entry -> { + Map<String, String> map = new HashMap<>(); + map.put("id", entry.getKey()); + map.put("name", entry.getValue()); + return map; + }) + .collect(Collectors.toList()); + } + + // Storage Resource methods + public String registerStorageResource(StorageResourceDTO dto) throws AppCatalogException { + StorageResourceDescription description = convertToStorageResourceDescription(dto); + return airavataService.registerStorageResource(description); + } + + public StorageResourceDTO getStorageResource(String storageResourceId) throws AppCatalogException { + StorageResourceDescription description = airavataService.getStorageResource(storageResourceId); + return convertToStorageResourceDTO(description); + } + + public boolean updateStorageResource(String storageResourceId, StorageResourceDTO dto) throws AppCatalogException { + StorageResourceDescription description = convertToStorageResourceDescription(dto); + return airavataService.updateStorageResource(storageResourceId, description); + } + + public boolean deleteStorageResource(String storageResourceId) throws AppCatalogException { + return airavataService.deleteStorageResource(storageResourceId); + } + + public List<Map<String, String>> getAllStorageResourceNames() throws AppCatalogException { + Map<String, String> names = airavataService.getAllStorageResourceNames(); + return names.entrySet().stream() + .map(entry -> { + Map<String, String> map = new HashMap<>(); + map.put("id", entry.getKey()); + map.put("name", entry.getValue()); + return map; + }) + .collect(Collectors.toList()); + } + + // Conversion methods + private ComputeResourceDescription convertToComputeResourceDescription(ComputeResourceDTO dto) { + ComputeResourceDescription description = new ComputeResourceDescription(); + if (dto.getComputeResourceId() != null && !dto.getComputeResourceId().equals("DO_NOT_SET_AT_CLIENTS")) { + description.setComputeResourceId(dto.getComputeResourceId()); + } else { + description.setComputeResourceId("DO_NOT_SET_AT_CLIENTS"); + } + description.setHostName(dto.getHostName()); + if (dto.getHostAliases() != null) { + description.setHostAliases(dto.getHostAliases()); + } + if (dto.getIpAddresses() != null) { + description.setIpAddresses(dto.getIpAddresses()); + } + description.setResourceDescription(dto.getResourceDescription()); + description.setEnabled(dto.getEnabled()); + if (dto.getBatchQueues() != null) { + List<BatchQueue> queues = new ArrayList<>(); + for (BatchQueueDTO queueDTO : dto.getBatchQueues()) { + queues.add(convertToBatchQueue(queueDTO)); + } + description.setBatchQueues(queues); + } + if (dto.getFileSystems() != null) { + Map<org.apache.airavata.model.appcatalog.computeresource.FileSystems, String> fileSystems = new HashMap<>(); + for (Map.Entry<String, String> entry : dto.getFileSystems().entrySet()) { + try { + org.apache.airavata.model.appcatalog.computeresource.FileSystems fs = + org.apache.airavata.model.appcatalog.computeresource.FileSystems.valueOf(entry.getKey()); + fileSystems.put(fs, entry.getValue()); + } catch (IllegalArgumentException e) { + logger.warn("Invalid file system type: " + entry.getKey()); + } + } + description.setFileSystems(fileSystems); + } + description.setMaxMemoryPerNode(dto.getMaxMemoryPerNode()); + description.setGatewayUsageReporting(dto.getGatewayUsageReporting()); + description.setGatewayUsageModuleLoadCommand(dto.getGatewayUsageModuleLoadCommand()); + description.setGatewayUsageExecutable(dto.getGatewayUsageExecutable()); + description.setCpusPerNode(dto.getCpusPerNode()); + description.setDefaultNodeCount(dto.getDefaultNodeCount()); + description.setDefaultCPUCount(dto.getDefaultCPUCount()); + description.setDefaultWalltime(dto.getDefaultWalltime()); + return description; + } + + private ComputeResourceDTO convertToComputeResourceDTO(ComputeResourceDescription description) { + ComputeResourceDTO dto = new ComputeResourceDTO(); + dto.setComputeResourceId(description.getComputeResourceId()); + dto.setHostName(description.getHostName()); + dto.setHostAliases(description.getHostAliases()); + dto.setIpAddresses(description.getIpAddresses()); + dto.setResourceDescription(description.getResourceDescription()); + dto.setEnabled(description.isEnabled()); + if (description.getBatchQueues() != null) { + List<BatchQueueDTO> queues = new ArrayList<>(); + for (BatchQueue queue : description.getBatchQueues()) { + queues.add(convertToBatchQueueDTO(queue)); + } + dto.setBatchQueues(queues); + } + if (description.getFileSystems() != null) { + Map<String, String> fileSystems = new HashMap<>(); + for (Map.Entry<org.apache.airavata.model.appcatalog.computeresource.FileSystems, String> entry : + description.getFileSystems().entrySet()) { + fileSystems.put(entry.getKey().name(), entry.getValue()); + } + dto.setFileSystems(fileSystems); + } + dto.setMaxMemoryPerNode(description.getMaxMemoryPerNode()); + dto.setGatewayUsageReporting(description.isGatewayUsageReporting()); + dto.setGatewayUsageModuleLoadCommand(description.getGatewayUsageModuleLoadCommand()); + dto.setGatewayUsageExecutable(description.getGatewayUsageExecutable()); + dto.setCpusPerNode(description.getCpusPerNode()); + dto.setDefaultNodeCount(description.getDefaultNodeCount()); + dto.setDefaultCPUCount(description.getDefaultCPUCount()); + dto.setDefaultWalltime(description.getDefaultWalltime()); + return dto; + } + + private BatchQueue convertToBatchQueue(BatchQueueDTO dto) { + BatchQueue queue = new BatchQueue(); + queue.setQueueName(dto.getQueueName()); + queue.setQueueDescription(dto.getQueueDescription()); + queue.setMaxRunTime(dto.getMaxRunTime()); + queue.setMaxNodes(dto.getMaxNodes()); + queue.setMaxProcessors(dto.getMaxProcessors()); + queue.setMaxJobsInQueue(dto.getMaxJobsInQueue()); + queue.setMaxMemory(dto.getMaxMemory()); + queue.setCpuPerNode(dto.getCpuPerNode()); + queue.setDefaultNodeCount(dto.getDefaultNodeCount()); + queue.setDefaultCPUCount(dto.getDefaultCPUCount()); + queue.setDefaultWalltime(dto.getDefaultWalltime()); + queue.setQueueSpecificMacros(dto.getQueueSpecificMacros()); + queue.setIsDefaultQueue(dto.getIsDefaultQueue()); + return queue; + } + + private BatchQueueDTO convertToBatchQueueDTO(BatchQueue queue) { + BatchQueueDTO dto = new BatchQueueDTO(); + dto.setQueueName(queue.getQueueName()); + dto.setQueueDescription(queue.getQueueDescription()); + dto.setMaxRunTime(queue.getMaxRunTime()); + dto.setMaxNodes(queue.getMaxNodes()); + dto.setMaxProcessors(queue.getMaxProcessors()); + dto.setMaxJobsInQueue(queue.getMaxJobsInQueue()); + dto.setMaxMemory(queue.getMaxMemory()); + dto.setCpuPerNode(queue.getCpuPerNode()); + dto.setDefaultNodeCount(queue.getDefaultNodeCount()); + dto.setDefaultCPUCount(queue.getDefaultCPUCount()); + dto.setDefaultWalltime(queue.getDefaultWalltime()); + dto.setQueueSpecificMacros(queue.getQueueSpecificMacros()); + dto.setIsDefaultQueue(queue.isIsDefaultQueue()); + return dto; + } + + private StorageResourceDescription convertToStorageResourceDescription(StorageResourceDTO dto) { + StorageResourceDescription description = new StorageResourceDescription(); + if (dto.getStorageResourceId() != null && !dto.getStorageResourceId().equals("DO_NOT_SET_AT_CLIENTS")) { + description.setStorageResourceId(dto.getStorageResourceId()); + } else { + description.setStorageResourceId("DO_NOT_SET_AT_CLIENTS"); + } + description.setHostName(dto.getHostName()); + description.setStorageResourceDescription(dto.getStorageResourceDescription()); + description.setEnabled(dto.getEnabled()); + return description; + } + + private StorageResourceDTO convertToStorageResourceDTO(StorageResourceDescription description) { + StorageResourceDTO dto = new StorageResourceDTO(); + dto.setStorageResourceId(description.getStorageResourceId()); + dto.setHostName(description.getHostName()); + dto.setStorageResourceDescription(description.getStorageResourceDescription()); + dto.setEnabled(description.isEnabled()); + if (description.getCreationTime() != null) { + dto.setCreationTime(description.getCreationTime()); + } + if (description.getUpdateTime() != null) { + dto.setUpdateTime(description.getUpdateTime()); + } + return dto; + } +} + + + diff --git a/modules/airavata-rest-api/src/main/resources/application.properties b/modules/airavata-rest-api/src/main/resources/application.properties new file mode 100644 index 0000000000..a7409a470a --- /dev/null +++ b/modules/airavata-rest-api/src/main/resources/application.properties @@ -0,0 +1,5 @@ +rest.api.server.port=8080 +rest.api.server.host=0.0.0.0 + + + diff --git a/modules/airavata-rest-api/src/main/resources/log4j2.xml b/modules/airavata-rest-api/src/main/resources/log4j2.xml new file mode 100644 index 0000000000..5385140ef7 --- /dev/null +++ b/modules/airavata-rest-api/src/main/resources/log4j2.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +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. +--> +<Configuration status="WARN"> + <Appenders> + <Console name="Console" target="SYSTEM_OUT"> + <PatternLayout pattern="%d [%t] %-5p %c{30} %X - %m%n" /> + </Console> + </Appenders> + <Loggers> + <logger name="ch.qos.logback" level="WARN" /> + <logger name="org.apache.helix" level="WARN" /> + <logger name="org.apache.zookeeper" level="ERROR" /> + <logger name="org.apache.airavata" level="INFO" /> + <logger name="org.hibernate" level="ERROR" /> + <Root level="INFO"> + <AppenderRef ref="Console" /> + </Root> + </Loggers> +</Configuration> + + diff --git a/pom.xml b/pom.xml index 2d860dc471..16496dc0fe 100644 --- a/pom.xml +++ b/pom.xml @@ -73,6 +73,7 @@ under the License. <module>modules/agent-framework/agent-service</module> <module>modules/research-framework/research-service</module> <module>modules/restproxy</module> + <module>modules/airavata-rest-api</module> <module>modules/registry-db-migrator</module> <module>modules/registry-jpa-generator</module> <module>modules/ide-integration</module>
