f980e9f03bcd1bd6d6297d8b8a30c95ad4ce239e
[iotivity.git] / cloud / stack / src / main / java / org / iotivity / cloud / base / ServerSystem.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;
23
24 import java.util.ArrayList;
25 import java.util.List;
26
27 import org.iotivity.cloud.base.connector.CoapClient;
28 import org.iotivity.cloud.base.device.CoapDevice;
29 import org.iotivity.cloud.base.device.Device;
30 import org.iotivity.cloud.base.device.IRequestChannel;
31 import org.iotivity.cloud.base.exception.ClientException;
32 import org.iotivity.cloud.base.exception.ServerException;
33 import org.iotivity.cloud.base.exception.ServerException.InternalServerErrorException;
34 import org.iotivity.cloud.base.protocols.MessageBuilder;
35 import org.iotivity.cloud.base.protocols.coap.CoapMessage;
36 import org.iotivity.cloud.base.protocols.coap.CoapRequest;
37 import org.iotivity.cloud.base.protocols.coap.CoapResponse;
38 import org.iotivity.cloud.base.protocols.enums.ResponseStatus;
39 import org.iotivity.cloud.base.resource.ResourceManager;
40 import org.iotivity.cloud.base.server.CoapServer;
41 import org.iotivity.cloud.base.server.HttpServer;
42 import org.iotivity.cloud.base.server.Server;
43 import org.iotivity.cloud.util.Log;
44
45 import io.netty.channel.ChannelDuplexHandler;
46 import io.netty.channel.ChannelHandler.Sharable;
47 import io.netty.channel.ChannelHandlerContext;
48 import io.netty.channel.SimpleChannelInboundHandler;
49 import io.netty.util.AttributeKey;
50
51 public class ServerSystem extends ResourceManager {
52     private List<Server>                  mServerList = new ArrayList<>();
53     protected static AttributeKey<Device> keyDevice   = AttributeKey
54             .newInstance("device");
55
56     @Sharable
57     public class PersistentPacketReceiver
58             extends SimpleChannelInboundHandler<CoapMessage> {
59         @Override
60         public void channelActive(ChannelHandlerContext ctx) {
61
62             StringBuilder deviceId = new StringBuilder(
63                     ctx.channel().id().asLongText().substring(26));
64             deviceId.deleteCharAt(25);
65             deviceId.insert(13, '-');
66             deviceId.insert(18, '-');
67             deviceId.insert(23, '-');
68             Device device = new CoapDevice(ctx, deviceId.toString(), null,
69                     null);
70             ctx.channel().attr(keyDevice).set(device);
71
72             device.onConnected();
73         }
74
75         @Override
76         protected void channelRead0(ChannelHandlerContext ctx,
77                 CoapMessage msg) {
78             try {
79                 // Find proper device and raise event.
80                 Device targetDevice = ctx.channel().attr(keyDevice).get();
81
82                 if (targetDevice == null) {
83                     throw new InternalServerErrorException();
84                 }
85
86                 if (msg instanceof CoapRequest) {
87                     onRequestReceived(targetDevice, (CoapRequest) msg);
88                 } else if (msg instanceof CoapResponse) {
89                     // TODO: Re-architecturing required
90                     IRequestChannel reqChannel = ((CoapDevice) targetDevice)
91                             .getRequestChannel();
92                     CoapClient coapClient = (CoapClient) reqChannel;
93                     coapClient.onResponseReceived(msg);
94                 }
95
96             } catch (ServerException e) {
97                 ctx.channel().writeAndFlush(MessageBuilder.createResponse(msg,
98                         e.getErrorResponse()));
99                 Log.f(ctx.channel(), e);
100             } catch (ClientException e) {
101                 Log.f(ctx.channel(), e);
102             } catch (Throwable t) {
103                 Log.f(ctx.channel(), t);
104                 if (msg instanceof CoapRequest) {
105                     ctx.channel().writeAndFlush(MessageBuilder.createResponse(
106                             msg, ResponseStatus.INTERNAL_SERVER_ERROR));
107                 }
108             }
109         }
110
111         @Override
112         public void channelInactive(ChannelHandlerContext ctx)
113                 throws Exception {
114             Device device = ctx.channel().attr(keyDevice).get();
115             device.onDisconnected();
116             ctx.channel().attr(keyDevice).remove();
117         }
118     }
119
120     @Sharable
121     public class NonPersistentPacketReceiver extends ChannelDuplexHandler {
122         @Override
123         public void channelActive(ChannelHandlerContext ctx) throws Exception {
124             // onDeviceConnected(ctx)
125         }
126
127         @Override
128         public void channelRead(ChannelHandlerContext ctx, Object msg)
129                 throws Exception {
130             // Find proper device and raise event.
131             // onRequestReceived(new Device(ctx), msg);
132         }
133     }
134
135     public void addServer(Server server) {
136         if (server instanceof CoapServer) {
137             server.addHandler(new PersistentPacketReceiver());
138         }
139
140         if (server instanceof HttpServer) {
141             server.addHandler(new NonPersistentPacketReceiver());
142         }
143         mServerList.add(server);
144     }
145
146     public void startSystem(boolean tlsMode) throws Exception {
147         for (Server server : mServerList) {
148             server.startServer(tlsMode);
149         }
150     }
151
152     public void stopSystem() throws Exception {
153         for (Server server : mServerList) {
154             server.stopServer();
155         }
156     }
157 }