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";
+
}
*/
package org.iotivity.cloud.ciserver.resources.proxy.rd;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
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 {
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
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;
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;
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
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);
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",
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);
+ }
+
}
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);
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);
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");
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) {