Minor changes 28/2328/3
authorPatrikBuhr <patrik.buhr@est.tech>
Fri, 24 Jan 2020 08:56:41 +0000 (09:56 +0100)
committerPatrikBuhr <patrik.buhr@est.tech>
Mon, 27 Jan 2020 10:03:38 +0000 (11:03 +0100)
Added DELETE Service REST call
Bugfix in dashboard, delete and put policy was broken
Formatting

Change-Id: I66d8aade6842053a6951166df66bc4d1fb8d4990
Issue-ID: NONRTRIC-84
Signed-off-by: PatrikBuhr <patrik.buhr@est.tech>
dashboard/webapp-backend/src/main/java/org/oransc/ric/portal/dashboard/policyagentapi/PolicyAgentApiImpl.java
policy-agent/src/main/java/org/oransc/policyagent/controllers/ServiceController.java
policy-agent/src/main/java/org/oransc/policyagent/repository/Service.java
policy-agent/src/main/java/org/oransc/policyagent/repository/Services.java
policy-agent/src/main/java/org/oransc/policyagent/tasks/ServiceSupervision.java
policy-agent/src/test/java/org/oransc/policyagent/ApplicationTest.java
policy-agent/src/test/java/org/oransc/policyagent/MockPolicyAgent.java

index c661e66..19865e1 100644 (file)
@@ -55,14 +55,14 @@ public class PolicyAgentApiImpl implements PolicyAgentApi {
     RestTemplate restTemplate = new RestTemplate();
 
     private static com.google.gson.Gson gson = new GsonBuilder() //
-        .serializeNulls() //
-        .create(); //
+            .serializeNulls() //
+            .create(); //
 
     private final String urlPrefix;
 
     @Autowired
     public PolicyAgentApiImpl(
-        @org.springframework.beans.factory.annotation.Value("${policycontroller.url.prefix}") final String urlPrefix) {
+            @org.springframework.beans.factory.annotation.Value("${policycontroller.url.prefix}") final String urlPrefix) {
         logger.debug("ctor prefix '{}'", urlPrefix);
         this.urlPrefix = urlPrefix;
     }
@@ -115,7 +115,8 @@ public class PolicyAgentApiImpl implements PolicyAgentApi {
         }
 
         try {
-            Type listType = new TypeToken<List<ImmutablePolicyInfo>>() {}.getType();
+            Type listType = new TypeToken<List<ImmutablePolicyInfo>>() {
+            }.getType();
             List<PolicyInfo> rspParsed = gson.fromJson(rsp.getBody(), listType);
             PolicyInstances result = new PolicyInstances();
             for (PolicyInfo p : rspParsed) {
@@ -137,17 +138,17 @@ public class PolicyAgentApiImpl implements PolicyAgentApi {
 
     @Override
     public ResponseEntity<String> putPolicy(String policyTypeIdString, String policyInstanceId, String json,
-        String ric) {
+            String ric) {
         String url = baseUrl() + "/policy?type={type}&instance={instance}&ric={ric}&service={service}";
         Map<String, ?> uriVariables = Map.of( //
-            "type", policyTypeIdString, //
-            "instance", policyInstanceId, //
-            "ric", ric, //
-            "service", "dashboard");
+                "type", policyTypeIdString, //
+                "instance", policyInstanceId, //
+                "ric", ric, //
+                "service", "dashboard");
 
         try {
             this.restTemplate.put(url, json, uriVariables);
-            return new ResponseEntity<>("Policy was put successfully", HttpStatus.OK);
+            return new ResponseEntity<>(HttpStatus.OK);
         } catch (Exception e) {
             return new ResponseEntity<>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
         }
@@ -159,7 +160,7 @@ public class PolicyAgentApiImpl implements PolicyAgentApi {
         Map<String, ?> uriVariables = Map.of("instance", policyInstanceId);
         try {
             this.restTemplate.delete(url, uriVariables);
-            return new ResponseEntity<>("Policy was deleted successfully", HttpStatus.NO_CONTENT);
+            return new ResponseEntity<>(HttpStatus.OK);
         } catch (Exception e) {
             return new ResponseEntity<>(e.getMessage(), HttpStatus.NOT_FOUND);
         }
@@ -183,7 +184,8 @@ public class PolicyAgentApiImpl implements PolicyAgentApi {
         String rsp = this.restTemplate.getForObject(url, String.class, uriVariables);
 
         try {
-            Type listType = new TypeToken<List<ImmutableRicInfo>>() {}.getType();
+            Type listType = new TypeToken<List<ImmutableRicInfo>>() {
+            }.getType();
             List<RicInfo> rspParsed = gson.fromJson(rsp, listType);
             Collection<String> result = new Vector<>(rspParsed.size());
             for (RicInfo ric : rspParsed) {
index bda5e09..cc1d711 100644 (file)
@@ -23,16 +23,23 @@ package org.oransc.policyagent.controllers;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
 import java.time.Duration;
 import java.util.Collection;
 import java.util.Vector;
 
 import org.oransc.policyagent.exceptions.ServiceException;
+import org.oransc.policyagent.repository.Policies;
+import org.oransc.policyagent.repository.Policy;
 import org.oransc.policyagent.repository.Service;
 import org.oransc.policyagent.repository.Services;
 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.PutMapping;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -43,31 +50,40 @@ import org.springframework.web.bind.annotation.RestController;
 public class ServiceController {
 
     private final Services services;
+    private final Policies policies;
+
     private static Gson gson = new GsonBuilder() //
         .serializeNulls() //
         .create(); //
 
     @Autowired
-    ServiceController(Services services) {
+    ServiceController(Services services, Policies policies) {
         this.services = services;
+        this.policies = policies;
     }
 
-    @GetMapping("/service")
-    public ResponseEntity<String> getService( //
-        @RequestParam(name = "name", required = true) String name) {
-        try {
-            Service s = services.getService(name);
-            String res = gson.toJson(toServiceStatus(s));
-            return new ResponseEntity<String>(res, HttpStatus.OK);
+    @GetMapping("/services")
+    @ApiOperation(value = "Returns service information", response = ServiceStatus.class)
+    @ApiResponses(value = {@ApiResponse(code = 200, message = "OK")})
+    public ResponseEntity<String> getServices( //
+        @RequestParam(name = "name", required = false) String name) {
 
-        } catch (ServiceException e) {
-            return new ResponseEntity<String>(e.getMessage(), HttpStatus.NO_CONTENT);
+        Collection<ServiceStatus> servicesStatus = new Vector<>();
+        synchronized (this.services) {
+            for (Service s : this.services.getAll()) {
+                if (name == null || name.equals(s.name())) {
+                    servicesStatus.add(toServiceStatus(s));
+                }
+            }
         }
+
+        String res = gson.toJson(servicesStatus);
+        return new ResponseEntity<String>(res, HttpStatus.OK);
     }
 
     private ServiceStatus toServiceStatus(Service s) {
         return ImmutableServiceStatus.builder() //
-            .name(s.getName()) //
+            .name(s.name()) //
             .keepAliveInterval(s.getKeepAliveInterval().toSeconds()) //
             .timeSincePing(s.timeSinceLastPing().toSeconds()) //
             .build();
@@ -85,31 +101,39 @@ public class ServiceController {
         }
     }
 
-    private Service toService(ServiceRegistrationInfo s) {
-        return new Service(s.name(), Duration.ofSeconds(s.keepAliveInterval()), s.callbackUrl());
+    @DeleteMapping("/services")
+    public ResponseEntity<String> deleteService( //
+        @RequestParam(name = "name", required = true) String name) {
+        try {
+            Service service = removeService(name);
+            // Remove the policies from the repo and let the consistency monitoring
+            // do the rest.
+            removePolicies(service);
+            return new ResponseEntity<String>("OK", HttpStatus.NO_CONTENT);
+        } catch (Exception e) {
+            return new ResponseEntity<String>(e.getMessage(), HttpStatus.NO_CONTENT);
+        }
     }
 
-    @GetMapping("/services")
-    public ResponseEntity<?> getServices() {
-        Collection<ServiceStatus> result = new Vector<>();
+    private Service removeService(String name) throws ServiceException {
         synchronized (this.services) {
-            for (Service s : this.services.getAll()) {
-                result.add(toServiceStatus(s));
-            }
+            Service service = this.services.getService(name);
+            this.services.remove(service.name());
+            return service;
         }
-        return new ResponseEntity<>(gson.toJson(result), HttpStatus.OK);
     }
 
-    @PutMapping("/service/ping")
-    public ResponseEntity<String> ping( //
-        @RequestBody String name) {
-        try {
-            Service s = services.getService(name);
-            s.ping();
-            return new ResponseEntity<String>("OK", HttpStatus.OK);
-        } catch (ServiceException e) {
-            return new ResponseEntity<String>(e.getMessage(), HttpStatus.NO_CONTENT);
+    private void removePolicies(Service service) {
+        synchronized (this.policies) {
+            Vector<Policy> policyList = new Vector<>(this.policies.getForService(service.name()));
+            for (Policy policy : policyList) {
+                this.policies.remove(policy);
+            }
         }
     }
 
+    private Service toService(ServiceRegistrationInfo s) {
+        return new Service(s.name(), Duration.ofSeconds(s.keepAliveInterval()), s.callbackUrl());
+    }
+
 }
index 6458dbb..18a85a9 100644 (file)
@@ -36,7 +36,7 @@ public class Service {
         ping();
     }
 
-    public synchronized String getName() {
+    public synchronized String name() {
         return this.name;
     }
 
@@ -44,7 +44,7 @@ public class Service {
         return this.keepAliveInterval;
     }
 
-    public synchronized void ping() {
+    private synchronized void ping() {
         this.lastPing = Instant.now();
     }
 
index 2e1d8da..01d6a7a 100644 (file)
@@ -48,12 +48,20 @@ public class Services {
     }
 
     public synchronized void put(Service service) {
-        logger.debug("Put service: " + service.getName());
-        services.put(service.getName(), service);
+        logger.debug("Put service: " + service.name());
+        services.put(service.name(), service);
     }
 
     public synchronized Iterable<Service> getAll() {
         return services.values();
     }
 
+    public synchronized void remove(String name) {
+        services.remove(name);
+    }
+
+    public synchronized int size() {
+        return services.size();
+    }
+
 }
index d4b32e0..c10e004 100644 (file)
@@ -72,7 +72,7 @@ public class ServiceSupervision {
         synchronized (services) {
             return Flux.fromIterable(services.getAll()) //
                 .filter(service -> service.isExpired()) //
-                .doOnNext(service -> logger.info("Service is expired:" + service.getName())) //
+                .doOnNext(service -> logger.info("Service is expired:" + service.name())) //
                 .flatMap(service -> getAllPolicies(service)) //
                 .doOnNext(policy -> this.policies.remove(policy)) //
                 .flatMap(policy -> deletePolicyInRic(policy));
@@ -81,7 +81,7 @@ public class ServiceSupervision {
 
     private Flux<Policy> getAllPolicies(Service service) {
         synchronized (policies) {
-            return Flux.fromIterable(policies.getForService(service.getName()));
+            return Flux.fromIterable(policies.getForService(service.name()));
         }
     }
 
index 4270ded..5b1f3ca 100644 (file)
@@ -26,8 +26,11 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
 
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
-import com.google.gson.reflect.TypeToken;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Vector;
 
@@ -49,6 +52,7 @@ import org.oransc.policyagent.repository.PolicyType;
 import org.oransc.policyagent.repository.PolicyTypes;
 import org.oransc.policyagent.repository.Ric;
 import org.oransc.policyagent.repository.Rics;
+import org.oransc.policyagent.repository.Services;
 import org.oransc.policyagent.tasks.RepositorySupervision;
 import org.oransc.policyagent.utils.MockA1Client;
 import org.oransc.policyagent.utils.MockA1ClientFactory;
@@ -85,6 +89,9 @@ public class ApplicationTest {
     @Autowired
     RepositorySupervision supervision;
 
+    @Autowired
+    Services services;
+
     private static Gson gson = new GsonBuilder() //
         .serializeNulls() //
         .create(); //
@@ -284,14 +291,6 @@ public class ApplicationTest {
         assertThat(policies.size()).isEqualTo(0);
     }
 
-    private static <T> List<T> parseList(String json, Class<T> clazz) {
-        if (null == json) {
-            return null;
-        }
-        return gson.fromJson(json, new TypeToken<T>() {}.getType());
-
-    }
-
     @Test
     public void testGetPolicySchemas() throws Exception {
         reset();
@@ -305,13 +304,13 @@ public class ApplicationTest {
         assertThat(rsp).contains("type2");
         assertThat(rsp).contains("title");
 
-        List<String> info = parseList(rsp, String.class);
+        List<String> info = parseSchemas(rsp);
         assertEquals(2, info.size());
 
         url = baseUrl() + "/policy_schemas?ric=ric1";
         rsp = this.restTemplate.getForObject(url, String.class);
         assertThat(rsp).contains("type1");
-        info = parseList(rsp, String.class);
+        info = parseSchemas(rsp);
         assertEquals(1, info.size());
     }
 
@@ -393,21 +392,48 @@ public class ApplicationTest {
 
     @Test
     public void testPutAndGetService() throws Exception {
+        // PUT
         putService("name");
 
-        String url = baseUrl() + "/service?name=name";
+        // GET
+        String url = baseUrl() + "/services?name=name";
         String rsp = this.restTemplate.getForObject(url, String.class);
-        ServiceStatus status = gson.fromJson(rsp, ImmutableServiceStatus.class);
+        List<ImmutableServiceStatus> info = parseList(rsp, ImmutableServiceStatus.class);
+        assertThat(info.size() == 1);
+        ServiceStatus status = info.iterator().next();
         assertThat(status.keepAliveInterval() == 1);
         assertThat(status.name().equals("name"));
 
+        // GET (all)
         url = baseUrl() + "/services";
         rsp = this.restTemplate.getForObject(url, String.class);
         assertThat(rsp.contains("name"));
         System.out.println(rsp);
 
-        url = baseUrl() + "/service/ping";
-        this.restTemplate.put(url, "name");
+        // DELETE
+        assertThat(services.size() == 1);
+        url = baseUrl() + "/services?name=name";
+        this.restTemplate.delete(url);
+        assertThat(services.size() == 0);
+    }
+
+    private static <T> List<T> parseList(String jsonString, Class<T> clazz) {
+        List<T> result = new ArrayList<>();
+        JsonArray jsonArr = new JsonParser().parse(jsonString).getAsJsonArray();
+        for (JsonElement jsonElement : jsonArr) {
+            T o = gson.fromJson(jsonElement.toString(), clazz);
+            result.add(o);
+        }
+        return result;
+    }
+
+    private static List<String> parseSchemas(String jsonString) {
+        JsonArray arrayOfSchema = new JsonParser().parse(jsonString).getAsJsonArray();
+        List<String> result = new ArrayList<>();
+        for (JsonElement schemaObject : arrayOfSchema) {
+            result.add(schemaObject.toString());
+        }
+        return result;
     }
 
 }
index bbbc06d..b4c4129 100644 (file)
@@ -121,7 +121,6 @@ public class MockPolicyAgent {
                 }
             }
         }
-
     }
 
     @LocalServerPort