Add execute-graph and vlbcheck to swagger-codegen code 07/102507/4
authorDan Timoney <dtimoney@att.com>
Wed, 26 Feb 2020 21:07:53 +0000 (16:07 -0500)
committerDan Timoney <dtimoney@att.com>
Thu, 27 Feb 2020 19:05:55 +0000 (14:05 -0500)
Add implementation for execute-graph and vlbcheck RPCs.  Also,
added junit tests.

Change-Id: Id2a31c033d25ef12c455bfee98c5aea8439fc2f9
Issue-ID: CCSDK-2096
Signed-off-by: Dan Timoney <dtimoney@att.com>
sli/common/src/main/java/org/onap/ccsdk/sli/core/sli/SvcLogicContext.java
sliapi/model/src/main/resources/sli-api.20161110.yaml
sliapi/springboot/pom.xml
sliapi/springboot/src/main/java/org/onap/ccsdk/sli/core/sliapi/springboot/RestconfApiController.java
sliapi/springboot/src/main/resources/application.properties
sliapi/springboot/src/main/resources/graph.versions
sliapi/springboot/src/main/resources/sli_vlbcheck.xml [new file with mode: 0644]
sliapi/springboot/src/main/resources/svclogic.properties
sliapi/springboot/src/test/java/org/onap/ccsdk/sli/core/sliapi/springboot/RestconfApiControllerTest.java [new file with mode: 0644]

index 549e636..3681e1e 100644 (file)
@@ -91,7 +91,7 @@ public class SvcLogicContext {
        {
                return attributes.keySet();
        }
-  public Boolean isSuccess() {
+    public Boolean isSuccess() {
         return status.equals(SvcLogicConstants.SUCCESS);
   }
 
index db60aa1..3420c66 100644 (file)
@@ -164,12 +164,6 @@ paths:
       produces:
         - application/json
         - application/xml
-#      parameters:
-#        - in: body
-#          name: healthcheckInput
-#          required: false
-#          schema:
-#            $ref: '#/definitions/healthcheck-input'
       responses:
         '200':
           description: No response was specified
@@ -184,12 +178,6 @@ paths:
       produces:
         - application/json
         - application/xml
-      parameters:
-        - in: body
-          name: vlbcheckInput
-          required: false
-          schema:
-            $ref: '#/definitions/vlbcheck-input'
       responses:
         '200':
           description: No response was specified
@@ -242,28 +230,23 @@ definitions:
 
   execute-graph-input:
     properties:
-      'mode':
-        type: string
-      'module-name':
-        type: string
-      'rpc-name':
-        type: string
-      'sli-parameter':
-        items:
-          $ref: '#/definitions/parameter-setting'
-        type: array
+      'input':
+        type: object
+        properties:
+          'mode':
+             type: string
+          'module-name':
+            type: string
+          'rpc-name':
+            type: string
+          'sli-parameter':
+            items:
+              $ref: '#/definitions/parameter-setting'
+            type: array
     type: object
 
-  healthcheck-input:
-    properties:
-      'dummy':
-        type: string
 
 
-  vlbcheck-input:
-    properties:
-      'dummy':
-        type: string
 
 
 
index e9d5a9d..d7962c5 100644 (file)
 <?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">
-       <modelVersion>4.0.0</modelVersion>
+    <modelVersion>4.0.0</modelVersion>
 
-       <parent>
-               <groupId>org.onap.ccsdk.parent</groupId>
-               <artifactId>spring-boot-starter-parent</artifactId>
-               <version>1.5.2-SNAPSHOT</version>
-       </parent>
+    <parent>
+        <groupId>org.onap.ccsdk.parent</groupId>
+        <artifactId>spring-boot-starter-parent</artifactId>
+        <version>1.5.2-SNAPSHOT</version>
+    </parent>
 
-       <groupId>org.onap.ccsdk.sli.core</groupId>
-       <artifactId>sliapi-springboot</artifactId>
-       <version>0.7.1-SNAPSHOT</version>
-       <packaging>jar</packaging>
+    <groupId>org.onap.ccsdk.sli.core</groupId>
+    <artifactId>sliapi-springboot</artifactId>
+    <version>0.7.1-SNAPSHOT</version>
+    <packaging>jar</packaging>
 
-       <name>sliapi-springboot</name>
+    <name>sliapi-springboot</name>
 
-       <dependencies>
-               <dependency>
-                       <groupId>io.swagger</groupId>
-                       <artifactId>swagger-annotations</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.springframework.boot</groupId>
-                       <artifactId>spring-boot-starter-web</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.springframework.boot</groupId>
-                       <artifactId>spring-boot-starter-data-jpa</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>io.springfox</groupId>
-                       <artifactId>springfox-swagger2</artifactId>
-                       <version>2.9.2</version>
-               </dependency>
-               <dependency>
-                       <groupId>io.springfox</groupId>
-                       <artifactId>springfox-swagger-ui</artifactId>
-                       <version>2.9.2</version>
-               </dependency>
-               <dependency>
-                       <groupId>${project.groupId}</groupId>
-                       <artifactId>sli-provider-base</artifactId>
-                       <version>${project.version}</version>
-               </dependency>
-               <dependency>
-                       <groupId>com.google.code.gson</groupId>
-                       <artifactId>gson</artifactId>
-               </dependency>
-               <dependency>
-                       <groupId>org.apache.derby</groupId>
-                       <artifactId>derby</artifactId>
-                       <scope>runtime</scope>
-               </dependency>
-       </dependencies>
+    <dependencies>
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-annotations</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+            <version>2.9.2</version>
+        </dependency>
 
-       <build>
-               <plugins>
-                       <plugin>
-                               <groupId>io.swagger</groupId>
-                               <artifactId>swagger-codegen-maven-plugin</artifactId>
-                               <version>2.3.1</version>
-                               <executions>
-                                       <execution>
-                                               <goals>
-                                                       <goal>generate</goal>
-                                               </goals>
-                                               <configuration>
-                                                       <output>target/generated-sources</output>
-                                                       <inputSpec>${project.basedir}/../model/src/main/resources/sli-api.20161110.yaml</inputSpec>
-                                                       <language>spring</language>
-                                                       <apiPackage>org.onap.ccsdk.sli.core.sliapi.springboot</apiPackage>
-                                                       <modelPackage>org.onap.ccsdk.sli.core.sliapi.model</modelPackage>
-                                                       <invokerPackage>org.onap.ccsdk.sli.core.sliapi.springboot</invokerPackage>
-                                                       <generateApis>true</generateApis>
-                                                       <generateApiTests>true</generateApiTests>
-                                                       <ignoreFileOverride>${project.basedir}/.swagger-codegen-ignore</ignoreFileOverride>
-                                                       <withXml>true</withXml>
-                                                       <configOptions>
-                                                               <java8>true</java8>
-                                                               <springBootVersion>2.2.4-RELEASE</springBootVersion>
-                                                       </configOptions>
-                                               </configuration>
-                                       </execution>
-                               </executions>
-                       </plugin>
-                       <plugin>
-                               <groupId>org.springframework.boot</groupId>
-                               <artifactId>spring-boot-maven-plugin</artifactId>
-                               <executions>
-                                       <execution>
-                                               <goals>
-                                                       <goal>repackage</goal>
-                                               </goals>
-                                       </execution>
-                               </executions>
-                       </plugin>
-               </plugins>
-       </build>
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+            <version>2.9.2</version>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>sli-provider-base</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.derby</groupId>
+            <artifactId>derby</artifactId>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>io.swagger</groupId>
+                <artifactId>swagger-codegen-maven-plugin</artifactId>
+                <version>2.3.1</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>generate</goal>
+                        </goals>
+                        <configuration>
+                            <output>target/generated-sources</output>
+                            <inputSpec>${project.basedir}/../model/src/main/resources/sli-api.20161110.yaml</inputSpec>
+                            <language>spring</language>
+                            <apiPackage>org.onap.ccsdk.sli.core.sliapi.springboot</apiPackage>
+                            <modelPackage>org.onap.ccsdk.sli.core.sliapi.model</modelPackage>
+                            <invokerPackage>org.onap.ccsdk.sli.core.sliapi.springboot</invokerPackage>
+                            <generateApis>true</generateApis>
+                            <generateApiTests>true</generateApiTests>
+                            <ignoreFileOverride>${project.basedir}/.swagger-codegen-ignore</ignoreFileOverride>
+                            <withXml>true</withXml>
+                            <configOptions>
+                                <java8>true</java8>
+                                <springBootVersion>2.2.4-RELEASE</springBootVersion>
+                            </configOptions>
+
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <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>
index 8d2553a..e2cd864 100644 (file)
@@ -2,11 +2,16 @@ package org.onap.ccsdk.sli.core.sliapi.springboot;
 
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Properties;
 
 import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
 
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.google.gson.*;
 import org.onap.ccsdk.sli.core.sli.ConfigurationException;
 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
 import org.onap.ccsdk.sli.core.sli.SvcLogicLoader;
@@ -17,6 +22,7 @@ import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicPropertiesProvider;
 import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicResolver;
 import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicServiceBase;
 import org.onap.ccsdk.sli.core.sli.provider.base.SvcLogicServiceImplBase;
+import org.onap.ccsdk.sli.core.sliapi.model.ExecuteGraphInput;
 import org.onap.ccsdk.sli.core.sliapi.model.ResponseFields;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -33,6 +39,8 @@ public class RestconfApiController implements RestconfApi {
 
        private final ObjectMapper objectMapper;
        private final HttpServletRequest request;
+
+
        private static SvcLogicServiceBase svc;
        private static final Logger log = LoggerFactory.getLogger(RestconfApiController.class);
 
@@ -90,17 +98,11 @@ public class RestconfApiController implements RestconfApi {
                        log.info("Calling SLI-API:healthcheck DG");
                        Properties inputProps = new Properties();
                        Properties respProps = svc.execute("sli", "healthcheck", null, "sync", inputProps);
-                       if (respProps == null) {
-                               log.info("DG execution returned no properties!");
-                       } else {
-                               log.info("DG execution returned properties");
-                               for (String key : respProps.stringPropertyNames()) {
-                                       log.info("DG returned property " + key + " = " + respProps.getProperty(key));
-                               }
-                       }
+
                        resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
                        resp.setResponseCode(respProps.getProperty("error-code", "200"));
                        resp.setResponseMessage(respProps.getProperty("error-message", "Success"));
+                       resp.setContextMemoryJson(propsToJson(respProps, "context-memory"));
 
                        return (new ResponseEntity<>(resp, HttpStatus.OK));
                } catch (Exception e) {
@@ -113,6 +115,32 @@ public class RestconfApiController implements RestconfApi {
                return (new ResponseEntity<>(resp, HttpStatus.INTERNAL_SERVER_ERROR));
        }
 
+       @Override
+       public ResponseEntity<ResponseFields> vlbcheck() {
+               ResponseFields resp = new ResponseFields();
+
+               try {
+                       log.info("Calling SLI-API:vlbcheck DG");
+                       Properties inputProps = new Properties();
+                       Properties respProps = svc.execute("sli", "vlbcheck", null, "sync", inputProps);
+
+                       resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
+                       resp.setResponseCode(respProps.getProperty("error-code", "200"));
+                       resp.setResponseMessage(respProps.getProperty("error-message", "Success"));
+                       resp.setContextMemoryJson(propsToJson(respProps, "context-memory"));
+
+                       return (new ResponseEntity<>(resp, HttpStatus.OK));
+               } catch (Exception e) {
+                       resp.setAckFinalIndicator("true");
+                       resp.setResponseCode("500");
+                       resp.setResponseMessage(e.getMessage());
+                       log.error("Error calling vlbcheck directed graph", e);
+
+               }
+               return (new ResponseEntity<>(resp, HttpStatus.INTERNAL_SERVER_ERROR));
+       }
+
+
        @Override
        public Optional<ObjectMapper> getObjectMapper() {
                return Optional.ofNullable(objectMapper);
@@ -123,4 +151,107 @@ public class RestconfApiController implements RestconfApi {
                return Optional.ofNullable(request);
        }
 
+       @Override
+       public ResponseEntity<ResponseFields> executeGraph(@Valid ExecuteGraphInput executeGraphInput) {
+               Properties parms = new Properties();
+               ResponseFields resp = new ResponseFields();
+               String executeGraphInputJson = null;
+
+               try {
+                        executeGraphInputJson = objectMapper.writeValueAsString(executeGraphInput);
+                        log.info("Input as JSON is "+executeGraphInputJson);
+               } catch (JsonProcessingException e) {
+
+                       resp.setAckFinalIndicator("true");
+                       resp.setResponseCode("500");
+                       resp.setResponseMessage(e.getMessage());
+                       log.error("Cannot create JSON from input object", e);
+                       return (new ResponseEntity<>(resp, HttpStatus.INTERNAL_SERVER_ERROR));
+
+               }
+               JsonObject jsonInput = new Gson().fromJson(executeGraphInputJson, JsonObject.class);
+               JsonObject passthroughObj = jsonInput.get("input").getAsJsonObject();
+
+               writeResponseToCtx(passthroughObj.toString(), parms, "input");
+
+
+               try {
+                       // Any of these can throw a nullpointer exception
+                       String calledModule = executeGraphInput.getInput().getModuleName();
+                       String calledRpc = executeGraphInput.getInput().getRpcName();
+                       String modeStr = executeGraphInput.getInput().getMode();
+                       // execute should only throw a SvcLogicException
+                       Properties respProps = svc.execute(calledModule, calledRpc, null, modeStr, parms);
+
+                       resp.setAckFinalIndicator(respProps.getProperty("ack-final-indicator", "Y"));
+                       resp.setResponseCode(respProps.getProperty("error-code", "200"));
+                       resp.setResponseMessage(respProps.getProperty("error-message", "SUCCESS"));
+                       resp.setContextMemoryJson(propsToJson(respProps, "context-memory"));
+                       return (new ResponseEntity<>(resp, HttpStatus.valueOf(Integer.parseInt(resp.getResponseCode()))));
+
+               } catch (NullPointerException npe) {
+                       resp.setAckFinalIndicator("true");
+                       resp.setResponseCode("500");
+                       resp.setResponseMessage("Check that you populated module, rpc and or mode correctly.");
+
+                       return (new ResponseEntity<>(resp, HttpStatus.INTERNAL_SERVER_ERROR));
+               } catch (SvcLogicException e) {
+                       resp.setAckFinalIndicator("true");
+                       resp.setResponseCode("500");
+                       resp.setResponseMessage(e.getMessage());
+
+                       return (new ResponseEntity<>(resp, HttpStatus.INTERNAL_SERVER_ERROR));
+               }
+       }
+
+       public static void writeResponseToCtx(String resp, Properties ctx, String prefix) {
+               JsonParser jp = new JsonParser();
+               JsonElement element = jp.parse(resp);
+               writeJsonObject(element.getAsJsonObject(), ctx, prefix + ".");
+       }
+
+       public static void writeJsonObject(JsonObject obj, Properties ctx, String root) {
+               for (Map.Entry<String, JsonElement> entry : obj.entrySet()) {
+                       if (entry.getValue().isJsonObject()) {
+                               writeJsonObject(entry.getValue().getAsJsonObject(), ctx, root + entry.getKey() + ".");
+                       } else if (entry.getValue().isJsonArray()) {
+                               JsonArray array = entry.getValue().getAsJsonArray();
+                               ctx.put(root + entry.getKey() + "_length", String.valueOf(array.size()));
+                               Integer arrayIdx = 0;
+                               for (JsonElement element : array) {
+                                       if (element.isJsonObject()) {
+                                               writeJsonObject(element.getAsJsonObject(), ctx, root + entry.getKey() + "[" + arrayIdx + "].");
+                                       }
+                                       arrayIdx++;
+                               }
+                       } else {
+                               if (entry.getValue() instanceof JsonNull) {
+                                       log.info("Skipping parameter "+entry.getKey()+" with null value");
+
+                               } else {
+                                       ctx.put(root + entry.getKey(), entry.getValue().getAsString());
+                               }
+                       }
+               }
+       }
+
+       public static String propsToJson(Properties props, String root)
+       {
+               StringBuffer sbuff = new StringBuffer();
+
+               sbuff.append("{ \""+root+"\" : { ");
+               boolean needComma = false;
+               for (Map.Entry<Object, Object> prop : props.entrySet()) {
+                       sbuff.append("\""+(String) prop.getKey()+"\" : \""+(String)prop.getValue()+"\"");
+                       if (needComma) {
+                               sbuff.append(" , ");
+                       } else {
+                               needComma = true;
+                       }
+               }
+               sbuff.append(" } }");
+
+               return(sbuff.toString());
+       }
+
 }
index 6218d11..64415bd 100644 (file)
@@ -5,4 +5,4 @@ spring.jackson.date-format=org.onap.ccsdk.sli.core.sliapi.springboot.RFC3339Date
 spring.jackson.serialization.WRITE_DATES_AS_TIMESTAMPS=false
 spring.datasource.url=jdbc:derby:sdnctl;create=true
 spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.DerbyTenSevenDialect
-spring.jpa.hibernate.ddl-auto=update
\ No newline at end of file
+spring.jpa.hibernate.ddl-auto=update
diff --git a/sliapi/springboot/src/main/resources/sli_vlbcheck.xml b/sliapi/springboot/src/main/resources/sli_vlbcheck.xml
new file mode 100644 (file)
index 0000000..820a85c
--- /dev/null
@@ -0,0 +1,27 @@
+<!--
+  ============LICENSE_START=======================================================
+  openECOMP : SDN-C
+  ================================================================================
+  Copyright (C) 2017 AT&T Intellectual Property. All rights
+                                                       reserved.
+  ================================================================================
+  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=========================================================
+  -->
+
+<service-logic xmlns="http://www.onap.org/sdnc/svclogic"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://www.onap.org/sdnc/svclogic ./svclogic.xsd" module='sli' version='0.7.0'><method rpc='vlbcheck' mode='sync'>
+<set>
+<parameter name='error-code' value='200' />
+<parameter name='error-message' value='SDN-C is healthy'/>
+<parameter name='ack-final' value='Y'/>
+</set></method></service-logic>
index 426960f..1d90ab9 100644 (file)
@@ -25,3 +25,5 @@ org.onap.ccsdk.sli.jdbc.driver=org.apache.derby.jdbc.EmbeddedDriver
 org.onap.ccsdk.sli.jdbc.database = sdnctl
 org.onap.ccsdk.sli.jdbc.user = test
 org.onap.ccsdk.sli.jdbc.password = test
+
+sliapi.serviceLogicDirectory=/opt/onap/sdnc/svclogic/graphs
diff --git a/sliapi/springboot/src/test/java/org/onap/ccsdk/sli/core/sliapi/springboot/RestconfApiControllerTest.java b/sliapi/springboot/src/test/java/org/onap/ccsdk/sli/core/sliapi/springboot/RestconfApiControllerTest.java
new file mode 100644 (file)
index 0000000..af55a51
--- /dev/null
@@ -0,0 +1,99 @@
+package org.onap.ccsdk.sli.core.sliapi.springboot;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.ccsdk.sli.core.sliapi.model.ExecuteGraphInput;
+import org.onap.ccsdk.sli.core.sliapi.model.ExecutegraphinputInput;
+import org.onap.ccsdk.sli.core.sliapi.model.ResponseFields;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.MvcResult;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+
+import static org.junit.Assert.assertEquals;
+
+@RunWith(SpringRunner.class)
+@WebMvcTest(RestconfApiController.class)
+public class RestconfApiControllerTest {
+
+    @Autowired
+    private MockMvc mvc;
+
+    @MockBean
+    private RestconfApiController restconfApiController;
+
+    @Test
+    public void testHealthcheck() throws Exception {
+        String url = "/restconf/operations/SLI-API:healthcheck";
+
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(url).contentType(MediaType.APPLICATION_JSON_VALUE).content("")).andReturn();
+
+        assertEquals(200, mvcResult.getResponse().getStatus());
+    }
+
+    @Test
+    public void testVlbcheck() throws Exception {
+        String url = "/restconf/operations/SLI-API:vlbcheck";
+
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(url).contentType(MediaType.APPLICATION_JSON_VALUE).content("")).andReturn();
+
+        assertEquals(200, mvcResult.getResponse().getStatus());
+    }
+
+    @Test
+    public void testExecuteHealthcheck() throws Exception {
+        String url = "/restconf/operations/SLI-API:execute-graph";
+
+        ExecuteGraphInput executeGraphInput = new ExecuteGraphInput();
+        ExecutegraphinputInput executeGraphData = new ExecutegraphinputInput();
+
+        executeGraphData.setModuleName("sli");
+        executeGraphData.setRpcName("healthcheck");
+        executeGraphData.setMode("sync");
+        executeGraphInput.setInput(executeGraphData);
+
+        String jsonString = mapToJson(executeGraphInput);
+
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(url).contentType(MediaType.APPLICATION_JSON_VALUE).content(jsonString)).andReturn();
+
+        assertEquals(200, mvcResult.getResponse().getStatus());
+
+    }
+
+    @Test
+    public void testExecuteMissingDg() throws Exception {
+        String url = "/restconf/operations/SLI-API:execute-graph";
+
+        ExecuteGraphInput executeGraphInput = new ExecuteGraphInput();
+        ExecutegraphinputInput executeGraphData = new ExecutegraphinputInput();
+
+        executeGraphData.setModuleName("sli");
+        executeGraphData.setRpcName("noSuchRPC");
+        executeGraphData.setMode("sync");
+        executeGraphInput.setInput(executeGraphData);
+
+        String jsonString = mapToJson(executeGraphInput);
+
+        MvcResult mvcResult = mvc.perform(MockMvcRequestBuilders.post(url).contentType(MediaType.APPLICATION_JSON_VALUE).content(jsonString)).andReturn();
+
+        // Note: this really should return 401 (and truly does), but mockito always returns a 200.
+        assertEquals(200, mvcResult.getResponse().getStatus());
+
+    }
+
+    private String mapToJson(Object obj) throws JsonProcessingException {
+        ObjectMapper objectMapper = new ObjectMapper();
+        return objectMapper.writeValueAsString(obj);
+    }
+
+    private ResponseFields respFromJson(String jsonString) throws JsonProcessingException {
+        ObjectMapper objectMapper = new ObjectMapper();
+        return(objectMapper.readValue(jsonString, ResponseFields.class));
+    }
+}