1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package openr66.protocol.localhandler;
22
23 import static openr66.context.R66FiniteDualStates.ERROR;
24
25 import goldengate.common.logging.GgInternalLogger;
26 import goldengate.common.logging.GgInternalLoggerFactory;
27 import openr66.context.ErrorCode;
28 import openr66.context.R66Result;
29 import openr66.protocol.configuration.Configuration;
30 import openr66.protocol.exception.OpenR66Exception;
31 import openr66.protocol.exception.OpenR66ExceptionTrappedFactory;
32 import openr66.protocol.exception.OpenR66ProtocolBusinessNoWriteBackException;
33 import openr66.protocol.exception.OpenR66ProtocolNetworkException;
34 import openr66.protocol.exception.OpenR66ProtocolNoConnectionException;
35 import openr66.protocol.exception.OpenR66ProtocolShutdownException;
36 import openr66.protocol.exception.OpenR66ProtocolSystemException;
37 import openr66.protocol.localhandler.packet.AbstractLocalPacket;
38 import openr66.protocol.localhandler.packet.ErrorPacket;
39 import openr66.protocol.localhandler.packet.LocalPacketFactory;
40 import openr66.protocol.utils.ChannelCloseTimer;
41 import openr66.protocol.utils.ChannelUtils;
42
43 import org.jboss.netty.channel.Channel;
44 import org.jboss.netty.channel.ChannelHandlerContext;
45 import org.jboss.netty.channel.ChannelStateEvent;
46 import org.jboss.netty.channel.Channels;
47 import org.jboss.netty.channel.ExceptionEvent;
48 import org.jboss.netty.channel.MessageEvent;
49 import org.jboss.netty.channel.SimpleChannelHandler;
50
51
52
53
54 public class LocalClientHandler extends SimpleChannelHandler {
55
56
57
58 private static final GgInternalLogger logger = GgInternalLoggerFactory
59 .getLogger(LocalClientHandler.class);
60
61
62
63
64 private volatile LocalChannelReference localChannelReference = null;
65
66
67
68
69
70
71
72
73
74 @Override
75 public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
76 throws Exception {
77 logger.debug("Local Client Channel Closed: {}", e.getChannel().getId());
78 }
79
80
81
82
83
84
85
86
87
88 @Override
89 public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
90 throws Exception {
91 logger
92 .debug("Local Client Channel Connected: " +
93 e.getChannel().getId());
94 }
95
96
97
98
99
100
101 private void initLocalClientHandler(Channel channel)
102 throws InterruptedException, OpenR66ProtocolNetworkException {
103 int i = 0;
104 if (localChannelReference == null) {
105 for (i = 0; i < Configuration.RETRYNB; i ++) {
106 localChannelReference = Configuration.configuration
107 .getLocalTransaction().getFromId(channel.getId());
108 if (localChannelReference != null) {
109 return;
110 }
111 Thread.sleep(Configuration.RETRYINMS);
112 }
113 logger.warn("Cannot find local connection");
114 }
115 }
116
117
118
119
120
121
122
123
124
125 @Override
126 public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
127 throws Exception {
128 if (localChannelReference == null) {
129 initLocalClientHandler(e.getChannel());
130 }
131
132 final AbstractLocalPacket packet = (AbstractLocalPacket) e.getMessage();
133 if (packet.getType() != LocalPacketFactory.STARTUPPACKET) {
134 logger.error("Local Client Channel Recv wrong packet: " +
135 e.getChannel().getId() + " : " + packet.toString());
136 throw new OpenR66ProtocolSystemException("Should not be here");
137 }
138 logger.debug("LocalClientHandler initialized: " +
139 (localChannelReference != null));
140 }
141
142
143
144
145
146
147
148
149
150 @Override
151 public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
152 throws Exception {
153
154 logger.debug(
155 "Local Client Channel Exception: {}",e.getChannel().getId(), e
156 .getCause());
157 if (localChannelReference == null) {
158 initLocalClientHandler(e.getChannel());
159 }
160 if (localChannelReference != null) {
161 OpenR66Exception exception = OpenR66ExceptionTrappedFactory
162 .getExceptionFromTrappedException(e.getChannel(), e);
163 localChannelReference.sessionNewState(ERROR);
164 if (exception != null) {
165 if (exception instanceof OpenR66ProtocolShutdownException) {
166 Thread thread = new Thread(new ChannelUtils(), "R66 Shutdown Thread");
167 thread.setDaemon(true);
168 thread.start();
169 logger.debug("Will close channel");
170 Channels.close(e.getChannel());
171 return;
172 } else if (exception instanceof OpenR66ProtocolBusinessNoWriteBackException) {
173 logger.error("Will close channel", exception);
174 Channels.close(e.getChannel());
175 return;
176 } else if (exception instanceof OpenR66ProtocolNoConnectionException) {
177 logger.error("Will close channel", exception);
178 Channels.close(e.getChannel());
179 return;
180 }
181 final ErrorPacket errorPacket = new ErrorPacket(exception
182 .getMessage(),
183 ErrorCode.RemoteError.getCode(), ErrorPacket.FORWARDCLOSECODE);
184 ChannelUtils.writeAbstractLocalPacket(localChannelReference, errorPacket, true);
185 if (!localChannelReference.getFutureRequest().isDone()) {
186 localChannelReference.invalidateRequest(new R66Result(
187 exception, localChannelReference.getSession(), true, ErrorCode.Internal, null));
188 }
189 } else {
190
191 return;
192 }
193 }
194 logger.debug("Will close channel");
195 ChannelCloseTimer.closeFutureChannel(e.getChannel());
196 }
197
198 }