2 * //******************************************************************
4 * // Copyright 2016 Samsung Electronics All Rights Reserved.
6 * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
12 * // http://www.apache.org/licenses/LICENSE-2.0
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.
20 * //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
22 package org.iotivity.cloud.ciserver.resources;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.Iterator;
30 import java.util.Timer;
31 import java.util.TimerTask;
33 import javax.swing.text.html.parser.Entity;
35 import org.iotivity.cloud.base.Resource;
36 import org.iotivity.cloud.base.SessionManager;
37 import org.iotivity.cloud.base.protocols.coap.CoapRequest;
38 import org.iotivity.cloud.base.protocols.coap.CoapResponse;
39 import org.iotivity.cloud.base.protocols.coap.enums.CoapStatus;
40 import org.iotivity.cloud.ciserver.Constants;
41 import org.iotivity.cloud.util.Cbor;
42 import org.iotivity.cloud.util.Logger;
44 import io.netty.channel.ChannelHandlerContext;
45 import io.netty.util.collection.IntObjectMap.Entry;
49 * This class provides a set of APIs to use KeepAlive Resource for ensuring the
53 public class KeepAliveResource extends Resource {
55 private int[] intervals;
56 private HashMap<ChannelHandlerContext, Long> connectPool;
58 private Cbor<HashMap<String, Integer>> cbor;
59 private SessionManager sessionManager = null;
61 public void setIntervals(int[] intervals) {
62 this.intervals = intervals;
65 public int[] getIntervals() {
66 return this.intervals;
69 public KeepAliveResource(SessionManager sessionManager, int[] intervals) {
70 setUri(Constants.KEEP_ALIVE_URI);
71 setIntervals(intervals);
72 this.sessionManager = sessionManager;
73 connectPool = new HashMap<ChannelHandlerContext, Long>();
75 cbor = new Cbor<HashMap<String, Integer>>();
78 public void startSessionChecker() {
79 timer.schedule(new KeepAliveTask(), 30000, 60000);
82 public void stopSessionChecker() {
87 * API for receiving message(message to keepalive resource)
90 * ChannelHandlerContext of request message
92 * CoAP request message
95 public void onRequestReceived(ChannelHandlerContext ctx,
96 CoapRequest request) {
98 CoapResponse response = null;
100 switch (request.getRequestMethod()) {
101 // First message to KeepAlive from resource
103 if (intervals != null) {
104 response = makePingConfigMessage(request);
105 connectPool.put(ctx, System.currentTimeMillis()
106 + (intervals[0] * (long) 60000));
109 // interval Message to KeepAlive After receiving GET Message
111 HashMap<String, Integer> payloadData = null;
112 payloadData = cbor.parsePayloadFromCbor(request.getPayload(),
115 Logger.d("Receive payloadData : " + payloadData);
116 if (payloadData != null) {
117 if (payloadData.containsKey("in")) {
118 Logger.d("interval : " + payloadData.get("in"));
120 connectPool.put(ctx, System.currentTimeMillis()
121 + (payloadData.get("in") * (long) 60000));
124 response = makeResponse(request);
134 ctx.writeAndFlush(response);
138 * API for making response to Resource
141 * ChannelHandlerContext of request message
143 private CoapResponse makeResponse(CoapRequest request) {
144 CoapResponse response = new CoapResponse(CoapStatus.VALID);
145 response.setToken(request.getToken());
151 * API for making interval and first response to Resource
154 * ChannelHandlerContext of request message
156 private CoapResponse makePingConfigMessage(CoapRequest request) {
157 CoapResponse response = new CoapResponse(CoapStatus.CONTENT);
158 response.setToken(request.getToken());
160 HashMap<String, int[]> payloadData = new HashMap<String, int[]>();
161 payloadData.put("inarray", intervals);
163 byte[] cborData = cbor.encodingPayloadToCbor(payloadData);
165 response.setPayload(cborData);
167 Logger.d("Send payloadData : " + payloadData);
173 * API for managing session
175 public class KeepAliveTask extends TimerTask {
179 Map<ChannelHandlerContext, Long> map = Collections
180 .synchronizedMap(connectPool);
181 Set<ChannelHandlerContext> keySet = map.keySet();
182 ArrayList<ChannelHandlerContext> deleteList = new ArrayList<ChannelHandlerContext>();
183 Iterator<ChannelHandlerContext> iterator = null;
185 iterator = keySet.iterator();
186 Long currentTime = System.currentTimeMillis();
188 while (iterator.hasNext()) {
189 ChannelHandlerContext key = iterator.next();
190 if (map.containsKey(key)) {
191 if (map.get(key) != null) {
192 Long lifeTime = (Long) map.get(key);
193 if (lifeTime != null) {
194 Logger.d("KeepAliveTask Operating : "
195 + key.channel().toString() + ", Time : "
196 + (lifeTime - currentTime));
197 if (lifeTime < currentTime) {
206 iterator = deleteList.iterator();
208 while (iterator.hasNext()) {
209 ChannelHandlerContext key = iterator.next();
210 Logger.d("KeepAliveTask Remove");
211 connectPool.remove(key);
212 sessionManager.removeSessionByChannel(key);