Fixed SVACE deteted Code
[platform/upstream/iotivity.git] / cloud / interface / src / main / java / org / iotivity / cloud / ciserver / resources / KeepAliveResource.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;
23
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.Map;
29 import java.util.Set;
30 import java.util.Timer;
31 import java.util.TimerTask;
32
33 import javax.swing.text.html.parser.Entity;
34
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;
43
44 import io.netty.channel.ChannelHandlerContext;
45 import io.netty.util.collection.IntObjectMap.Entry;
46
47 /**
48  *
49  * This class provides a set of APIs to use KeepAlive Resource for ensuring the
50  * connection.
51  *
52  */
53 public class KeepAliveResource extends Resource {
54
55     private int[]                                intervals;
56     private HashMap<ChannelHandlerContext, Long> connectPool;
57     private Timer                                timer;
58     private Cbor<HashMap<String, Integer>>       cbor;
59     private SessionManager                       sessionManager = null;
60
61     public void setIntervals(int[] intervals) {
62         this.intervals = intervals;
63     }
64
65     public int[] getIntervals() {
66         return this.intervals;
67     }
68
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>();
74         timer = new Timer();
75         cbor = new Cbor<HashMap<String, Integer>>();
76     }
77
78     public void startSessionChecker() {
79         timer.schedule(new KeepAliveTask(), 30000, 60000);
80     }
81
82     public void stopSessionChecker() {
83         timer.cancel();
84     }
85
86     /**
87      * API for receiving message(message to keepalive resource)
88      *
89      * @param ctx
90      *            ChannelHandlerContext of request message
91      * @param request
92      *            CoAP request message
93      */
94     @Override
95     public void onRequestReceived(ChannelHandlerContext ctx,
96             CoapRequest request) {
97
98         CoapResponse response = null;
99
100         switch (request.getRequestMethod()) {
101             // First message to KeepAlive from resource
102             case GET:
103                 if (intervals != null) {
104                     response = makePingConfigMessage(request);
105                     connectPool.put(ctx, System.currentTimeMillis()
106                             + (intervals[0] * (long) 60000));
107                 }
108                 break;
109             // interval Message to KeepAlive After receiving GET Message
110             case PUT:
111                 HashMap<String, Integer> payloadData = null;
112                 payloadData = cbor.parsePayloadFromCbor(request.getPayload(),
113                         HashMap.class);
114
115                 Logger.d("Receive payloadData : " + payloadData);
116                 if (payloadData != null) {
117                     if (payloadData.containsKey("in")) {
118                         Logger.d("interval : " + payloadData.get("in"));
119
120                         connectPool.put(ctx, System.currentTimeMillis()
121                                 + (payloadData.get("in") * (long) 60000));
122                     }
123                 }
124                 response = makeResponse(request);
125                 break;
126
127             case POST:
128                 break;
129
130             case DELETE:
131                 break;
132         }
133
134         ctx.writeAndFlush(response);
135     }
136
137     /**
138      * API for making response to Resource
139      *
140      * @param request
141      *            ChannelHandlerContext of request message
142      */
143     private CoapResponse makeResponse(CoapRequest request) {
144         CoapResponse response = new CoapResponse(CoapStatus.VALID);
145         response.setToken(request.getToken());
146
147         return response;
148     }
149
150     /**
151      * API for making interval and first response to Resource
152      *
153      * @param request
154      *            ChannelHandlerContext of request message
155      */
156     private CoapResponse makePingConfigMessage(CoapRequest request) {
157         CoapResponse response = new CoapResponse(CoapStatus.CONTENT);
158         response.setToken(request.getToken());
159
160         HashMap<String, int[]> payloadData = new HashMap<String, int[]>();
161         payloadData.put("inarray", intervals);
162
163         byte[] cborData = cbor.encodingPayloadToCbor(payloadData);
164
165         response.setPayload(cborData);
166
167         Logger.d("Send payloadData : " + payloadData);
168
169         return response;
170     }
171
172     /**
173      * API for managing session
174      */
175     public class KeepAliveTask extends TimerTask {
176
177         @Override
178         public void run() {
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;
184             synchronized (map) {
185                 iterator = keySet.iterator();
186                 Long currentTime = System.currentTimeMillis();
187                 // check interval
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) {
198                                     deleteList.add(key);
199                                 }
200                             }
201                         }
202                     }
203                 }
204
205             }
206             iterator = deleteList.iterator();
207             // remove session
208             while (iterator.hasNext()) {
209                 ChannelHandlerContext key = iterator.next();
210                 Logger.d("KeepAliveTask Remove");
211                 connectPool.remove(key);
212                 sessionManager.removeSessionByChannel(key);
213                 key.close();
214             }
215         }
216     }
217 }