Initial drop of code 99/118099/1
authorClaudio D. Gasparini <claudio.gasparini@pantheon.tech>
Fri, 19 Feb 2021 11:27:45 +0000 (12:27 +0100)
committerClaudio D. Gasparini <claudio.gasparini@pantheon.tech>
Fri, 19 Feb 2021 11:34:44 +0000 (12:34 +0100)
Issue-ID: CPS-243
Signed-off-by: Claudio D. Gasparini <claudio.gasparini@pantheon.tech>
Change-Id: I048cc8931097c2f38331aaf60861d9c5a1ca7599

24 files changed:
application.yml [new file with mode: 0644]
docs/api/swagger/swagger.yaml [new file with mode: 0644]
lombok.config [new file with mode: 0644]
pom.xml
src/main/java/org/onap/cps/tdmt/Application.java [new file with mode: 0644]
src/main/java/org/onap/cps/tdmt/client/CpsRestClient.java [new file with mode: 0644]
src/main/java/org/onap/cps/tdmt/db/TemplateRepository.java [new file with mode: 0644]
src/main/java/org/onap/cps/tdmt/exception/CpsException.java [new file with mode: 0644]
src/main/java/org/onap/cps/tdmt/exception/ExecuteException.java [new file with mode: 0644]
src/main/java/org/onap/cps/tdmt/exception/RecordNotFoundException.java [new file with mode: 0644]
src/main/java/org/onap/cps/tdmt/exception/TemplateExceptionHandler.java [new file with mode: 0644]
src/main/java/org/onap/cps/tdmt/model/AppConfiguration.java [new file with mode: 0644]
src/main/java/org/onap/cps/tdmt/model/ErrorResponse.java [new file with mode: 0644]
src/main/java/org/onap/cps/tdmt/model/ExecutionRequest.java [new file with mode: 0644]
src/main/java/org/onap/cps/tdmt/model/ExecutionResponse.java [new file with mode: 0644]
src/main/java/org/onap/cps/tdmt/model/Template.java [new file with mode: 0644]
src/main/java/org/onap/cps/tdmt/model/TemplateId.java [new file with mode: 0644]
src/main/java/org/onap/cps/tdmt/model/TemplateRequest.java [new file with mode: 0644]
src/main/java/org/onap/cps/tdmt/rest/ExecutionController.java [new file with mode: 0644]
src/main/java/org/onap/cps/tdmt/rest/TemplateController.java [new file with mode: 0644]
src/main/java/org/onap/cps/tdmt/service/ExecutionBusinessLogic.java [new file with mode: 0644]
src/main/java/org/onap/cps/tdmt/service/TemplateBusinessLogic.java [new file with mode: 0644]
src/main/resources/application.properties [new file with mode: 0644]
src/main/resources/schema.sql [new file with mode: 0644]

diff --git a/application.yml b/application.yml
new file mode 100644 (file)
index 0000000..9792753
--- /dev/null
@@ -0,0 +1,42 @@
+###############################################################################
+#  ============LICENSE_START=======================================================
+#  ONAP
+#  ================================================================================
+#   Copyright (C) 2021 Wipro Limited.
+#   ==============================================================================
+#     Licensed 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.
+#     ============LICENSE_END=========================================================
+#
+###############################################################################
+
+spring:
+  datasource:
+    initialization-mode: always
+    initialize: true
+    schema: classpath:/schema.sql
+    url: jdbc:postgresql://localhost:5432/template_db
+    username: postgres
+    password: postgres
+    continue-on-error: true
+  jpa:
+    hibernate:
+      ddl-auto: validate
+    properties:
+      hibernate:
+        temp:
+          use_jdbc_metadata_defaults: false
+    database-platform: org.hibernate.dialect.PostgreSQL9Dialect
+app:
+  xnfProxyUrl: http://localhost:8000/
+  schemaToAnchor:
+    ran-coverage-area: coverage-area-onap
diff --git a/docs/api/swagger/swagger.yaml b/docs/api/swagger/swagger.yaml
new file mode 100644 (file)
index 0000000..b6fe6fb
--- /dev/null
@@ -0,0 +1,178 @@
+swagger: "2.0"
+info:
+  description: ""
+  version: "1.0.0"
+  title: "Template based Data Model Transformer APIs"
+  license:
+    name: "Apache 2.0"
+    url: "http://www.apache.org/licenses/LICENSE-2.0.html"
+host: "localhost"
+basePath: "/v1"
+tags:
+- name: "templates"
+  description: "CRUD APIs for xpath templates"
+schemes:
+- "https"
+- "http"
+paths:
+  /templates:
+    post:
+      tags:
+      - "templates"
+      summary: "Add a new template"
+      description: ""
+      operationId: "addTemplate"
+      consumes:
+      - "application/json"
+      produces:
+      - "application/json"
+      parameters:
+      - in: "body"
+        name: "body"
+        description: "Template object that needs to be added"
+        required: true
+        schema:
+          $ref: "#/definitions/Template"
+      responses:
+        "201":
+          description: "Created successfully"
+        "400":
+          description: "Invalid input"
+        "500":
+          description: "Internal server error"
+    get:
+      tags:
+      - "templates"
+      summary: "Get all templates"
+      description: ""
+      operationId: "getAllTemplates"
+      consumes:
+      - "application/json"
+      produces:
+      - "application/json"
+      responses:
+        "200":
+          description: "Templates returned successfully"
+          schema:
+            type: "array"
+            items:
+              $ref: "#/definitions/Template"
+        "404":
+          description: "No templates found"
+        "500":
+          description: "Internal server error"
+  /templates/{schemaSet}/{id}:
+    get:
+      tags:
+      - "templates"
+      summary: "Find template by ID"
+      description: "Returns a single template"
+      operationId: "getTemplateById"
+      produces:
+      - "application/json"
+      parameters:
+      - name: "id"
+        in: "path"
+        description: "ID of template to return"
+        required: true
+        type: "string"
+      - name: "schemaSet"
+        in: "path"
+        description: "schema set"
+        required: true
+        type: "string"
+      responses:
+        "200":
+          description: "Template returned successfully"
+          schema:
+            $ref: "#/definitions/Template"
+        "400":
+          description: "Invalid ID supplied"
+        "404":
+          description: "Not found"
+    delete:
+      tags:
+      - "templates"
+      summary: "Deletes a template"
+      description: ""
+      operationId: "deleteTemplate"
+      produces:
+      - "application/json"
+      parameters:
+      - name: "id"
+        in: "path"
+        required: true
+        type: "string"
+      - name: "schemaSet"
+        in: "path"
+        description: "schema set"
+        required: true
+        type: "string"
+      responses:
+        "200":
+          description: "Deleted successfully"
+        "400":
+          description: "Invalid ID supplied"
+        "404":
+          description: "Template not found"
+  /execute/{schemaSet}/{id}:
+    post:
+      tags:
+      - "template executions"
+      summary: "Execute a template"
+      description: "Returns the result of execution"
+      operationId: "executeTemplateById"
+      produces:
+      - "application/json"
+      parameters:
+      - name: "id"
+        in: "path"
+        description: "ID of template to execute"
+        required: true
+        type: "string"
+      - name: "schemaSet"
+        in: "path"
+        description: "schema set"
+        required: true
+        type: "string"
+      - in: "body"
+        name: "body"
+        description: "Template object that needs to be added"
+        required: true
+        schema:
+          $ref: "#/definitions/ApiRequest"
+      responses:
+        "200":
+          description: "Result returned successfully"
+          schema:
+            $ref: "#/definitions/ApiResponse"
+        "400":
+          description: "Invalid ID supplied"
+        "404":
+          description: "Not found"
+        "500":
+          description: "Internal server error"
+definitions:
+  Template:
+    type: "object"
+    required:
+    - "id"
+    - "schemaSet"
+    - "xpathTemplate"
+    properties:
+      id:
+        type: "string"
+      schemaSet:
+        type: "string"
+      xpathTemplate:
+        type: "string"
+  ApiRequest:
+    type: "object"
+    properties:
+      input:
+        type: "object"
+  ApiResponse:
+    type: "object"
+externalDocs:
+  description: "Find out more about APIs"
+  url: "https://wiki.onap.org/display/DW/API+Mapper+Service"
diff --git a/lombok.config b/lombok.config
new file mode 100644 (file)
index 0000000..7a21e88
--- /dev/null
@@ -0,0 +1 @@
+lombok.addLombokGeneratedAnnotation = true
diff --git a/pom.xml b/pom.xml
index 7d3471e..058e9ae 100644 (file)
--- a/pom.xml
+++ b/pom.xml
     <description>Template Based DataModel Transformer</description>
     <packaging>jar</packaging>
 
+    <properties>
+        <maven.compiler.source>11</maven.compiler.source>
+        <maven.compiler.target>11</maven.compiler.target>
+        <maven.build.timestamp.format>yyyyMMdd'T'HHmmss</maven.build.timestamp.format>
+        <sonar.coverage.jacoco.xmlReportPaths>
+            ${project.reporting.outputDirectory}/jacoco-ut/jacoco.xml
+        </sonar.coverage.jacoco.xmlReportPaths>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-autoconfigure</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-webmvc</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-beans</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-expression</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-tx</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.data</groupId>
+            <artifactId>spring-data-commons</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.postgresql</groupId>
+            <artifactId>postgresql</artifactId>
+            <version>42.2.5</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.hibernate.javax.persistence</groupId>
+            <artifactId>hibernate-jpa-2.0-api</artifactId>
+            <version>1.0.1.Final</version>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.16</version>
+        </dependency>
+        <dependency>
+            <groupId>com.hubspot.jinjava</groupId>
+            <artifactId>jinjava</artifactId>
+            <version>2.5.6</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.fasterxml.jackson.core</groupId>
+                    <artifactId>jackson-annotations</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>com.fasterxml.jackson.core</groupId>
+                    <artifactId>jackson-databind</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>com.fasterxml.jackson.core</groupId>
+                    <artifactId>jackson-core</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>com.fasterxml.jackson.dataformat</groupId>
+                    <artifactId>jackson-dataformat-yaml</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-tomcat</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-validation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.tomcat.embed</groupId>
+            <artifactId>tomcat-embed-core</artifactId>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>
\ No newline at end of file
diff --git a/src/main/java/org/onap/cps/tdmt/Application.java b/src/main/java/org/onap/cps/tdmt/Application.java
new file mode 100644 (file)
index 0000000..2d82eba
--- /dev/null
@@ -0,0 +1,32 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 Wipro Limited.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.tdmt;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class Application {
+
+    public static void main(final String[] args) {
+        SpringApplication.run(Application.class, args);
+    }
+}
diff --git a/src/main/java/org/onap/cps/tdmt/client/CpsRestClient.java b/src/main/java/org/onap/cps/tdmt/client/CpsRestClient.java
new file mode 100644 (file)
index 0000000..c04290d
--- /dev/null
@@ -0,0 +1,77 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 Wipro Limited.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.tdmt.client;
+
+import java.util.Arrays;
+import org.onap.cps.tdmt.exception.CpsException;
+import org.onap.cps.tdmt.model.AppConfiguration;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+@Component
+public class CpsRestClient {
+
+    @Autowired
+    private RestTemplate restTemplate;
+
+    @Autowired
+    private AppConfiguration appConfiguration;
+
+    /**
+     * Fetch node from the CPS using xpath.
+     *
+     * @param anchor anchor
+     * @param xpath xpath query
+     * @return result Response string from CPS
+     */
+    public String fetchNode(final String anchor, final String xpath) throws CpsException {
+        final String url = appConfiguration.getXnfProxyUrl();
+
+        final String uri = String.format("%s/anchors/%s/nodes?cps-path=%s", url, anchor, xpath);
+
+        final HttpHeaders headers = new HttpHeaders();
+        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
+        final HttpEntity<String> entity = new HttpEntity<>(headers);
+
+        ResponseEntity<String> responseEntity = null;
+        try {
+            responseEntity = restTemplate.exchange(uri, HttpMethod.GET, entity, String.class);
+        } catch (final Exception e) {
+            throw new CpsException(e.getLocalizedMessage());
+        }
+
+        final int statusCode = responseEntity.getStatusCodeValue();
+
+        if (statusCode == 200) {
+            return responseEntity.getBody();
+        } else {
+            throw new CpsException(
+                String.format("Response code from CPS other than 200: %d", statusCode));
+        }
+    }
+
+}
diff --git a/src/main/java/org/onap/cps/tdmt/db/TemplateRepository.java b/src/main/java/org/onap/cps/tdmt/db/TemplateRepository.java
new file mode 100644 (file)
index 0000000..a86621b
--- /dev/null
@@ -0,0 +1,31 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 Wipro Limited.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.tdmt.db;
+
+import org.onap.cps.tdmt.model.Template;
+import org.onap.cps.tdmt.model.TemplateId;
+import org.springframework.data.repository.CrudRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface TemplateRepository extends CrudRepository<Template, TemplateId> {
+
+}
diff --git a/src/main/java/org/onap/cps/tdmt/exception/CpsException.java b/src/main/java/org/onap/cps/tdmt/exception/CpsException.java
new file mode 100644 (file)
index 0000000..50c6c27
--- /dev/null
@@ -0,0 +1,28 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 Wipro Limited.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.tdmt.exception;
+
+public class CpsException extends Exception {
+
+    public CpsException(final String exception) {
+        super(exception);
+    }
+}
diff --git a/src/main/java/org/onap/cps/tdmt/exception/ExecuteException.java b/src/main/java/org/onap/cps/tdmt/exception/ExecuteException.java
new file mode 100644 (file)
index 0000000..40e97b9
--- /dev/null
@@ -0,0 +1,32 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 Wipro Limited.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.tdmt.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(HttpStatus.OK)
+public class ExecuteException extends RuntimeException {
+
+    public ExecuteException(final String exception) {
+        super(exception);
+    }
+}
diff --git a/src/main/java/org/onap/cps/tdmt/exception/RecordNotFoundException.java b/src/main/java/org/onap/cps/tdmt/exception/RecordNotFoundException.java
new file mode 100644 (file)
index 0000000..0bbf32a
--- /dev/null
@@ -0,0 +1,32 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 Wipro Limited.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.tdmt.exception;
+
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+@ResponseStatus(HttpStatus.NOT_FOUND)
+public class RecordNotFoundException extends RuntimeException {
+
+    public RecordNotFoundException(final String exception) {
+        super(exception);
+    }
+}
diff --git a/src/main/java/org/onap/cps/tdmt/exception/TemplateExceptionHandler.java b/src/main/java/org/onap/cps/tdmt/exception/TemplateExceptionHandler.java
new file mode 100644 (file)
index 0000000..5ccbff4
--- /dev/null
@@ -0,0 +1,82 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 Wipro Limited.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.tdmt.exception;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.onap.cps.tdmt.model.ErrorResponse;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.validation.ObjectError;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.context.request.WebRequest;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
+
+@ControllerAdvice
+public class TemplateExceptionHandler extends ResponseEntityExceptionHandler {
+
+    /**
+     * Handle TemplateNotFoundException.
+     *
+     * @param ex Exception
+     * @param request web request
+     * @return response entity
+     */
+    @ExceptionHandler(RecordNotFoundException.class)
+    public final ResponseEntity<Object> handleTemplateNotFoundException(final RecordNotFoundException ex,
+        final WebRequest request) {
+        final List<String> details = new ArrayList<>();
+        details.add(ex.getLocalizedMessage());
+        final ErrorResponse error = new ErrorResponse("Template Not found", details);
+        return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
+    }
+
+    /**
+     * Handle ExecuteException.
+     *
+     * @param ex Exception
+     * @param request web request
+     * @return response entity
+     */
+    @ExceptionHandler(ExecuteException.class)
+    public final ResponseEntity<Object> handleExecutionException(final ExecuteException ex,
+        final WebRequest request) {
+        final List<String> details = new ArrayList<>();
+        details.add(ex.getLocalizedMessage());
+        final ErrorResponse error = new ErrorResponse("Error while executing template", details);
+        return new ResponseEntity<>(error, HttpStatus.OK);
+    }
+
+    @Override
+    protected ResponseEntity<Object> handleMethodArgumentNotValid(
+        final MethodArgumentNotValidException ex,
+        final HttpHeaders headers, final HttpStatus status, final WebRequest request) {
+        final List<String> details = new ArrayList<>();
+        for (final ObjectError error : ex.getBindingResult().getAllErrors()) {
+            details.add(error.getDefaultMessage());
+        }
+        final ErrorResponse error = new ErrorResponse("Validation Failed", details);
+        return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
+    }
+}
diff --git a/src/main/java/org/onap/cps/tdmt/model/AppConfiguration.java b/src/main/java/org/onap/cps/tdmt/model/AppConfiguration.java
new file mode 100644 (file)
index 0000000..4310a9a
--- /dev/null
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 Wipro Limited.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.tdmt.model;
+
+import java.util.Map;
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.client.RestTemplate;
+
+@Getter
+@Setter
+@Configuration
+@EnableConfigurationProperties
+@ConfigurationProperties(prefix = "app")
+public class AppConfiguration {
+
+    private String xnfProxyUrl;
+    private Map<String, String> schemaToAnchor;
+
+    @Bean
+    public RestTemplate restTemplate() {
+        return new RestTemplate();
+    }
+
+}
diff --git a/src/main/java/org/onap/cps/tdmt/model/ErrorResponse.java b/src/main/java/org/onap/cps/tdmt/model/ErrorResponse.java
new file mode 100644 (file)
index 0000000..d5860ef
--- /dev/null
@@ -0,0 +1,35 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 Wipro Limited.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.tdmt.model;
+
+import java.util.List;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+@AllArgsConstructor
+public class ErrorResponse {
+
+    private String message;
+    private List<String> details;
+}
diff --git a/src/main/java/org/onap/cps/tdmt/model/ExecutionRequest.java b/src/main/java/org/onap/cps/tdmt/model/ExecutionRequest.java
new file mode 100644 (file)
index 0000000..7abe131
--- /dev/null
@@ -0,0 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 Wipro Limited.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.tdmt.model;
+
+import java.util.Map;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+public class ExecutionRequest {
+
+    private Map<String, String> input;
+}
diff --git a/src/main/java/org/onap/cps/tdmt/model/ExecutionResponse.java b/src/main/java/org/onap/cps/tdmt/model/ExecutionResponse.java
new file mode 100644 (file)
index 0000000..f66ca93
--- /dev/null
@@ -0,0 +1,35 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 Wipro Limited.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.tdmt.model;
+
+import lombok.AllArgsConstructor;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.Setter;
+
+@Getter
+@Setter
+@EqualsAndHashCode
+@AllArgsConstructor
+public class ExecutionResponse {
+
+    private Object result;
+}
diff --git a/src/main/java/org/onap/cps/tdmt/model/Template.java b/src/main/java/org/onap/cps/tdmt/model/Template.java
new file mode 100644 (file)
index 0000000..58266b5
--- /dev/null
@@ -0,0 +1,54 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 Wipro Limited.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.tdmt.model;
+
+import java.io.Serializable;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.IdClass;
+import javax.persistence.Table;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+@Entity
+@Table(name = "Template")
+@IdClass(TemplateId.class)
+public class Template implements Serializable {
+
+    private static final long serialVersionUID = 345L;
+
+    @Id
+    private String id;
+
+    @Id
+    private String schemaSet;
+
+    @Column(name = "xpath_template")
+    private String xpathTemplate;
+
+}
diff --git a/src/main/java/org/onap/cps/tdmt/model/TemplateId.java b/src/main/java/org/onap/cps/tdmt/model/TemplateId.java
new file mode 100644 (file)
index 0000000..7ca66fc
--- /dev/null
@@ -0,0 +1,45 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 Wipro Limited.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.tdmt.model;
+
+import java.io.Serializable;
+import javax.persistence.Column;
+import lombok.AllArgsConstructor;
+import lombok.EqualsAndHashCode;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@EqualsAndHashCode
+@AllArgsConstructor
+@NoArgsConstructor
+public class TemplateId implements Serializable {
+
+    private static final long serialVersionUID = 400L;
+
+    private String id;
+
+    @Column(name = "schema_set")
+    private String schemaSet;
+
+}
diff --git a/src/main/java/org/onap/cps/tdmt/model/TemplateRequest.java b/src/main/java/org/onap/cps/tdmt/model/TemplateRequest.java
new file mode 100644 (file)
index 0000000..fdb8fd7
--- /dev/null
@@ -0,0 +1,47 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 Wipro Limited.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.tdmt.model;
+
+import java.io.Serializable;
+import javax.validation.constraints.NotEmpty;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+@Getter
+@Setter
+@AllArgsConstructor
+@NoArgsConstructor
+public class TemplateRequest implements Serializable {
+
+    private static final long serialVersionUID = 543L;
+
+    @NotEmpty(message = "id missing")
+    private String id;
+
+    @NotEmpty(message = "schemaSet missing")
+    private String schemaSet;
+
+    @NotEmpty(message = "template missing")
+    private String xpathTemplate;
+
+}
diff --git a/src/main/java/org/onap/cps/tdmt/rest/ExecutionController.java b/src/main/java/org/onap/cps/tdmt/rest/ExecutionController.java
new file mode 100644 (file)
index 0000000..f6b24a8
--- /dev/null
@@ -0,0 +1,49 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 Wipro Limited.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.tdmt.rest;
+
+import javax.validation.Valid;
+import org.onap.cps.tdmt.model.ExecutionRequest;
+import org.onap.cps.tdmt.service.ExecutionBusinessLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class ExecutionController {
+
+    @Autowired
+    private ExecutionBusinessLogic executionBusinessLogic;
+
+
+    @PostMapping(path = "/execute/{schemaSet}/{id}")
+    public ResponseEntity<String> executeTemplate(@Valid @PathVariable final String schemaSet,
+        @Valid @PathVariable final String id,
+        @Valid @RequestBody final ExecutionRequest request) {
+        final String result = executionBusinessLogic.executeTemplate(schemaSet, id, request);
+        return new ResponseEntity<>(result, HttpStatus.OK);
+    }
+
+}
diff --git a/src/main/java/org/onap/cps/tdmt/rest/TemplateController.java b/src/main/java/org/onap/cps/tdmt/rest/TemplateController.java
new file mode 100644 (file)
index 0000000..8b56206
--- /dev/null
@@ -0,0 +1,86 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 Wipro Limited.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.tdmt.rest;
+
+import java.util.List;
+import javax.validation.Valid;
+import org.onap.cps.tdmt.exception.RecordNotFoundException;
+import org.onap.cps.tdmt.model.Template;
+import org.onap.cps.tdmt.model.TemplateId;
+import org.onap.cps.tdmt.model.TemplateRequest;
+import org.onap.cps.tdmt.service.TemplateBusinessLogic;
+import org.springframework.beans.factory.annotation.Autowired;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class TemplateController {
+
+    @Autowired
+    private TemplateBusinessLogic templateBusinessLogic;
+
+    @PostMapping(path = "/templates")
+    public ResponseEntity<Template> createTemplate(@Valid @RequestBody final TemplateRequest request) {
+        return new ResponseEntity<>(templateBusinessLogic.createTemplate(request),
+            HttpStatus.CREATED);
+    }
+
+    /**
+     * Get All Templates.
+     *
+     * @return templates
+     */
+    @GetMapping(path = "/templates")
+    public ResponseEntity<List<Template>> getAllTemplates() {
+        final List<Template> templates = templateBusinessLogic.getAllTemplates();
+        if (templates.isEmpty()) {
+            throw new RecordNotFoundException("Template repository is empty");
+        }
+        return new ResponseEntity<>(templates, HttpStatus.OK);
+    }
+
+    /**
+     * Get Template by Id.
+     *
+     * @param id id to find the template
+     * @param schemaSet schema set to find the template
+     * @return template
+     */
+    @GetMapping(path = "/templates/{schemaSet}/{id}")
+    public ResponseEntity<Template> getTemplate(@PathVariable final String id,
+        @PathVariable final String schemaSet) {
+        return new ResponseEntity<>(
+            templateBusinessLogic.getTemplate(new TemplateId(id, schemaSet)),
+            HttpStatus.OK);
+
+    }
+
+    @DeleteMapping(path = "/templates/{schemaSet}/{id}")
+    public void deleteTemplate(@PathVariable final String id, @PathVariable final String schemaSet) {
+        templateBusinessLogic.deleteTemplate(new TemplateId(id, schemaSet));
+    }
+}
diff --git a/src/main/java/org/onap/cps/tdmt/service/ExecutionBusinessLogic.java b/src/main/java/org/onap/cps/tdmt/service/ExecutionBusinessLogic.java
new file mode 100644 (file)
index 0000000..c05363d
--- /dev/null
@@ -0,0 +1,81 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 Wipro Limited.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.tdmt.service;
+
+import com.hubspot.jinjava.Jinjava;
+import java.util.Map;
+import java.util.Optional;
+import org.onap.cps.tdmt.client.CpsRestClient;
+import org.onap.cps.tdmt.db.TemplateRepository;
+import org.onap.cps.tdmt.exception.CpsException;
+import org.onap.cps.tdmt.exception.ExecuteException;
+import org.onap.cps.tdmt.exception.RecordNotFoundException;
+import org.onap.cps.tdmt.model.AppConfiguration;
+import org.onap.cps.tdmt.model.ExecutionRequest;
+import org.onap.cps.tdmt.model.Template;
+import org.onap.cps.tdmt.model.TemplateId;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class ExecutionBusinessLogic {
+
+    @Autowired
+    private TemplateRepository templateRepository;
+
+    @Autowired
+    private AppConfiguration appConfiguration;
+
+    @Autowired
+    private CpsRestClient cpsRestClient;
+
+    /**
+     * Execute a template stored in the database.
+     *
+     * @param schemaSet schema set
+     * @param id id
+     * @return result response from the execution of template
+     */
+    public String executeTemplate(final String schemaSet, final String id, final ExecutionRequest request) {
+
+        final Optional<Template> template = templateRepository.findById(new TemplateId(id, schemaSet));
+        if (template.isPresent()) {
+            return execute(template.get(), request.getInput());
+        } else {
+            throw new RecordNotFoundException("Template does not exist");
+        }
+    }
+
+    private String execute(final Template template, final Map<String, String> input) {
+        final String anchor = appConfiguration.getSchemaToAnchor().get(template.getSchemaSet());
+        if (anchor == null) {
+            throw new ExecuteException("Anchor not found for the schema");
+        }
+        final Jinjava jinja = new Jinjava();
+        final String xpath = jinja.render(template.getXpathTemplate(), input);
+        try {
+            return cpsRestClient.fetchNode(anchor, xpath);
+        } catch (final CpsException e) {
+            throw new ExecuteException(e.getLocalizedMessage());
+        }
+    }
+
+}
diff --git a/src/main/java/org/onap/cps/tdmt/service/TemplateBusinessLogic.java b/src/main/java/org/onap/cps/tdmt/service/TemplateBusinessLogic.java
new file mode 100644 (file)
index 0000000..f54e833
--- /dev/null
@@ -0,0 +1,92 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 Wipro Limited.
+ * ================================================================================
+ * Licensed 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.cps.tdmt.service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import org.onap.cps.tdmt.db.TemplateRepository;
+import org.onap.cps.tdmt.exception.RecordNotFoundException;
+import org.onap.cps.tdmt.model.Template;
+import org.onap.cps.tdmt.model.TemplateId;
+import org.onap.cps.tdmt.model.TemplateRequest;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class TemplateBusinessLogic {
+
+    @Autowired
+    private TemplateRepository templateRepository;
+
+    /**
+     * Create Template.
+     *
+     * @param templateRequest request object
+     * @return template
+     */
+    public Template createTemplate(final TemplateRequest templateRequest) {
+        final Template template = new Template(templateRequest.getId(),
+            templateRequest.getSchemaSet(),
+            templateRequest.getXpathTemplate());
+        return templateRepository.save(template);
+    }
+
+    /**
+     * Get All Templates.
+     *
+     * @return templates
+     */
+    public List<Template> getAllTemplates() {
+        final List<Template> templates = new ArrayList<>();
+        templateRepository.findAll().forEach(templates::add);
+        return templates;
+    }
+
+    /**
+     * Get Template by Id.
+     *
+     * @param templateId template id to find the template
+     * @return template
+     */
+    public Template getTemplate(final TemplateId templateId) {
+        final Optional<Template> template = templateRepository.findById(templateId);
+        if (template.isPresent()) {
+            return template.get();
+        } else {
+            throw new RecordNotFoundException("Template not found for given id and schema");
+        }
+    }
+
+    /**
+     * Delete Template.
+     *
+     * @param templateId template id to find the template
+     */
+    public void deleteTemplate(final TemplateId templateId) {
+        if (templateRepository.existsById(templateId)) {
+            templateRepository.deleteById(templateId);
+        } else {
+            throw new RecordNotFoundException(
+                "Delete failed. Could not find template with specified id");
+        }
+    }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
new file mode 100644 (file)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql
new file mode 100644 (file)
index 0000000..dd2ad51
--- /dev/null
@@ -0,0 +1,6 @@
+CREATE TABLE Template(
+       id TEXT NOT NULL,
+       schema_set TEXT NOT NULL,
+       xpath_template TEXT NOT NULL,
+       PRIMARY KEY(id, schema_set)
+);