ApiDocServiceImpl.getListOfMounts should return an Object instead of JSON string 29/78729/4
authorwsd <wusandi@163.com>
Thu, 13 Dec 2018 05:38:44 +0000 (13:38 +0800)
committerTom Pantelis <tompantelis@gmail.com>
Thu, 13 Dec 2018 14:04:17 +0000 (14:04 +0000)
Problem: when swagger access mounted resources via /apidoc/explorer/index.html,
the explorer can't show mounted resources, only some undefined.

Reason: The JSON string in response entity is escaped by GsonProvider.

JIRA: NETCONF-587
Change-Id: Ida30a50fd7168d96904ba59fb275cf4d24817bfa
Signed-off-by: wsd <wusandi@163.com>
restconf/sal-rest-docgen/pom.xml
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/impl/ApiDocServiceImpl.java
restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/swagger/MountPointInstance.java [new file with mode: 0644]
restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocServiceImplTest.java [new file with mode: 0644]

index 5052092a0a804bfc9a464139a08fbe34276e546d..156b378ff5af9c579356bba25a711b7a27a88a74 100644 (file)
       <groupId>org.opendaylight.aaa.web</groupId>
       <artifactId>servlet-api</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.glassfish.jersey.core</groupId>
+      <artifactId>jersey-server</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>
index fc84ee54b65abcfb8984febfed929ae18d8ca504..c9726b0e10b1840a20dc74de5b14e1565f65deb4 100644 (file)
@@ -7,20 +7,17 @@
  */
 package org.opendaylight.netconf.sal.rest.doc.impl;
 
-import com.fasterxml.jackson.core.JsonFactory;
-import com.fasterxml.jackson.core.JsonGenerator;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.UnsupportedEncodingException;
-import java.nio.charset.StandardCharsets;
-import java.util.Map.Entry;
+import java.util.List;
 import java.util.Objects;
+import java.util.stream.Collectors;
+
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
+
 import org.opendaylight.netconf.sal.rest.doc.api.ApiDocService;
 import org.opendaylight.netconf.sal.rest.doc.mountpoints.MountPointSwagger;
 import org.opendaylight.netconf.sal.rest.doc.swagger.ApiDeclaration;
+import org.opendaylight.netconf.sal.rest.doc.swagger.MountPointInstance;
 import org.opendaylight.netconf.sal.rest.doc.swagger.ResourceList;
 
 /**
@@ -96,29 +93,16 @@ public class ApiDocServiceImpl implements ApiDocService {
 
     @Override
     public synchronized Response getListOfMounts(final UriInfo uriInfo) {
-        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        try (OutputStreamWriter streamWriter = new OutputStreamWriter(baos, StandardCharsets.UTF_8)) {
-            JsonGenerator writer = new JsonFactory().createGenerator(streamWriter);
-            writer.writeStartArray();
-            for (final Entry<String, Long> entry : mountPointSwaggerDraft02.getInstanceIdentifiers()
-                    .entrySet()) {
-                writer.writeStartObject();
-                writer.writeObjectField("instance", entry.getKey());
-                writer.writeObjectField("id", entry.getValue());
-                writer.writeEndObject();
-            }
-            writer.writeEndArray();
-            writer.flush();
-        } catch (IOException e) {
-            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
-        }
-
-        try {
-            String responseStr = baos.toString(StandardCharsets.UTF_8.name());
-            return Response.status(Response.Status.OK).entity(responseStr).build();
-        } catch (UnsupportedEncodingException e) {
-            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(e.getMessage()).build();
+        final MountPointSwagger mountPointSwagger;
+        if (isNew(uriInfo)) {
+            mountPointSwagger = mountPointSwaggerRFC8040;
+        } else {
+            mountPointSwagger = mountPointSwaggerDraft02;
         }
+        final List<MountPointInstance> entity = mountPointSwagger
+                .getInstanceIdentifiers().entrySet().stream()
+                .map(MountPointInstance::new).collect(Collectors.toList());
+        return Response.ok(entity).build();
     }
 
     @Override
diff --git a/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/swagger/MountPointInstance.java b/restconf/sal-rest-docgen/src/main/java/org/opendaylight/netconf/sal/rest/doc/swagger/MountPointInstance.java
new file mode 100644 (file)
index 0000000..aa0bb15
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018 ZTE Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.sal.rest.doc.swagger;
+
+import java.util.Map;
+
+public class MountPointInstance {
+    private final String instance;
+    private final Long id;
+
+    public MountPointInstance(Map.Entry<String, Long> entry) {
+        this.instance = entry.getKey();
+        this.id = entry.getValue();
+    }
+
+    public String getInstance() {
+        return instance;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+}
diff --git a/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocServiceImplTest.java b/restconf/sal-rest-docgen/src/test/java/org/opendaylight/controller/sal/rest/doc/impl/ApiDocServiceImplTest.java
new file mode 100644 (file)
index 0000000..d2bbcfa
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2018 ZTE Corporation and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.rest.doc.impl;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+import javax.ws.rs.core.UriInfo;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.mdsal.dom.api.DOMMountPoint;
+import org.opendaylight.mdsal.dom.api.DOMMountPointService;
+import org.opendaylight.mdsal.dom.api.DOMSchemaService;
+import org.opendaylight.netconf.sal.rest.doc.api.ApiDocService;
+import org.opendaylight.netconf.sal.rest.doc.impl.ApiDocGeneratorDraftO2;
+import org.opendaylight.netconf.sal.rest.doc.impl.ApiDocGeneratorRFC8040;
+import org.opendaylight.netconf.sal.rest.doc.impl.ApiDocServiceImpl;
+import org.opendaylight.netconf.sal.rest.doc.impl.MountPointSwaggerGeneratorDraft02;
+import org.opendaylight.netconf.sal.rest.doc.impl.MountPointSwaggerGeneratorRFC8040;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class ApiDocServiceImplTest {
+    private static final String HTTP_URL = "http://localhost/path";
+    private static final YangInstanceIdentifier INSTANCE_ID = YangInstanceIdentifier.builder()
+            .node(QName.create("", "nodes"))
+            .node(QName.create("", "node"))
+            .nodeWithKey(QName.create("", "node"), QName.create("", "id"), "123").build();
+    private static final String INSTANCE_URL = "/nodes/node/123/";
+    private DocGenTestHelper helper;
+    private ApiDocService apiDocService;
+
+
+    @SuppressWarnings("resource")
+    @Before
+    public void setUp() throws Exception {
+        this.helper = new DocGenTestHelper();
+        this.helper.setUp();
+
+        final SchemaContext context = this.helper.createMockSchemaContext();
+        final DOMSchemaService schemaService = this.helper.createMockSchemaService(context);
+
+        final DOMMountPoint mountPoint = mock(DOMMountPoint.class);
+        when(mountPoint.getSchemaContext()).thenReturn(context);
+
+        final DOMMountPointService service = mock(DOMMountPointService.class);
+        when(service.getMountPoint(INSTANCE_ID)).thenReturn(java.util.Optional.of(mountPoint));
+        MountPointSwaggerGeneratorDraft02 swagger =
+                new MountPointSwaggerGeneratorDraft02(schemaService, service);
+        swagger.getMountPointSwagger().onMountPointCreated(INSTANCE_ID);
+        this.apiDocService = new ApiDocServiceImpl(
+                swagger,
+                new MountPointSwaggerGeneratorRFC8040(schemaService, service),
+                new ApiDocGeneratorDraftO2(schemaService),
+                new ApiDocGeneratorRFC8040(schemaService));
+    }
+
+    @Test
+    public void getListOfMounts() throws java.net.URISyntaxException {
+        final UriInfo mockInfo = this.helper.createMockUriInfo(HTTP_URL);
+        // simulate the behavior of GsonProvider
+        Gson gson = (new GsonBuilder()).serializeNulls()
+                .enableComplexMapKeySerialization().create();
+        String result = gson.toJson(apiDocService.getListOfMounts(mockInfo).getEntity());
+        Assert.assertEquals("[{\"instance\":\"/nodes/node/123/\",\"id\":1}]", result);
+    }
+}