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>

Reply via email to