2f066c7ddfcfff22f600c54da4a408a06456b8e6
[iotivity.git] / cloud / interface / src / main / java / org / iotivity / cloud / ciserver / resources / proxy / rd / ResourceDirectory.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 package org.iotivity.cloud.ciserver.resources.proxy.rd;
23
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.HashMap;
27
28 import org.iotivity.cloud.base.connector.ConnectorPool;
29 import org.iotivity.cloud.base.device.Device;
30 import org.iotivity.cloud.base.device.IRequestChannel;
31 import org.iotivity.cloud.base.device.IResponseEventHandler;
32 import org.iotivity.cloud.base.exception.ClientException;
33 import org.iotivity.cloud.base.exception.ServerException;
34 import org.iotivity.cloud.base.exception.ServerException.BadRequestException;
35 import org.iotivity.cloud.base.protocols.IRequest;
36 import org.iotivity.cloud.base.protocols.IResponse;
37 import org.iotivity.cloud.base.protocols.MessageBuilder;
38 import org.iotivity.cloud.base.protocols.enums.ContentFormat;
39 import org.iotivity.cloud.base.protocols.enums.RequestMethod;
40 import org.iotivity.cloud.base.resource.Resource;
41 import org.iotivity.cloud.ciserver.Constants;
42 import org.iotivity.cloud.util.Cbor;
43
44 /**
45  *
46  * This class provides a set of APIs to send requests about publish resource to
47  * resource directory
48  *
49  */
50
51 public class ResourceDirectory extends Resource {
52     private Cbor<HashMap<String, Object>> mCbor     = new Cbor<>();
53
54     public ResourceDirectory() {
55         super(Arrays.asList(Constants.PREFIX_OIC, Constants.RD_URI));
56     }
57
58     @Override
59     public void onDefaultRequestReceived(Device srcDevice, IRequest request)
60             throws ServerException {
61         switch (request.getMethod()) {
62             case POST:
63                 HashMap<String, Object> payloadData = mCbor
64                         .parsePayloadFromCbor(request.getPayload(),
65                                 HashMap.class);
66                 StringBuffer query = new StringBuffer();
67                 query.append("op=add;");
68                 query.append(Constants.USER_ID + "=" + srcDevice.getUserId());
69
70                 StringBuffer uriPath = new StringBuffer();
71                 uriPath.append(Constants.PREFIX_OIC + "/");
72                 uriPath.append(Constants.ACL_URI + "/");
73                 uriPath.append(Constants.GROUP_URI + "/");
74                 uriPath.append(srcDevice.getUserId());
75
76                 String di = payloadData.get(Constants.REQ_DEVICE_ID).toString();
77                 HashMap<String, Object> requestPayload = new HashMap<>();
78
79                 requestPayload.put(Constants.REQ_GROUP_DEVICES,
80                         Arrays.asList(di));
81                 IRequest requestToAS = MessageBuilder.createRequest(
82                         RequestMethod.POST, uriPath.toString(),
83                         query.toString(), ContentFormat.APPLICATION_CBOR,
84                         mCbor.encodingPayloadToCbor(requestPayload));
85
86                 ConnectorPool.getConnection("account").sendRequest(requestToAS,
87                         new AccountReceiveHandler(request, srcDevice));
88                 break;
89
90             case DELETE:
91                 ConnectorPool.getConnection("rd").sendRequest(request, srcDevice);
92                 break;
93
94             default:
95                 throw new BadRequestException(
96                         request.getMethod() + " request type is not support");
97         }
98     }
99
100     class AccountReceiveHandler implements IResponseEventHandler {
101         private Device   mSrcDevice;
102         private IRequest mRequest;
103
104         public AccountReceiveHandler(IRequest request, Device srcDevice) {
105             mSrcDevice = srcDevice;
106             mRequest = request;
107         }
108
109         @Override
110         public void onResponseReceived(IResponse response)
111                 throws ClientException {
112
113             switch (response.getStatus()) {
114                 case CHANGED:
115                     byte[] convertedPayload = convertPublishHref(mRequest,
116                             mSrcDevice);
117
118                     mRequest = MessageBuilder.modifyRequest(mRequest, null,
119                             null, ContentFormat.APPLICATION_CBOR,
120                             convertedPayload);
121
122                     ConnectorPool.getConnection("rd").sendRequest(mRequest,
123                             new PublishResponseHandler(mSrcDevice));
124                     break;
125
126                 default:
127                     mSrcDevice.sendResponse(response);
128             }
129         }
130
131         @SuppressWarnings("unchecked")
132         private byte[] convertPublishHref(IRequest request, Device device) {
133
134             Cbor<HashMap<String, Object>> cbor = new Cbor<>();
135             HashMap<String, Object> payload = cbor
136                     .parsePayloadFromCbor(request.getPayload(), HashMap.class);
137
138             ArrayList<HashMap<String, Object>> links = (ArrayList<HashMap<String, Object>>) payload
139                     .get(Constants.REQ_LINKS);
140
141             for (HashMap<String, Object> link : links) {
142
143                 String href = (String) link.get(Constants.REQ_HREF);
144                 href = Constants.ROUTE_FULL_URI + "/" + device.getDeviceId()
145                         + href;
146
147                 link.put(Constants.REQ_HREF, href);
148             }
149
150             payload.put(Constants.REQ_LINKS, links);
151
152             return cbor.encodingPayloadToCbor(payload);
153         }
154     }
155
156     // handles response to convert href in response payload into original href
157     // when resource published or updated
158     class PublishResponseHandler implements IResponseEventHandler {
159
160         private Device mSrcDevice;
161
162         public PublishResponseHandler(Device srcDevice) {
163             mSrcDevice = srcDevice;
164         }
165
166         @Override
167         public void onResponseReceived(IResponse response)
168                 throws ClientException {
169
170             switch (response.getStatus()) {
171                 case CHANGED:
172                     response = MessageBuilder.modifyResponse(response,
173                             ContentFormat.APPLICATION_CBOR,
174                             convertResponseHref(response));
175
176                 default:
177                     mSrcDevice.sendResponse(response);
178             }
179         }
180
181         @SuppressWarnings("unchecked")
182         private byte[] convertResponseHref(IResponse response) {
183
184             Cbor<HashMap<String, Object>> cbor = new Cbor<>();
185             HashMap<String, Object> payload = cbor
186                     .parsePayloadFromCbor(response.getPayload(), HashMap.class);
187
188             ArrayList<HashMap<String, Object>> links = (ArrayList<HashMap<String, Object>>) payload
189                     .get(Constants.REQ_LINKS);
190
191             for (HashMap<String, Object> link : links) {
192
193                 String href = (String) link.get(Constants.REQ_HREF);
194
195                 // remove prefix
196                 ArrayList<String> hrefSegments = new ArrayList<>(
197                         Arrays.asList(href.split("/")));
198
199                 ArrayList<String> RouteResourceSegment = new ArrayList<>(
200                         Arrays.asList(Constants.ROUTE_FULL_URI.split("/")));
201
202                 for (String path : RouteResourceSegment) {
203                     hrefSegments.remove(path);
204                 }
205                 hrefSegments.remove(0);
206
207                 StringBuilder newHref = new StringBuilder();
208                 for (String path : hrefSegments) {
209                     newHref.append("/" + path);
210                 }
211
212                 link.put(Constants.REQ_HREF, newHref.toString());
213             }
214
215             payload.put(Constants.REQ_LINKS, links);
216
217             return cbor.encodingPayloadToCbor(payload);
218         }
219     }
220
221 }