You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by di...@apache.org on 2019/11/08 13:50:31 UTC

[airavata-custos] branch develop updated: Rest API initial commit

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

dimuthuupe pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/airavata-custos.git


The following commit(s) were added to refs/heads/develop by this push:
     new aee42eb  Rest API initial commit
aee42eb is described below

commit aee42eb1868bd1edef1bf3349fc044489472d31e
Author: Dimuthu Wannipurage <di...@gmail.com>
AuthorDate: Fri Nov 8 08:50:16 2019 -0500

    Rest API initial commit
---
 custos-rest-api/pom.xml                            |  64 +++++++
 .../custos/rest/controller/AuthController.java     |   6 +
 .../custos/rest/controller/CILogonController.java  |  15 ++
 .../custos/rest/controller/TenantController.java   |  78 +++++++++
 .../org/apache/custos/rest/core/AppConfig.java     |  43 +++++
 .../org/apache/custos/rest/core/Application.java   |  34 ++++
 .../org/apache/custos/rest/filters/AuthFilter.java |  39 +++++
 .../custos/rest/resources/GatewayResource.java     | 184 +++++++++++++++++++++
 ide-integration/custos-services/pom.xml            |  27 ++-
 .../src/main/assembly/custos-bin-assembly.xml      |  87 ++++++++++
 .../src/main/resources/custos/bin/custos-daemon.sh | 113 +++++++++++++
 .../src/main/resources/custos/bin/custos.sh        |  71 ++++++++
 .../src/main/resources/custos/bin/setenv.sh        |  46 ++++++
 .../src/main/resources/custos/conf/logback.xml     |  53 ++++++
 pom.xml                                            |   1 +
 15 files changed, 860 insertions(+), 1 deletion(-)

diff --git a/custos-rest-api/pom.xml b/custos-rest-api/pom.xml
new file mode 100644
index 0000000..0b28150
--- /dev/null
+++ b/custos-rest-api/pom.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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">
+    <parent>
+        <artifactId>custos</artifactId>
+        <groupId>org.apache.custos</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>custos-rest-api</artifactId>
+
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>tenant-profile-service</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.custos</groupId>
+            <artifactId>custos-client</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <version>2.1.6.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>net.sf.dozer</groupId>
+            <artifactId>dozer</artifactId>
+            <version>5.4.0</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.slf4j</groupId>
+                    <artifactId>slf4j-log4j12</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.keycloak</groupId>
+            <artifactId>keycloak-admin-client</artifactId>
+            <version>2.5.5.Final</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.fasterxml.jackson.core</groupId>
+                    <artifactId>jackson-core</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/custos-rest-api/src/main/java/org/apache/custos/rest/controller/AuthController.java b/custos-rest-api/src/main/java/org/apache/custos/rest/controller/AuthController.java
new file mode 100644
index 0000000..2fc6a66
--- /dev/null
+++ b/custos-rest-api/src/main/java/org/apache/custos/rest/controller/AuthController.java
@@ -0,0 +1,6 @@
+package org.apache.custos.rest.controller;
+
+public class AuthController {
+
+
+}
diff --git a/custos-rest-api/src/main/java/org/apache/custos/rest/controller/CILogonController.java b/custos-rest-api/src/main/java/org/apache/custos/rest/controller/CILogonController.java
new file mode 100644
index 0000000..7b411e9
--- /dev/null
+++ b/custos-rest-api/src/main/java/org/apache/custos/rest/controller/CILogonController.java
@@ -0,0 +1,15 @@
+package org.apache.custos.rest.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/cilogon")
+public class CILogonController {
+
+    @RequestMapping(value = "hello", method = RequestMethod.GET)
+    public String helloMethod() {
+        return "Hello";
+    }
+}
diff --git a/custos-rest-api/src/main/java/org/apache/custos/rest/controller/TenantController.java b/custos-rest-api/src/main/java/org/apache/custos/rest/controller/TenantController.java
new file mode 100644
index 0000000..adfc984
--- /dev/null
+++ b/custos-rest-api/src/main/java/org/apache/custos/rest/controller/TenantController.java
@@ -0,0 +1,78 @@
+package org.apache.custos.rest.controller;
+
+import org.apache.custos.client.profile.service.CustosProfileServiceClientFactory;
+import org.apache.custos.commons.model.security.AuthzToken;
+import org.apache.custos.profile.model.workspace.Gateway;
+import org.apache.custos.profile.tenant.cpi.TenantProfileService;
+import org.apache.custos.rest.resources.GatewayResource;
+import org.apache.thrift.TException;
+import org.dozer.DozerBeanMapper;
+import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
+import org.keycloak.admin.client.KeycloakBuilder;
+import org.keycloak.representations.idm.RealmRepresentation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.keycloak.admin.client.Keycloak;
+
+@RestController
+@RequestMapping("/tenant")
+public class TenantController {
+
+    @Autowired
+    private TenantProfileService.Client tenantClient;
+
+    @Autowired
+    private DozerBeanMapper mapper;
+
+    @Autowired
+    private Keycloak keycloakAdminClient;
+
+    private static AuthzToken authzToken = new AuthzToken("empy_token");
+
+    /*
+
+    Sample Request
+
+    POST
+    http://localhost:8080/tenant/
+
+        {
+          "gatewayId":"test-gateway-10",
+          "gatewayApprovalStatus":"APPROVED",
+          "gatewayName":"test-gateway-10",
+          "domain":"test-gateway-domain",
+          "emailAddress":"test-gateway-1@gmail.com",
+          "gatewayURL":"test-gateway-1.com",
+          "gatewayAdminFirstName":"John",
+          "gatewayAdminLastName":"Doe",
+          "gatewayAdminEmail":"admin.test-gateway-1@gmail.com"
+        }
+     */
+    @RequestMapping(value = "", method = RequestMethod.POST)
+    public String createTenant(@RequestBody GatewayResource gatewayResource) throws TException {
+
+        Gateway gatewayT = mapper.map(gatewayResource, Gateway.class);
+        Gateway gateway = tenantClient.addGateway(authzToken, gatewayT);
+        return gateway.getCustosInternalGatewayId();
+    }
+
+    /*
+    Sample Request
+
+    GET
+    Creating a realm on keycloak for above gateway
+        http://localhost:8080/tenant/realm/40e5be38-0fde-41fe-a846-13de8b2ecfec
+     */
+    @RequestMapping(value = "/realm/{tenant}", method = RequestMethod.POST)
+    public String createRealm(@PathVariable("tenant") String gateway) throws TException {
+        Gateway gatewayT = tenantClient.getGateway(authzToken, gateway);
+
+        RealmRepresentation realmRepresentation = new RealmRepresentation();
+        realmRepresentation.setRealm(gatewayT.getGatewayId());
+        keycloakAdminClient.realms().create(realmRepresentation);
+
+        return "Created";
+    }
+
+
+}
diff --git a/custos-rest-api/src/main/java/org/apache/custos/rest/core/AppConfig.java b/custos-rest-api/src/main/java/org/apache/custos/rest/core/AppConfig.java
new file mode 100644
index 0000000..48b607d
--- /dev/null
+++ b/custos-rest-api/src/main/java/org/apache/custos/rest/core/AppConfig.java
@@ -0,0 +1,43 @@
+package org.apache.custos.rest.core;
+
+import org.apache.custos.client.profile.service.CustosProfileServiceClientFactory;
+import org.apache.custos.profile.tenant.cpi.TenantProfileService;
+import org.apache.custos.profile.tenant.cpi.exception.TenantProfileServiceException;
+import org.dozer.DozerBeanMapper;
+import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
+import org.keycloak.admin.client.Keycloak;
+import org.keycloak.admin.client.KeycloakBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Configuration
+public class AppConfig {
+
+    // Use for future custom mapping scenarios https://www.java-success.com/dozer-with-spring-maven-tutorial/
+    @Bean
+    public DozerBeanMapper dozerBeanMapper() {
+        return new DozerBeanMapper();
+    }
+
+    @Bean
+    public TenantProfileService.Client tenantClient() throws TenantProfileServiceException {
+        return CustosProfileServiceClientFactory.createCustosTenantProfileServiceClient("iam.custos.scigap.org", 8081);
+    }
+
+    @Bean Keycloak keycloakAdminClient() {
+        ResteasyClientBuilder clientBuilder = new ResteasyClientBuilder()
+                .connectionPoolSize(10);
+
+        clientBuilder.disableTrustManager().hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY);
+        return KeycloakBuilder.builder()
+                .username("admin")
+                .realm("master")
+                .clientId("admin-cli")
+                .password("PASSWORD")
+                .resteasyClient(clientBuilder.build())
+                .serverUrl("https://iam.custos.scigap.org/auth").build();
+    }
+}
\ No newline at end of file
diff --git a/custos-rest-api/src/main/java/org/apache/custos/rest/core/Application.java b/custos-rest-api/src/main/java/org/apache/custos/rest/core/Application.java
new file mode 100644
index 0000000..aee1a65
--- /dev/null
+++ b/custos-rest-api/src/main/java/org/apache/custos/rest/core/Application.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.custos.rest.core;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+
+@SpringBootApplication
+@ComponentScan(basePackages = {"org.apache.custos"})
+public class Application {
+
+    public static void main(String[] args) {
+        SpringApplication.run(Application.class, args);
+    }
+}
\ No newline at end of file
diff --git a/custos-rest-api/src/main/java/org/apache/custos/rest/filters/AuthFilter.java b/custos-rest-api/src/main/java/org/apache/custos/rest/filters/AuthFilter.java
new file mode 100644
index 0000000..d3b989e
--- /dev/null
+++ b/custos-rest-api/src/main/java/org/apache/custos/rest/filters/AuthFilter.java
@@ -0,0 +1,39 @@
+package org.apache.custos.rest.filters;
+
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.util.Enumeration;
+
+@Component
+@Order(Ordered.HIGHEST_PRECEDENCE)
+public class AuthFilter implements Filter{
+
+    public AuthFilter() {}
+
+
+    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+        HttpServletResponse response = (HttpServletResponse) servletResponse;
+        HttpServletRequest request = (HttpServletRequest) servletRequest;
+
+        HttpServletRequest httpRequest = (HttpServletRequest) request;
+        Enumeration<String> headerNames = httpRequest.getHeaderNames();
+
+        if (headerNames != null) {
+            while (headerNames.hasMoreElements()) {
+                String name = headerNames.nextElement();
+                if ("authorization".equals(name)) {
+                    String headerValue = httpRequest.getHeader(name);
+                    // TODO Validate the authorization header
+                }
+            }
+        }
+
+        filterChain.doFilter(request, response);
+    }
+}
diff --git a/custos-rest-api/src/main/java/org/apache/custos/rest/resources/GatewayResource.java b/custos-rest-api/src/main/java/org/apache/custos/rest/resources/GatewayResource.java
new file mode 100644
index 0000000..60f9c79
--- /dev/null
+++ b/custos-rest-api/src/main/java/org/apache/custos/rest/resources/GatewayResource.java
@@ -0,0 +1,184 @@
+package org.apache.custos.rest.resources;
+
+public class GatewayResource {
+    private String custosInternalGatewayId; // optional
+    private String gatewayId; // required
+    private String gatewayApprovalStatus; // required
+    private String gatewayName; // optional
+    private String domain; // optional
+    private String emailAddress; // optional
+    private String gatewayAcronym; // optional
+    private String gatewayURL; // optional
+    private String gatewayPublicAbstract; // optional
+    private String reviewProposalDescription; // optional
+    private String gatewayAdminFirstName; // optional
+    private String gatewayAdminLastName; // optional
+    private String gatewayAdminEmail; // optional
+    private String identityServerUserName; // optional
+    private String identityServerPasswordToken; // optional
+    private String declinedReason; // optional
+    private String oauthClientId; // optional
+    private String oauthClientSecret; // optional
+    private long requestCreationTime; // optional
+    private String requesterUsername; // optional
+
+    public String getCustosInternalGatewayId() {
+        return custosInternalGatewayId;
+    }
+
+    public void setCustosInternalGatewayId(String custosInternalGatewayId) {
+        this.custosInternalGatewayId = custosInternalGatewayId;
+    }
+
+    public String getGatewayId() {
+        return gatewayId;
+    }
+
+    public void setGatewayId(String gatewayId) {
+        this.gatewayId = gatewayId;
+    }
+
+    public String getGatewayApprovalStatus() {
+        return gatewayApprovalStatus;
+    }
+
+    public void setGatewayApprovalStatus(String gatewayApprovalStatus) {
+        this.gatewayApprovalStatus = gatewayApprovalStatus;
+    }
+
+    public String getGatewayName() {
+        return gatewayName;
+    }
+
+    public void setGatewayName(String gatewayName) {
+        this.gatewayName = gatewayName;
+    }
+
+    public String getDomain() {
+        return domain;
+    }
+
+    public void setDomain(String domain) {
+        this.domain = domain;
+    }
+
+    public String getEmailAddress() {
+        return emailAddress;
+    }
+
+    public void setEmailAddress(String emailAddress) {
+        this.emailAddress = emailAddress;
+    }
+
+    public String getGatewayAcronym() {
+        return gatewayAcronym;
+    }
+
+    public void setGatewayAcronym(String gatewayAcronym) {
+        this.gatewayAcronym = gatewayAcronym;
+    }
+
+    public String getGatewayURL() {
+        return gatewayURL;
+    }
+
+    public void setGatewayURL(String gatewayURL) {
+        this.gatewayURL = gatewayURL;
+    }
+
+    public String getGatewayPublicAbstract() {
+        return gatewayPublicAbstract;
+    }
+
+    public void setGatewayPublicAbstract(String gatewayPublicAbstract) {
+        this.gatewayPublicAbstract = gatewayPublicAbstract;
+    }
+
+    public String getReviewProposalDescription() {
+        return reviewProposalDescription;
+    }
+
+    public void setReviewProposalDescription(String reviewProposalDescription) {
+        this.reviewProposalDescription = reviewProposalDescription;
+    }
+
+    public String getGatewayAdminFirstName() {
+        return gatewayAdminFirstName;
+    }
+
+    public void setGatewayAdminFirstName(String gatewayAdminFirstName) {
+        this.gatewayAdminFirstName = gatewayAdminFirstName;
+    }
+
+    public String getGatewayAdminLastName() {
+        return gatewayAdminLastName;
+    }
+
+    public void setGatewayAdminLastName(String gatewayAdminLastName) {
+        this.gatewayAdminLastName = gatewayAdminLastName;
+    }
+
+    public String getGatewayAdminEmail() {
+        return gatewayAdminEmail;
+    }
+
+    public void setGatewayAdminEmail(String gatewayAdminEmail) {
+        this.gatewayAdminEmail = gatewayAdminEmail;
+    }
+
+    public String getIdentityServerUserName() {
+        return identityServerUserName;
+    }
+
+    public void setIdentityServerUserName(String identityServerUserName) {
+        this.identityServerUserName = identityServerUserName;
+    }
+
+    public String getIdentityServerPasswordToken() {
+        return identityServerPasswordToken;
+    }
+
+    public void setIdentityServerPasswordToken(String identityServerPasswordToken) {
+        this.identityServerPasswordToken = identityServerPasswordToken;
+    }
+
+    public String getDeclinedReason() {
+        return declinedReason;
+    }
+
+    public void setDeclinedReason(String declinedReason) {
+        this.declinedReason = declinedReason;
+    }
+
+    public String getOauthClientId() {
+        return oauthClientId;
+    }
+
+    public void setOauthClientId(String oauthClientId) {
+        this.oauthClientId = oauthClientId;
+    }
+
+    public String getOauthClientSecret() {
+        return oauthClientSecret;
+    }
+
+    public void setOauthClientSecret(String oauthClientSecret) {
+        this.oauthClientSecret = oauthClientSecret;
+    }
+
+    public long getRequestCreationTime() {
+        return requestCreationTime;
+    }
+
+    public void setRequestCreationTime(long requestCreationTime) {
+        this.requestCreationTime = requestCreationTime;
+    }
+
+    public String getRequesterUsername() {
+        return requesterUsername;
+    }
+
+    public void setRequesterUsername(String requesterUsername) {
+        this.requesterUsername = requesterUsername;
+    }
+}
diff --git a/ide-integration/custos-services/pom.xml b/ide-integration/custos-services/pom.xml
index db15484..db7e0ba 100644
--- a/ide-integration/custos-services/pom.xml
+++ b/ide-integration/custos-services/pom.xml
@@ -11,5 +11,30 @@
 
     <artifactId>custos-services-start</artifactId>
 
-
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-assembly-plugin</artifactId>
+                <version>${maven.assembly.plugin}</version>
+                <executions>
+                    <execution>
+                        <id>custos-distribution-package</id>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>single</goal>
+                        </goals>
+                        <configuration>
+                            <tarLongFileMode>posix</tarLongFileMode>
+                            <finalName>custos</finalName>
+                            <descriptors>
+                                <descriptor>src/main/assembly/custos-bin-assembly.xml</descriptor>
+                            </descriptors>
+                            <attach>false</attach>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
\ No newline at end of file
diff --git a/ide-integration/custos-services/src/main/assembly/custos-bin-assembly.xml b/ide-integration/custos-services/src/main/assembly/custos-bin-assembly.xml
new file mode 100644
index 0000000..5060144
--- /dev/null
+++ b/ide-integration/custos-services/src/main/assembly/custos-bin-assembly.xml
@@ -0,0 +1,87 @@
+<!--
+
+    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.
+
+-->
+<!DOCTYPE assembly [
+        <!ELEMENT assembly (id|includeBaseDirectory|baseDirectory|formats|fileSets|dependencySets)*>
+        <!ELEMENT id (#PCDATA)>
+        <!ELEMENT includeBaseDirectory (#PCDATA)>
+        <!ELEMENT baseDirectory (#PCDATA)>
+        <!ELEMENT formats (format)*>
+        <!ELEMENT format (#PCDATA)>
+        <!ELEMENT fileSets (fileSet)*>
+        <!ELEMENT fileSet (directory|outputDirectory|fileMode|includes)*>
+        <!ELEMENT directory (#PCDATA)>
+        <!ELEMENT outputDirectory (#PCDATA)>
+        <!ELEMENT includes (include)*>
+        <!ELEMENT include (#PCDATA)>
+        <!ELEMENT dependencySets (dependencySet)*>
+        <!ELEMENT dependencySet (outputDirectory|outputFileNameMapping|includes)*>
+        ]>
+<assembly>
+    <id>bin</id>
+    <includeBaseDirectory>true</includeBaseDirectory>
+    <baseDirectory>custos</baseDirectory>
+    <formats>
+        <format>tar.gz</format>
+        <format>zip</format>
+    </formats>
+
+    <fileSets>
+        <fileSet>
+            <directory>src/main/resources/custos/bin</directory>
+            <outputDirectory>bin</outputDirectory>
+            <fileMode>777</fileMode>
+            <includes>
+                <include>*.sh</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>src/main/resources/custos/conf</directory>
+            <outputDirectory>conf</outputDirectory>
+            <includes>
+                <include>airavata-server.properties</include>
+                <include>logback.xml</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>./</directory>
+            <outputDirectory>logs</outputDirectory>
+            <excludes>
+                <exclude>*/**</exclude>
+            </excludes>
+        </fileSet>
+    </fileSets>
+
+    <dependencySets>
+        <dependencySet>
+            <useProjectArtifact>false</useProjectArtifact>
+            <outputDirectory>lib</outputDirectory>
+            <includes>
+                <include>org.apache.custos:custos-services-start:jar</include>
+                <include>*:*:jar</include>
+            </includes>
+            <excludes>
+                <exclude>mysql:mysql-connector-java:jar</exclude>
+                <exclude>log4j:log4j:jar</exclude>
+            </excludes>
+        </dependencySet>
+    </dependencySets>
+
+</assembly>
diff --git a/ide-integration/custos-services/src/main/resources/custos/bin/custos-daemon.sh b/ide-integration/custos-services/src/main/resources/custos/bin/custos-daemon.sh
new file mode 100644
index 0000000..67c4a40
--- /dev/null
+++ b/ide-integration/custos-services/src/main/resources/custos/bin/custos-daemon.sh
@@ -0,0 +1,113 @@
+#!/usr/bin/env bash
+
+# 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.
+
+. `dirname $0`/setenv.sh
+# Capture user's working dir before changing directory
+CWD="$PWD"
+cd ${AIRAVATA_HOME}/bin
+LOGO_FILE="logo.txt"
+
+JAVA_OPTS="-Dairavata.config.dir=${AIRAVATA_HOME}/conf -Dairavata.home=${AIRAVATA_HOME} -Dlogback.configurationFile=file:${AIRAVATA_HOME}/conf/logback.xml"
+AIRAVATA_COMMAND=""
+EXTRA_ARGS=""
+SERVERS=""
+LOGO=true
+IS_SUBSET=false
+SUBSET=""
+DEFAULT_LOG_FILE="${AIRAVATA_HOME}/logs/airavata-daemon.out"
+LOG_FILE=$DEFAULT_LOG_FILE
+
+SERVICE_NAME="Custos Server"
+PID_PATH_NAME="${AIRAVATA_HOME}/bin/service-pid"
+
+case $1 in
+    start)
+        echo "Starting $SERVICE_NAME ..."
+        if [ ! -f $PID_PATH_NAME ]; then
+            nohup java ${JAVA_OPTS} -classpath "${AIRAVATA_CLASSPATH}" \
+            org.apache.custos.server.start.CustosAPIServerStarter ${AIRAVATA_COMMAND} $* > $LOG_FILE 2>&1 &
+            echo $! > $PID_PATH_NAME
+            echo "$SERVICE_NAME started ..."
+        else
+            echo "$SERVICE_NAME is already running ..."
+        fi
+    ;;
+    stop)
+        if [ -f $PID_PATH_NAME ]; then
+            PID=$(cat $PID_PATH_NAME);
+            echo "$SERVICE_NAME stoping ..."
+            kill $PID;
+            RETRY=0
+            while kill -0 $PID 2> /dev/null; do
+                echo "Waiting for the process $PID to be stopped"
+                RETRY=`expr ${RETRY} + 1`
+                if [ "${RETRY}" -gt "20" ]
+                then
+                    echo "Forcefully killing the process as it is not responding ..."
+                    kill -9 $PID
+                fi
+                sleep 1
+            done
+            echo "$SERVICE_NAME stopped ..."
+            rm $PID_PATH_NAME
+        else
+            echo "$SERVICE_NAME is not running ..."
+        fi
+    ;;
+    restart)
+        if [ -f $PID_PATH_NAME ]; then
+            PID=$(cat $PID_PATH_NAME);
+            echo "$SERVICE_NAME stopping ...";
+            kill $PID;
+            RETRY=0
+            while kill -0 $PID 2> /dev/null; do
+                echo "Waiting for the process $PID to be stopped"
+                RETRY=`expr ${RETRY} + 1`
+                if [ "${RETRY}" -gt "20" ]
+                then
+                    echo "Forcefully killing the process as it is not responding ..."
+                    kill -9 $PID
+                fi
+                sleep 1
+            done
+            echo "$SERVICE_NAME stopped ...";
+            rm $PID_PATH_NAME
+            echo "$SERVICE_NAME starting ..."
+            nohup java ${JAVA_OPTS} -classpath "${AIRAVATA_CLASSPATH}" \
+            org.apache.airavata.helix.impl.controller.HelixController ${AIRAVATA_COMMAND} $* > $LOG_FILE 2>&1 &
+            echo $! > $PID_PATH_NAME
+            echo "$SERVICE_NAME started ..."
+        else
+            echo "$SERVICE_NAME is not running ..."
+        fi
+    ;;
+    -h)
+        echo "Usage: custos-daemon.sh"
+
+        echo "command options:"
+        echo "  start               Start server in daemon mode"
+        echo "  stop                Stop server running in daemon mode"
+        echo "  restart             Restart server in daemon mode"
+	    echo "  -log <LOG_FILE>     Where to redirect stdout/stderr (defaults to $DEFAULT_LOG_FILE)"
+        echo "  -h                  Display this help and exit"
+        shift
+        exit 0
+    ;;
+esac
+
diff --git a/ide-integration/custos-services/src/main/resources/custos/bin/custos.sh b/ide-integration/custos-services/src/main/resources/custos/bin/custos.sh
new file mode 100644
index 0000000..5e96590
--- /dev/null
+++ b/ide-integration/custos-services/src/main/resources/custos/bin/custos.sh
@@ -0,0 +1,71 @@
+#!/usr/bin/env bash
+
+# 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.
+
+. `dirname $0`/setenv.sh
+# Capture user's working dir before changing directory
+CWD="$PWD"
+cd ${AIRAVATA_HOME}/bin
+LOGO_FILE="logo.txt"
+
+JAVA_OPTS="-Dairavata.config.dir=${AIRAVATA_HOME}/conf -Dairavata.home=${AIRAVATA_HOME} -Dlogback.configurationFile=file:${AIRAVATA_HOME}/conf/logback.xml"
+AIRAVATA_COMMAND=""
+EXTRA_ARGS=""
+SERVERS=""
+IS_SUBSET=false
+SUBSET=""
+DEFAULT_LOG_FILE="${AIRAVATA_HOME}/logs/airavata.out"
+LOG_FILE=$DEFAULT_LOG_FILE
+
+# parse command arguments
+for var in "$@"
+do
+    case ${var} in
+        -xdebug)
+        	AIRAVATA_COMMAND="${AIRAVATA_COMMAND}"
+            JAVA_OPTS="$JAVA_OPTS -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,address=8000"
+            shift
+	    ;;
+        -log)
+            shift
+            LOG_FILE="$1"
+            shift
+            # If relative path, expand to absolute path using the user's $CWD
+            if [ -z "`echo "$LOG_FILE" | egrep "^/"`" ]; then
+                LOG_FILE="${CWD}/${LOG_FILE}"
+            fi
+        ;;
+        -h)
+            echo "Usage: controller.sh"
+
+            echo "command options:"
+            echo "  -xdebug             Start Email Monitor under JPDA debugger"
+            echo "  -h                  Display this help and exit"
+            shift
+            exit 0
+        ;;
+	    *)
+	        EXTRA_ARGS="${EXTRA_ARGS} ${var}"
+            shift
+        ;;
+    esac
+done
+
+java ${JAVA_OPTS} -classpath "${AIRAVATA_CLASSPATH}" \
+    org.apache.custos.server.start.CustosAPIServerStarter ${AIRAVATA_COMMAND} $*
+
diff --git a/ide-integration/custos-services/src/main/resources/custos/bin/setenv.sh b/ide-integration/custos-services/src/main/resources/custos/bin/setenv.sh
new file mode 100755
index 0000000..9e894e1
--- /dev/null
+++ b/ide-integration/custos-services/src/main/resources/custos/bin/setenv.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+# 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.
+
+# resolve links - $0 may be a softlink
+PRG="$0"
+
+while [ -h "$PRG" ]; do
+  ls=`ls -ld "$PRG"`
+  link=`expr "$ls" : '.*-> \(.*\)$'`
+  if expr "$link" : '.*/.*' > /dev/null; then
+    PRG="$link"
+  else
+    PRG=`dirname "$PRG"`/"$link"
+  fi
+done
+
+PRGDIR=`dirname "$PRG"`
+
+# Only set AIRAVATA_HOME if not already set
+[ -z "$AIRAVATA_HOME" ] && AIRAVATA_HOME=`cd "$PRGDIR/.." ; pwd`
+
+AIRAVATA_CLASSPATH=""
+
+for f in "$AIRAVATA_HOME"/lib/*.jar
+do
+  AIRAVATA_CLASSPATH="$AIRAVATA_CLASSPATH":$f
+done
+
+export AIRAVATA_HOME
+export AIRAVATA_CLASSPATH
diff --git a/ide-integration/custos-services/src/main/resources/custos/conf/logback.xml b/ide-integration/custos-services/src/main/resources/custos/conf/logback.xml
new file mode 100644
index 0000000..ef38b65
--- /dev/null
+++ b/ide-integration/custos-services/src/main/resources/custos/conf/logback.xml
@@ -0,0 +1,53 @@
+<?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>
+
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%d [%t] %-5p %c{30} %X - %m%n</pattern>
+        </encoder>
+    </appender>
+
+    <appender name="LOGFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <File>../logs/airavata.log</File>
+        <Append>true</Append>
+        <encoder>
+            <pattern>%d [%t] %-5p %c{30} %X - %m%n</pattern>
+        </encoder>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>../logs/airavata.log.%d{yyyy-MM-dd}</fileNamePattern>
+            <maxHistory>30</maxHistory>
+            <totalSizeCap>1GB</totalSizeCap>
+        </rollingPolicy>
+    </appender>
+
+    <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">
+        <appender-ref ref="CONSOLE"/>
+        <appender-ref ref="LOGFILE"/>
+    </root>
+</configuration>
diff --git a/pom.xml b/pom.xml
index 0169baf..0c7620b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,6 +23,7 @@
         <module>custos-profile-service</module>
         <module>custos-connectors</module>
         <module>custos-sharing-registry-service</module>
+        <module>custos-rest-api</module>
     </modules>
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>