Implement reconnection and ping-pong between cloud services. Make
[iotivity.git] / cloud / interface / src / test / java / org / iotivity / cloud / ciserver / resources / proxy / rd / ResourceDirectoryTest.java
1 /*
2  * //******************************************************************
3  * //
4  * // Copyright 2016 Samsung Electronics All Rights Reserved.
5  * //
6  * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7  * //
8  * // Licensed under the Apache License, Version 2.0 (the "License");
9  * // you may not use this file except in compliance with the License.
10  * // You may obtain a copy of the License at
11  * //
12  * //      http://www.apache.org/licenses/LICENSE-2.0
13  * //
14  * // Unless required by applicable law or agreed to in writing, software
15  * // distributed under the License is distributed on an "AS IS" BASIS,
16  * // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * // See the License for the specific language governing permissions and
18  * // limitations under the License.
19  * //
20  * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21  */
22
23 package org.iotivity.cloud.ciserver.resources.proxy.rd;
24
25 import static java.util.concurrent.TimeUnit.SECONDS;
26 import static org.junit.Assert.assertEquals;
27 import static org.junit.Assert.assertTrue;
28 import static org.mockito.Mockito.mock;
29
30 import java.util.ArrayList;
31 import java.util.HashMap;
32 import java.util.concurrent.CountDownLatch;
33
34 import org.iotivity.cloud.base.connector.ConnectorPool;
35 import org.iotivity.cloud.base.device.CoapDevice;
36 import org.iotivity.cloud.base.device.IRequestChannel;
37 import org.iotivity.cloud.base.protocols.IRequest;
38 import org.iotivity.cloud.base.protocols.IResponse;
39 import org.iotivity.cloud.base.protocols.MessageBuilder;
40 import org.iotivity.cloud.base.protocols.coap.CoapRequest;
41 import org.iotivity.cloud.base.protocols.coap.CoapResponse;
42 import org.iotivity.cloud.base.protocols.enums.ContentFormat;
43 import org.iotivity.cloud.base.protocols.enums.RequestMethod;
44 import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
45 import org.iotivity.cloud.ciserver.Constants;
46 import org.iotivity.cloud.ciserver.DeviceServerSystem;
47 import org.iotivity.cloud.util.Cbor;
48 import org.junit.Before;
49 import org.junit.Test;
50 import org.junit.runner.RunWith;
51 import org.mockito.InjectMocks;
52 import org.mockito.Mock;
53 import org.mockito.Mockito;
54 import org.mockito.MockitoAnnotations;
55 import org.mockito.invocation.InvocationOnMock;
56 import org.mockito.stubbing.Answer;
57 import org.powermock.api.mockito.PowerMockito;
58 import org.powermock.core.classloader.annotations.PrepareForTest;
59 import org.powermock.modules.junit4.PowerMockRunner;
60
61 @RunWith(PowerMockRunner.class)
62 @PrepareForTest(ConnectorPool.class)
63 public class ResourceDirectoryTest {
64     private static final String TEST_RD_URI         = Constants.RD_FULL_URI;
65     public static final String  DEVICE_LIST_KEY     = "devices";
66
67     private String              mDi                 = "B371C481-38E6-4D47-8320-7688D8A5B58C";
68     String                      mUserId             = "testuser";
69     private CoapDevice          mMockDevice         = null;
70     IRequest                    mReqRDServer        = null;
71     IRequest                    mReqASServer        = null;
72     DeviceServerSystem          mDeviceServerSystem = new DeviceServerSystem();
73     final CountDownLatch        mLatch              = new CountDownLatch(1);
74     @Mock(name = "mRDServer")
75     IRequestChannel             mRequestChannelRDServer;
76     @Mock(name = "mASServer")
77     IRequestChannel             mRequestChannelASServer;
78
79     @InjectMocks
80     ResourceDirectory           mRdHandler          = new ResourceDirectory();
81
82     @Before
83     public void setUp() throws Exception {
84         MockitoAnnotations.initMocks(this);
85         mDeviceServerSystem.addResource(mRdHandler);
86         mMockDevice = mock(CoapDevice.class);
87         Mockito.doReturn(mUserId).when(mMockDevice).getUserId();
88         Mockito.doReturn(mDi).when(mMockDevice).getDeviceId();
89
90         Mockito.doAnswer(new Answer<Object>() {
91             @Override
92             public CoapRequest answer(InvocationOnMock invocation)
93                     throws Throwable {
94                 Object[] args = invocation.getArguments();
95                 CoapRequest request = (CoapRequest) args[0];
96                 System.out.println("\t----------mRDServer --------------");
97                 System.out.println(
98                         "\t----------payload : " + request.getPayloadString());
99                 System.out.println("\t----------uripath : "
100                         + request.getMethod() + " " + request.getUriPath());
101                 System.out.println(
102                         "\t---------uriquery : " + request.getUriQuery());
103                 mReqRDServer = request;
104                 mLatch.countDown();
105                 return request;
106             }
107         }).when(mRequestChannelRDServer).sendRequest(
108                 Mockito.any(IRequest.class), Mockito.any(CoapDevice.class));
109
110         Mockito.doAnswer(new Answer<Object>() {
111             @Override
112             public CoapRequest answer(InvocationOnMock invocation)
113                     throws Throwable {
114                 Object[] args = invocation.getArguments();
115                 CoapRequest request = (CoapRequest) args[0];
116                 System.out.println("\t----------mASServer --------------");
117                 System.out.println(
118                         "\t----------payload : " + request.getPayloadString());
119                 System.out.println("\t----------uripath : "
120                         + request.getMethod() + " " + request.getUriPath());
121                 System.out.println(
122                         "\t---------uriquery : " + request.getUriQuery());
123                 mReqASServer = request;
124                 mLatch.countDown();
125                 return request;
126             }
127         }).when(mRequestChannelASServer).sendRequest(
128                 Mockito.any(IRequest.class), Mockito.any(CoapDevice.class));
129
130         PowerMockito.mockStatic(ConnectorPool.class);
131         PowerMockito.when(ConnectorPool.getConnection("account")).thenReturn(mRequestChannelASServer);
132         PowerMockito.when(ConnectorPool.getConnection("rd")).thenReturn(mRequestChannelRDServer);
133     }
134
135     @Test
136     public void testRDResourcePublishOnRequestReceived() throws Exception {
137         IRequest request = makeResourcePublishRequest();
138         mDeviceServerSystem.onRequestReceived(mMockDevice, request);
139         assertTrue(mLatch.await(1L, SECONDS));
140         assertTrue(mReqASServer.getMethod().equals(RequestMethod.POST));
141         assertTrue(mReqASServer.getUriPath()
142                 .contains(Constants.GROUP_FULL_URI + "/"));
143     }
144
145     @Test
146     public void testRDResourceDeleteOnRequestReceived() throws Exception {
147         IRequest request = makeResourceDeleteRequest();
148         mDeviceServerSystem.onRequestReceived(mMockDevice, request);
149         assertTrue(mLatch.await(1L, SECONDS));
150         assertTrue(mReqRDServer.getMethod().equals(RequestMethod.DELETE));
151         assertTrue(mReqRDServer.getUriPath().contains(TEST_RD_URI));
152     }
153
154     IRequest  rdPublishRequest  = makeResourcePublishRequest();
155     IResponse rdPublishResponse = makeResourcePublishResponse();
156
157     @Test
158     public void testRDResourcePublishOnResponseReceived() throws Exception {
159
160         ResourceDirectory.AccountReceiveHandler accountReceiveHandler = mRdHandler.new AccountReceiveHandler(
161                 rdPublishRequest, mMockDevice);
162
163         IRequest request = makeResourcePublishRequest();
164         accountReceiveHandler.onResponseReceived(
165                 MessageBuilder.createResponse(request, ResponseStatus.CHANGED));
166
167         assertEquals(mReqRDServer, rdPublishRequest);
168         assertTrue(mLatch.await(1L, SECONDS));
169     }
170
171     @Test
172     public void testRDResourcePublishPayloadConverted() throws Exception {
173
174         ResourceDirectory.AccountReceiveHandler accountReceiveHandler = mRdHandler.new AccountReceiveHandler(
175                 rdPublishRequest, mMockDevice);
176
177         IRequest request = makeResourcePublishRequest();
178         accountReceiveHandler.onResponseReceived(
179                 MessageBuilder.createResponse(request, ResponseStatus.CHANGED));
180
181         assertEquals(getHrefInTestPublishPayload(mReqRDServer.getPayload()),
182                 "/oic/route/" + mDi + "/a/light");
183     }
184
185     @Test
186     public void testRDResourcePublishResponse() throws Exception {
187
188         ResourceDirectory.PublishResponseHandler publishResponseHandler = mRdHandler.new PublishResponseHandler(
189                 mMockDevice);
190
191         CountDownLatch latch = new CountDownLatch(1);
192
193         Mockito.doAnswer(new Answer<Object>() {
194             @Override
195             public CoapResponse answer(InvocationOnMock invocation)
196                     throws Throwable {
197                 Object[] args = invocation.getArguments();
198                 CoapResponse resp = (CoapResponse) args[0];
199
200                 assertEquals(getHrefInTestPublishPayload(resp.getPayload()),
201                         "/a/light");
202
203                 latch.countDown();
204                 return resp;
205             }
206         }).when(mMockDevice).sendResponse(Mockito.anyObject());
207
208         publishResponseHandler
209                 .onResponseReceived(makeResourcePublishResponse());
210
211         assertTrue(latch.await(1L, SECONDS));
212     }
213
214     private IRequest makeResourcePublishRequest() {
215         HashMap<Object, Object> payload = new HashMap<>();
216         payload.put(Constants.DEVICE_ID, mDi);
217         ArrayList<HashMap<Object, Object>> publishLinks = new ArrayList<>();
218         HashMap<Object, Object> link = new HashMap<>();
219         link.put("href", "/a/light");
220         ArrayList<String> rt = new ArrayList<String>();
221         rt.add("core.light");
222         ArrayList<String> itf = new ArrayList<String>();
223         itf.add("oic.if.baseline");
224         HashMap<String, Object> policy = new HashMap<>();
225         policy.put("bm", 5);
226         link.put("rt", rt);
227         link.put("if", itf);
228         link.put("p", policy);
229         publishLinks.add(link);
230         payload.put("links", publishLinks);
231         Cbor<HashMap<Object, Object>> cbor = new Cbor<>();
232         IRequest request = MessageBuilder.createRequest(RequestMethod.POST,
233                 TEST_RD_URI, "rt" + "=" + "oic.wk.rdpub",
234                 ContentFormat.APPLICATION_CBOR,
235                 cbor.encodingPayloadToCbor(payload));
236         return request;
237     }
238
239     private IResponse makeResourcePublishResponse() {
240         HashMap<Object, Object> payload = new HashMap<>();
241         payload.put(Constants.DEVICE_ID, mDi);
242         ArrayList<HashMap<Object, Object>> publishLinks = new ArrayList<>();
243         HashMap<Object, Object> link = new HashMap<>();
244         link.put("href", "/oic/route/" + mDi + "/a/light");
245         ArrayList<String> rt = new ArrayList<String>();
246         rt.add("core.light");
247         ArrayList<String> itf = new ArrayList<String>();
248         itf.add("oic.if.baseline");
249         HashMap<String, Object> policy = new HashMap<>();
250         policy.put("bm", 5);
251         link.put("rt", rt);
252         link.put("if", itf);
253         link.put("p", policy);
254         publishLinks.add(link);
255         payload.put("links", publishLinks);
256
257         Cbor<HashMap<Object, Object>> cbor = new Cbor<>();
258         return MessageBuilder.createResponse(makeResourcePublishRequest(),
259                 ResponseStatus.CHANGED, ContentFormat.APPLICATION_CBOR,
260                 cbor.encodingPayloadToCbor(payload));
261     }
262
263     private IRequest makeResourceDeleteRequest() {
264         IRequest request = MessageBuilder.createRequest(RequestMethod.DELETE,
265                 TEST_RD_URI, "di" + "=" + mDi + ";" + "ins" + "=" + "1234",
266                 null, null);
267         return request;
268     }
269
270     private String getHrefInTestPublishPayload(byte[] payload) {
271
272         Cbor<HashMap<String, Object>> cbor = new Cbor<>();
273         HashMap<String, Object> parsedPayload = cbor
274                 .parsePayloadFromCbor(payload, HashMap.class);
275
276         @SuppressWarnings("unchecked")
277         ArrayList<HashMap<String, Object>> links = (ArrayList<HashMap<String, Object>>) parsedPayload
278                 .get(Constants.REQ_LINKS);
279
280         return (String) links.get(0).get(Constants.REQ_HREF);
281     }
282
283 }