Add resouce publish request, response handling in cloud interface
authorMinji Park <minjii.park@samsung.com>
Thu, 25 Aug 2016 07:01:30 +0000 (16:01 +0900)
committerJee Hyeok Kim <jihyeok13.kim@samsung.com>
Fri, 26 Aug 2016 03:42:32 +0000 (03:42 +0000)
- resource publish request and response handling added in CI
  to append routing info to href

Change-Id: I4040d142648cab5a87a5241fc489530c6294ab32
Signed-off-by: Minji Park <minjii.park@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/10897
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Jee Hyeok Kim <jihyeok13.kim@samsung.com>
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/Constants.java
cloud/interface/src/main/java/org/iotivity/cloud/ciserver/resources/proxy/rd/ResourceDirectory.java
cloud/interface/src/test/java/org/iotivity/cloud/ciserver/resources/proxy/rd/ResourceDirectoryTest.java
cloud/resourcedirectory/src/main/java/org/iotivity/cloud/rdserver/resources/directory/rd/ResourceDirectoryResource.java

index 005c700..9ef30d0 100644 (file)
@@ -48,4 +48,7 @@ public class Constants extends OICConstants {
     public static final String REQ_PING_ARRAY      = "inarray";
     public static final String REQ_PING            = "in";
 
+    public static final String REQ_LINKS           = "links";
+    public static final String REQ_HREF            = "href";
+
 }
index 97f2f1e..fa024d0 100644 (file)
@@ -21,6 +21,7 @@
  */
 package org.iotivity.cloud.ciserver.resources.proxy.rd;
 
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 
@@ -52,31 +53,6 @@ public class ResourceDirectory extends Resource {
         mASServer = ConnectorPool.getConnection("account");
     }
 
-    class AccountReceiveHandler implements IResponseEventHandler {
-        private Device   mSrcDevice;
-        private IRequest mRequest;
-
-        public AccountReceiveHandler(IRequest request, Device srcDevice) {
-            mSrcDevice = srcDevice;
-            mRequest = request;
-        }
-
-        @Override
-        public void onResponseReceived(IResponse response)
-                throws ClientException {
-
-            switch (response.getStatus()) {
-                case CHANGED:
-                    mRDServer.sendRequest(mRequest, mSrcDevice);
-                    break;
-
-                default:
-                    mSrcDevice.sendResponse(MessageBuilder.createResponse(
-                            mRequest, ResponseStatus.BAD_REQUEST));
-            }
-        }
-    }
-
     @Override
     public void onDefaultRequestReceived(Device srcDevice, IRequest request)
             throws ServerException {
@@ -96,23 +72,176 @@ public class ResourceDirectory extends Resource {
 
                 HashMap<String, Object> requestPayload = new HashMap<>();
 
-                requestPayload.put(Constants.REQ_DEVICE_LIST,
-                        Arrays.asList(di));
+                requestPayload
+                        .put(Constants.REQ_DEVICE_LIST, Arrays.asList(di));
                 IRequest requestToAS = MessageBuilder.createRequest(
                         RequestMethod.POST, uriPath.toString(), null,
                         ContentFormat.APPLICATION_CBOR,
                         mCbor.encodingPayloadToCbor(requestPayload));
 
-                mASServer.sendRequest(requestToAS,
-                        new AccountReceiveHandler(request, srcDevice));
+                mASServer.sendRequest(requestToAS, new AccountReceiveHandler(
+                        request, srcDevice));
                 break;
 
             case DELETE:
                 mRDServer.sendRequest(request, srcDevice);
                 break;
             default:
-                throw new BadRequestException(
-                        request.getMethod() + " request type is not support");
+                throw new BadRequestException(request.getMethod()
+                        + " request type is not support");
+        }
+    }
+
+    class AccountReceiveHandler implements IResponseEventHandler {
+        private Device   mSrcDevice;
+        private IRequest mRequest;
+
+        public AccountReceiveHandler(IRequest request, Device srcDevice) {
+            mSrcDevice = srcDevice;
+            mRequest = request;
+        }
+
+        @Override
+        public void onResponseReceived(IResponse response)
+                throws ClientException {
+
+            switch (response.getStatus()) {
+                case CHANGED:
+
+                    byte[] convertedPayload = convertPublishHref(mRequest,
+                            mSrcDevice);
+
+                    if (convertedPayload == null) {
+
+                        mSrcDevice.sendResponse(MessageBuilder.createResponse(
+                                mRequest, ResponseStatus.PRECONDITION_FAILED));
+                    }
+
+                    mRequest = MessageBuilder.modifyRequest(mRequest, null,
+                            null, ContentFormat.APPLICATION_CBOR,
+                            convertedPayload);
+
+                    mRDServer.sendRequest(mRequest, new PublishResponseHandler(
+                            mSrcDevice));
+                    break;
+
+                default:
+                    mSrcDevice.sendResponse(MessageBuilder.createResponse(
+                            mRequest, ResponseStatus.BAD_REQUEST));
+            }
+        }
+
+        @SuppressWarnings("unchecked")
+        private byte[] convertPublishHref(IRequest request, Device device) {
+
+            Cbor<HashMap<String, Object>> cbor = new Cbor<>();
+            HashMap<String, Object> payload = cbor.parsePayloadFromCbor(
+                    request.getPayload(), HashMap.class);
+
+            if (verifyPublishPayload(payload) == false) {
+
+                return null;
+            }
+
+            ArrayList<HashMap<String, Object>> links = (ArrayList<HashMap<String, Object>>) payload
+                    .get(Constants.REQ_LINKS);
+
+            for (HashMap<String, Object> link : links) {
+
+                String href = (String) link.get(Constants.REQ_HREF);
+                href = "/di/" + device.getDeviceId() + href;
+
+                link.put(Constants.REQ_HREF, href);
+            }
+
+            payload.put(Constants.REQ_LINKS, links);
+
+            return cbor.encodingPayloadToCbor(payload);
+        }
+
+        @SuppressWarnings("unchecked")
+        private boolean verifyPublishPayload(HashMap<String, Object> payload) {
+
+            ArrayList<HashMap<String, Object>> links = (ArrayList<HashMap<String, Object>>) payload
+                    .get(Constants.REQ_LINKS);
+
+            if (links == null || links.isEmpty()) {
+                return false;
+            }
+
+            for (HashMap<String, Object> link : links) {
+
+                String href = (String) link.get(Constants.REQ_HREF);
+
+                if (href == null || href.isEmpty()) {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+    }
+
+    // handles response to convert href in response payload into original href
+    // when resource published or updated
+    class PublishResponseHandler implements IResponseEventHandler {
+
+        private Device mSrcDevice;
+
+        public PublishResponseHandler(Device srcDevice) {
+            mSrcDevice = srcDevice;
+        }
+
+        @Override
+        public void onResponseReceived(IResponse response)
+                throws ClientException {
+
+            switch (response.getStatus()) {
+                case CHANGED:
+
+                    response = MessageBuilder.modifyResponse(response,
+                            ContentFormat.APPLICATION_CBOR,
+                            convertResponseHref(response));
+
+                default:
+
+                    mSrcDevice.sendResponse(response);
+            }
+        }
+
+        @SuppressWarnings("unchecked")
+        private byte[] convertResponseHref(IResponse response) {
+
+            Cbor<HashMap<String, Object>> cbor = new Cbor<>();
+            HashMap<String, Object> payload = cbor.parsePayloadFromCbor(
+                    response.getPayload(), HashMap.class);
+
+            ArrayList<HashMap<String, Object>> links = (ArrayList<HashMap<String, Object>>) payload
+                    .get(Constants.REQ_LINKS);
+
+            for (HashMap<String, Object> link : links) {
+
+                String href = (String) link.get(Constants.REQ_HREF);
+
+                // remove prefix
+                ArrayList<String> hrefSegments = new ArrayList<>(
+                        Arrays.asList(href.split("/")));
+                for (int i = 0; i < 3; i++) {
+                    hrefSegments.remove(0);
+                }
+
+                StringBuilder newHref = new StringBuilder();
+                for (String path : hrefSegments) {
+                    newHref.append("/" + path);
+                }
+
+                link.put(Constants.REQ_HREF, newHref.toString());
+            }
+
+            payload.put(Constants.REQ_LINKS, links);
+
+            return cbor.encodingPayloadToCbor(payload);
         }
     }
-}
+
+}
\ No newline at end of file
index be5b77b..6d46ff0 100644 (file)
@@ -34,8 +34,10 @@ import java.util.concurrent.CountDownLatch;
 import org.iotivity.cloud.base.device.CoapDevice;
 import org.iotivity.cloud.base.device.IRequestChannel;
 import org.iotivity.cloud.base.protocols.IRequest;
+import org.iotivity.cloud.base.protocols.IResponse;
 import org.iotivity.cloud.base.protocols.MessageBuilder;
 import org.iotivity.cloud.base.protocols.coap.CoapRequest;
+import org.iotivity.cloud.base.protocols.coap.CoapResponse;
 import org.iotivity.cloud.base.protocols.enums.ContentFormat;
 import org.iotivity.cloud.base.protocols.enums.RequestMethod;
 import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
@@ -56,7 +58,7 @@ public class ResourceDirectoryTest {
     public static final String  DEVICE_PRS_REQ_URI  = Constants.DEVICE_PRESENCE_FULL_URI;
     public static final String  DEVICE_LIST_KEY     = "devices";
     public static final String  RES_PRS_URI         = Constants.RESOURCE_PRESENCE_FULL_URI;
-    // private DeviceServerSystem deviceServerSystem = new DeviceServerSystem();
+
     private String              mDi                 = "B371C481-38E6-4D47-8320-7688D8A5B58C";
     String                      mUserId             = "testuser";
     private CoapDevice          mMockDevice         = null;
@@ -78,6 +80,7 @@ public class ResourceDirectoryTest {
         mDeviceServerSystem.addResource(mRdHandler);
         mMockDevice = mock(CoapDevice.class);
         Mockito.doReturn(mUserId).when(mMockDevice).getUserId();
+        Mockito.doReturn(mDi).when(mMockDevice).getDeviceId();
 
         Mockito.doAnswer(new Answer<Object>() {
             @Override
@@ -140,21 +143,66 @@ public class ResourceDirectoryTest {
         assertTrue(mReqRDServer.getUriPath().contains(TEST_RD_URI));
     }
 
-    IRequest                                rdPublishRequest      = makeResourcePublishRequest();
-
-    @InjectMocks
-    ResourceDirectory.AccountReceiveHandler accountReceiveHandler = mRdHandler.new AccountReceiveHandler(
-            rdPublishRequest, mMockDevice);
+    IRequest  rdPublishRequest  = makeResourcePublishRequest();
+    IResponse rdPublishResponse = makeResourcePublishResponse();
 
     @Test
     public void testRDResourcePublishOnResponseReceived() throws Exception {
+
+        ResourceDirectory.AccountReceiveHandler accountReceiveHandler = mRdHandler.new AccountReceiveHandler(
+                rdPublishRequest, mMockDevice);
+
         IRequest request = makeResourcePublishRequest();
-        accountReceiveHandler.onResponseReceived(
-                MessageBuilder.createResponse(request, ResponseStatus.CHANGED));
+        accountReceiveHandler.onResponseReceived(MessageBuilder.createResponse(
+                request, ResponseStatus.CHANGED));
+
         assertEquals(mReqRDServer, rdPublishRequest);
         assertTrue(mLatch.await(1L, SECONDS));
     }
 
+    @Test
+    public void testRDResourcePublishPayloadConverted() throws Exception {
+
+        ResourceDirectory.AccountReceiveHandler accountReceiveHandler = mRdHandler.new AccountReceiveHandler(
+                rdPublishRequest, mMockDevice);
+
+        IRequest request = makeResourcePublishRequest();
+        accountReceiveHandler.onResponseReceived(MessageBuilder.createResponse(
+                request, ResponseStatus.CHANGED));
+
+        assertEquals(getHrefInTestPublishPayload(mReqRDServer.getPayload()),
+                "/di/" + mDi + "/a/light");
+    }
+
+    @Test
+    public void testRDResourcePublishResponse() throws Exception {
+
+        ResourceDirectory.PublishResponseHandler publishResponseHandler = mRdHandler.new PublishResponseHandler(
+                mMockDevice);
+
+        CountDownLatch latch = new CountDownLatch(1);
+
+        Mockito.doAnswer(new Answer<Object>() {
+            @Override
+            public CoapResponse answer(InvocationOnMock invocation)
+                    throws Throwable {
+                Object[] args = invocation.getArguments();
+                CoapResponse resp = (CoapResponse) args[0];
+
+                assertEquals(getHrefInTestPublishPayload(resp.getPayload()),
+                        "/a/light");
+
+                latch.countDown();
+                return resp;
+            }
+        }).when(mMockDevice).sendResponse(Mockito.anyObject());
+
+        publishResponseHandler
+                .onResponseReceived(makeResourcePublishResponse());
+
+        assertTrue(latch.await(1L, SECONDS));
+    }
+
     private IRequest makeResourcePublishRequest() {
         HashMap<Object, Object> payload = new HashMap<>();
         payload.put(Constants.DEVICE_ID, mDi);
@@ -180,6 +228,30 @@ public class ResourceDirectoryTest {
         return request;
     }
 
+    private IResponse makeResourcePublishResponse() {
+        HashMap<Object, Object> payload = new HashMap<>();
+        payload.put(Constants.DEVICE_ID, mDi);
+        ArrayList<HashMap<Object, Object>> publishLinks = new ArrayList<>();
+        HashMap<Object, Object> link = new HashMap<>();
+        link.put("href", "/di/" + mDi + "/a/light");
+        ArrayList<String> rt = new ArrayList<String>();
+        rt.add("core.light");
+        ArrayList<String> itf = new ArrayList<String>();
+        itf.add("oic.if.baseline");
+        HashMap<String, Object> policy = new HashMap<>();
+        policy.put("bm", 5);
+        link.put("rt", rt);
+        link.put("if", itf);
+        link.put("p", policy);
+        publishLinks.add(link);
+        payload.put("links", publishLinks);
+
+        Cbor<HashMap<Object, Object>> cbor = new Cbor<>();
+        return MessageBuilder.createResponse(makeResourcePublishRequest(),
+                ResponseStatus.CHANGED, ContentFormat.APPLICATION_CBOR,
+                cbor.encodingPayloadToCbor(payload));
+    }
+
     private IRequest makeResourceDeleteRequest() {
         IRequest request = MessageBuilder.createRequest(RequestMethod.DELETE,
                 TEST_RD_URI, "di" + "=" + mDi + ";" + "ins" + "=" + "1234",
@@ -187,4 +259,17 @@ public class ResourceDirectoryTest {
         return request;
     }
 
+    private String getHrefInTestPublishPayload(byte[] payload) {
+
+        Cbor<HashMap<String, Object>> cbor = new Cbor<>();
+        HashMap<String, Object> parsedPayload = cbor.parsePayloadFromCbor(
+                payload, HashMap.class);
+
+        @SuppressWarnings("unchecked")
+        ArrayList<HashMap<String, Object>> links = (ArrayList<HashMap<String, Object>>) parsedPayload
+                .get(Constants.REQ_LINKS);
+
+        return (String) links.get(0).get(Constants.REQ_HREF);
+    }
+
 }
index 69eab17..9d465a4 100644 (file)
@@ -73,8 +73,8 @@ public class ResourceDirectoryResource extends Resource {
                 break;
 
             default:
-                throw new BadRequestException(
-                        request.getMethod() + " request type is not supported");
+                throw new BadRequestException(request.getMethod()
+                        + " request type is not supported");
         }
 
         srcDevice.sendResponse(response);
@@ -101,18 +101,20 @@ public class ResourceDirectoryResource extends Resource {
             throw new PreconditionFailedException("rt property is not include");
         } else if (listRT.get(0).equals(Constants.RESOURCE_TYPE_RDPUBLISH)) {
 
-            PublishPayload pubPayload = parsingPublishPayload(
-                    request.getPayload());
+            PublishPayload pubPayload = parsingPublishPayload(request
+                    .getPayload());
 
             mNotiDeviceId = pubPayload.getTags().getDi();
 
-            PublishPayload copyPubPayload = pubPayload.copy();
+            // PublishPayload copyPubPayload = pubPayload.copy();
 
-            ArrayList<HashMap<Object, Object>> storeResList = creatDBStoreResource(
-                    changeResourceUri(copyPubPayload));
+            // ArrayList<HashMap<Object, Object>> storeResList =
+            // creatDBStoreResource(changeResourceUri(copyPubPayload));
 
-            mNotiPayloadList = DBManager.getInstance()
-                    .registerResource(storeResList);
+            ArrayList<HashMap<Object, Object>> storeResList = creatDBStoreResource(pubPayload);
+
+            mNotiPayloadList = DBManager.getInstance().registerResource(
+                    storeResList);
 
             encodedPayload = createPublishResponse(pubPayload);
 
@@ -151,8 +153,8 @@ public class ResourceDirectoryResource extends Resource {
     private PublishPayload parsingPublishPayload(byte[] payload)
             throws ServerException {
 
-        HashMap<Object, Object> payloadData = mCbor
-                .parsePayloadFromCbor(payload, HashMap.class);
+        HashMap<Object, Object> payloadData = mCbor.parsePayloadFromCbor(
+                payload, HashMap.class);
 
         if (payloadData == null) {
             throw new BadRequestException("payload is null");
@@ -175,7 +177,7 @@ public class ResourceDirectoryResource extends Resource {
             pubLinks = mPublishLinksTypeManager.convertMaptoObject(links,
                     pubLinks);
             String href = pubLinks.getHref();
-            href = "/di/" + di + href;
+            // href = "/di/" + di + href;
             int ins = pubLinks.getIns();
             ins = checkResourceIns(di, href, ins);
             if (ins == 0) {