c6343f0b13c164a926d357fa1b2249bf4edaf27f
[iotivity.git] / cloud / stack / src / main / java / org / iotivity / cloud / base / protocols / coap / CoapLogHandler.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.base.protocols.coap;
23
24 import org.iotivity.cloud.util.Log;
25
26 import io.netty.channel.ChannelDuplexHandler;
27 import io.netty.channel.ChannelHandler.Sharable;
28 import io.netty.channel.ChannelHandlerContext;
29 import io.netty.channel.ChannelPromise;
30
31 /**
32  *
33  * This class provides a set of APIs to print out logs for CoAP request and
34  * response.
35  *
36  */
37 @Sharable
38 public class CoapLogHandler extends ChannelDuplexHandler {
39
40     static final int MAX_LOGLEN = 100;
41
42     @Override
43     public void channelActive(ChannelHandlerContext ctx) throws Exception {
44         Log.v(ctx.channel().id().asLongText().substring(26)
45                 + " Connected, Address: "
46                 + ctx.channel().remoteAddress().toString());
47
48         ctx.fireChannelActive();
49     }
50
51     @Override
52     public void channelInactive(ChannelHandlerContext ctx) throws Exception {
53         ctx.fireChannelInactive();
54         Log.v(ctx.channel().id().asLongText().substring(26)
55                 + " Disconnected, Address: "
56                 + ctx.channel().remoteAddress().toString());
57     }
58
59     @Override
60     public void write(ChannelHandlerContext ctx, Object msg,
61             ChannelPromise promise) {
62
63         String log = null;
64
65         if (msg instanceof CoapRequest) {
66             log = composeCoapRequest(
67                     ctx.channel().id().asLongText().substring(26),
68                     (CoapRequest) msg);
69         } else {
70             log = composeCoapResponse(
71                     ctx.channel().id().asLongText().substring(26),
72                     (CoapResponse) msg);
73         }
74
75         Log.v(log);
76
77         ctx.writeAndFlush(msg);
78     }
79
80     @Override
81     public void channelRead(ChannelHandlerContext ctx, Object msg)
82             throws Exception {
83
84         String log = null;
85
86         if (msg instanceof CoapRequest) {
87             log = composeCoapRequest(
88                     ctx.channel().id().asLongText().substring(26),
89                     (CoapRequest) msg);
90         } else {
91             log = composeCoapResponse(
92                     ctx.channel().id().asLongText().substring(26),
93                     (CoapResponse) msg);
94         }
95
96         Log.v(log);
97
98         ctx.fireChannelRead(msg);
99     }
100
101     private String composeCoapRequest(String channelId, CoapRequest request) {
102         StringBuilder strBuilder = new StringBuilder();
103
104         strBuilder.append(channelId);
105         strBuilder.append(" " + request.getTokenString());
106
107         switch (request.getMethod()) {
108             case DELETE:
109                 strBuilder.append(" DELETE ");
110                 break;
111             case GET:
112                 switch (request.getObserve()) {
113                     case SUBSCRIBE:
114                         strBuilder.append(" GET OBSERVE ");
115                         break;
116                     case UNSUBSCRIBE:
117                         strBuilder.append(" GET OBSERVE CANCEL ");
118                         break;
119                     default:
120                         strBuilder.append(" GET ");
121                         break;
122                 }
123                 break;
124             case POST:
125                 strBuilder.append(" POST ");
126                 break;
127             case PUT:
128                 strBuilder.append(" PUT ");
129                 break;
130         }
131
132         strBuilder.append(request.getUriPath());
133         String query = request.getUriQuery();
134         if (query != null) {
135             strBuilder.append("/?" + query);
136         }
137
138         if (request.getPayloadSize() > 0) {
139             strBuilder.append(" SZ:" + request.getPayloadSize() + " P:"
140                     + new String(request.getPayload(), 0,
141                             request.getPayloadSize() > MAX_LOGLEN ? MAX_LOGLEN
142                                     : request.getPayloadSize()));
143         }
144
145         return strBuilder.toString();
146     }
147
148     private String composeCoapResponse(String channelId,
149             CoapResponse response) {
150         StringBuilder strBuilder = new StringBuilder();
151
152         strBuilder.append(channelId);
153         strBuilder.append(" " + response.getTokenString());
154
155         switch (response.getStatus()) {
156             case BAD_GATEWAY:
157                 strBuilder.append(" 5.02 Bad Gateway");
158                 break;
159             case BAD_OPTION:
160                 strBuilder.append(" 4.02 Bad Option");
161                 break;
162             case BAD_REQUEST:
163                 strBuilder.append(" 4.00 Bad Request");
164                 break;
165             case CHANGED:
166                 strBuilder.append(" 2.04 Changed");
167                 break;
168             case CONTENT:
169                 strBuilder.append(" 2.05 Content");
170                 break;
171             case CREATED:
172                 strBuilder.append(" 2.01 Created");
173                 break;
174             case DELETED:
175                 strBuilder.append(" 2.02 Deleted");
176                 break;
177             case FORBIDDEN:
178                 strBuilder.append(" 4.03 Forbidden");
179                 break;
180             case GATEWAY_TIMEOUT:
181                 strBuilder.append(" 5.04 Gateway Timeout");
182                 break;
183             case INTERNAL_SERVER_ERROR:
184                 strBuilder.append(" 5.00 Internal Server Error");
185                 break;
186             case METHOD_NOT_ALLOWED:
187                 strBuilder.append(" 4.05 Method Not Allowed");
188                 break;
189             case NOT_ACCEPTABLE:
190                 strBuilder.append(" 4.06 Not Acceptable");
191                 break;
192             case NOT_FOUND:
193                 strBuilder.append(" 4.04 Not Found");
194                 break;
195             case NOT_IMPLEMENTED:
196                 strBuilder.append(" 5.01 Not Implemented");
197                 break;
198             case PRECONDITION_FAILED:
199                 strBuilder.append(" 4.12 Precondition Failed");
200                 break;
201             case PROXY_NOT_SUPPORTED:
202                 strBuilder.append(" 5.05 Proxying Not Supported");
203                 break;
204             case REQUEST_ENTITY_TOO_LARGE:
205                 strBuilder.append(" 4.13 Request Entity Too Large");
206                 break;
207             case SERVICE_UNAVAILABLE:
208                 strBuilder.append(" 5.03 Service Unavailable");
209                 break;
210             case UNAUTHORIZED:
211                 strBuilder.append(" 4.01 Unauthorized");
212                 break;
213             case UNSUPPORTED_CONTENT_FORMAT:
214                 strBuilder.append(" 4.15 Unsupported Content-Format");
215                 break;
216             case VALID:
217                 strBuilder.append(" 2.03 Valid");
218                 break;
219             default:
220                 break;
221         }
222
223         switch (response.getObserve()) {
224             case SUBSCRIBE:
225                 strBuilder.append(" OBSERVE");
226                 break;
227             case UNSUBSCRIBE:
228                 strBuilder.append(" OBSERVE CANCEL");
229                 break;
230             case SEQUENCE_NUMBER:
231                 strBuilder.append(" OBSERVE SEQ:");
232                 strBuilder.append(response.getSequenceNumber());
233                 break;
234             default:
235                 break;
236         }
237
238         if (response.getPayloadSize() > 0) {
239             strBuilder.append(" SZ:" + response.getPayloadSize() + " P:"
240                     + new String(response.getPayload(), 0,
241                             response.getPayloadSize() > MAX_LOGLEN ? MAX_LOGLEN
242                                     : response.getPayloadSize()));
243         }
244
245         return strBuilder.toString();
246     }
247 }