View Javadoc
1   package org.kuali.ole.sip2.sip2Server;
2   
3   import io.netty.buffer.ByteBuf;
4   import io.netty.buffer.Unpooled;
5   import io.netty.channel.ChannelFuture;
6   import io.netty.channel.ChannelHandlerContext;
7   import io.netty.channel.ChannelInboundHandlerAdapter;
8   import io.netty.util.CharsetUtil;
9   import org.apache.commons.lang3.StringUtils;
10  import org.apache.http.HttpEntity;
11  import org.apache.http.HttpResponse;
12  import org.apache.http.client.ClientProtocolException;
13  import org.apache.http.client.ResponseHandler;
14  import org.apache.http.client.methods.HttpGet;
15  import org.apache.http.impl.client.CloseableHttpClient;
16  import org.apache.http.impl.client.HttpClients;
17  import org.apache.http.util.EntityUtils;
18  import org.apache.log4j.Logger;
19  import org.kuali.ole.sip2.response.*;
20  
21  import java.io.FileNotFoundException;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.io.UnsupportedEncodingException;
25  import java.net.SocketAddress;
26  import java.net.URLEncoder;
27  import java.util.HashMap;
28  import java.util.Map;
29  import java.util.Properties;
30  
31  public class OLENettyServerHandler extends ChannelInboundHandlerAdapter {
32  
33      private final static Logger LOG = Logger.getLogger(OLENettyServerHandler.class.getName());
34      private static String INSTITUTION = "OLE";
35      private String serverURL;
36      private String circulationService;
37  
38      /*private String clientName;
39      private String clientLocation;*/
40      private String clientIP;
41      private String loginUserId;
42  
43      private Map<String, String> lastResponseSendToClient = new HashMap<String, String>();
44  
45      protected Properties properties = new Properties();
46  
47      String propertiesFileName = "sip2-config.properties";
48      InputStream inputStream;
49  
50      public OLENettyServerHandler() {
51          // TODO Auto-generated constructor stub
52      }
53  
54      public OLENettyServerHandler(String serverURL, String circulationService) {
55          this.serverURL = serverURL;
56          this.circulationService = circulationService;
57      }
58  
59      @Override
60      public void channelRegistered(ChannelHandlerContext channelHandlerContext) throws Exception {
61          super.channelRegistered(channelHandlerContext);
62          SocketAddress address = channelHandlerContext.channel().remoteAddress();
63          clientIP = address.toString();
64      }
65  
66      @Override
67      public void channelRead(ChannelHandlerContext channelHandlerContext, Object message) throws Exception {
68  
69  
70          LOG.info("Entry OLENettyServerHandler.channelRead(channelHandlerContext, message)");
71          ByteBuf byteBuf = (ByteBuf) message;
72          String requestMessage = "";
73          ChannelFuture channelFuture = null;
74          String response = "";
75  
76          try {/*
77              SocketAddress address = channelHandlerContext.channel().remoteAddress();
78              clientIP = address.toString();*/
79              requestMessage = byteBuf.toString(CharsetUtil.UTF_8);
80  
81              if (requestMessage != null && !requestMessage.equalsIgnoreCase("")) {
82                  response = this.processRequest(requestMessage);
83              }
84  
85              LOG.info("Client IP Address : " + clientIP);
86              LOG.info("Response Message : " + response);
87  
88              if (response != null) {
89                  String[] responseArray = response.split("\\$|$");
90  
91                  for (String responseMessage : responseArray) {
92                      channelFuture = channelHandlerContext.write(Unpooled.copiedBuffer(responseMessage, CharsetUtil.UTF_8));
93                      channelHandlerContext.flush();
94                      if (StringUtils.isNotBlank(responseMessage.trim())) {
95                          lastResponseSendToClient.put(clientIP, responseMessage);
96                      }
97                  }
98              }
99  
100 
101             if (channelFuture == null || !channelFuture.isSuccess()) {
102                 LOG.info("Send Failed: " + channelFuture.cause());
103             } else {
104                 LOG.info("Send Success ");
105             }
106 
107         } catch (Exception e) {
108             LOG.error(e.getMessage(), e);
109         } finally {
110             byteBuf.release();
111         }
112 
113         LOG.info("Exit OLENettyServerHandler.channelRead(channelHandlerContext, message)");
114 
115     }
116 
117 
118     public String processRequest(String requestData) {
119         String response = "";
120         //SC Status
121         LOG.info("Client IP Address : " + clientIP);
122         LOG.info("Request Message : " + requestData);
123         inputStream = getClass().getClassLoader().getResourceAsStream("sip2-config.properties");
124 
125         try {
126             if (inputStream != null) {
127                 properties.load(inputStream);
128             } else {
129                 throw new FileNotFoundException("property file '" + propertiesFileName + "' not found in the classpath");
130             }
131         } catch (IOException e) {
132             LOG.error(e.getMessage(), e);
133         }
134 
135         if (properties != null) {
136             String code = requestData.substring(0, 2);
137 
138             switch (code) {
139                 case "99":
140                     LOG.info("Request Type :  SC Status Request");
141                     response = this.sendRequestToOle(requestData, loginUserId);
142                     break;
143                 case "97":
144 
145 
146                     LOG.info("Request Type :  Request ACS Resend");
147 
148                     if (lastResponseSendToClient.containsKey(clientIP)) {
149 
150                         response = this.removeSeqNumFromResponse(lastResponseSendToClient.get(clientIP)) + "$|$";
151                         if (requestData.length() > 2) {
152                             response = response + requestData.replace("97", "96");
153                         } else {
154                             response = response + "96";
155                         }
156                     }
157 
158                     break;
159                 case "93":
160 
161                     LOG.info("Request Type :  Login Request");
162                     if (properties.getProperty("sip2.service.login").equalsIgnoreCase("yes")) {
163 
164                         response = this.sendRequestToOle(requestData, loginUserId);
165                         if (response.charAt(2) == '1') {
166                             this.loginUserId = getLoginUserId(requestData);
167                         }
168 
169                     } else {
170                         OLESIP2LoginTurnedOffResponse olesip2LoginTurnedOffResponse = new OLESIP2LoginTurnedOffResponse();
171                         response = olesip2LoginTurnedOffResponse.getOLESIP2LoginTurnedOffResponse(requestData);
172 
173                     }
174 
175                     break;
176                 case "09":
177 
178                     LOG.info("Request Type :  Checkin Request");
179                     if (properties.getProperty("sip2.service.checkIn").equalsIgnoreCase("yes")) {
180                         response = this.sendRequestToOle(requestData, loginUserId);
181                     } else {
182                         OLESIP2CheckInTurnedOffResponse olesip2CheckInTurnedOffResponse = new OLESIP2CheckInTurnedOffResponse();
183                         response = olesip2CheckInTurnedOffResponse.getOLESIP2CheckInTurnedOffResponse(requestData);
184                     }
185                     break;
186                 case "11":
187 
188                     LOG.info("Request Type :  Checkout Request");
189                     if (properties.getProperty("sip2.service.checkOut").equalsIgnoreCase("yes")) {
190                         response = this.sendRequestToOle(requestData, loginUserId);
191                     } else {
192                         OLESIP2CheckOutTurnedOffResponse olesip2CheckOutTurnedOffResponse = new OLESIP2CheckOutTurnedOffResponse();
193                         response = olesip2CheckOutTurnedOffResponse.getOLESIP2CheckOutTurnedOffResponse(requestData);
194                     }
195 
196                     break;
197                 case "17":
198                     LOG.info("Request Type :  Item Information");
199                     if (properties.getProperty("sip2.service.itemInformation").equalsIgnoreCase("yes")) {
200                         response = this.sendRequestToOle(requestData, loginUserId);
201                     } else {
202                         OLESIP2ItemInfoTurnedOffResponse olesip2ItemInfoTurnedOffResponse = new OLESIP2ItemInfoTurnedOffResponse();
203                         response = olesip2ItemInfoTurnedOffResponse.getOLESIP2ItemInfoTurnedOffResponse(requestData);
204                     }
205 
206                     break;
207                 case "23":
208                     LOG.info("Request Type :  Patron Status Request");
209                     if (properties.getProperty("sip2.service.patronStatus").equalsIgnoreCase("yes")) {
210                         response = this.sendRequestToOle(requestData, loginUserId);
211                     } else {
212                         OLESIP2PatronStatusTurnedOffResponse patronStatusTurnedOffResponse = new OLESIP2PatronStatusTurnedOffResponse();
213                         response = patronStatusTurnedOffResponse.getOLESIP2PatronStatusTurnedOffResponse(requestData, "Patron Status Request");
214                     }
215 
216                     break;
217                 case "63":
218                     LOG.info("Request Type :  Patron Information");
219                     if (properties.getProperty("sip2.service.patronInformation").equalsIgnoreCase("yes")) {
220                         response = this.sendRequestToOle(requestData, loginUserId);
221                     } else {
222                         OLESIP2PatronInformationTurnedOffResponse patronInformationTurnedOffResponse = new OLESIP2PatronInformationTurnedOffResponse();
223                         response = patronInformationTurnedOffResponse.getOLESIP2PatronInformationTurnedOffResponse(requestData);
224                     }
225 
226 
227                     break;
228                 case "01":
229                     LOG.info("Request Type :  Patron Block");
230                     if (properties.getProperty("sip2.service.blockPatron").equalsIgnoreCase("yes")) {
231                         response = this.sendRequestToOle(requestData, loginUserId);
232                     } else {
233                         OLESIP2PatronStatusTurnedOffResponse patronStatusTurnedOffResponse = new OLESIP2PatronStatusTurnedOffResponse();
234                         response = patronStatusTurnedOffResponse.getOLESIP2PatronStatusTurnedOffResponse(requestData, "Patron Block Request");
235                     }
236 
237                     break;
238 
239                 case "25":
240 
241                     LOG.info("Request Type :  Patron Enable");
242                     if (properties.getProperty("sip2.service.patronEnable").equalsIgnoreCase("yes")) {
243                         response = this.sendRequestToOle(requestData, loginUserId);
244                     } else {
245                         OLESIP2PatronEnableTurnedOffResponse patronEnableTurnedOffResponse = new OLESIP2PatronEnableTurnedOffResponse();
246                         response = patronEnableTurnedOffResponse.getOLESIP2PatronEnableTurnedOffResponse(requestData);
247                     }
248                     break;
249                 case "35":
250                     LOG.info("Request Type :  End Patron Session");
251                     //response =this.endPatronSessionResponse();
252                     if (properties.getProperty("sip2.service.endPatronSession").equalsIgnoreCase("yes")) {
253                         response = this.sendRequestToOle(requestData, loginUserId);
254                     } else {
255                         OLESIP2EndPatronSessionTurnedOffResponse endPatronSessionTurnedOffResponse = new OLESIP2EndPatronSessionTurnedOffResponse();
256                         response = endPatronSessionTurnedOffResponse.getOLESIP2EndPatronSessionTurnedOffResponse(requestData);
257                     }
258                     break;
259                 case "29":
260 
261                     LOG.info("Request Type :  Renew");
262                     if (properties.getProperty("sip2.service.renew").equalsIgnoreCase("yes")) {
263                         response = this.sendRequestToOle(requestData, loginUserId);
264                     } else {
265                         OLESIP2RenewTurnedOffResponse renewTurnedOffResponse = new OLESIP2RenewTurnedOffResponse();
266                         response = renewTurnedOffResponse.getOLESIP2RenewTurnedOffResponse(requestData);
267                     }
268                     break;
269                 case "15":
270                     LOG.info("Request Type :  Hold");
271                     if (properties.getProperty("sip2.service.hold").equalsIgnoreCase("yes")) {
272                         response = this.sendRequestToOle(requestData, loginUserId);
273                     } else {
274                         OLESIP2HoldTurnedOffResponse holdTurnedOffResponse = new OLESIP2HoldTurnedOffResponse();
275                         response = holdTurnedOffResponse.getOLESIP2HoldTurnedOffResponse(requestData);
276                     }
277 
278                     break;
279                 case "37":
280                     LOG.info("Request Type :  Fee Paid Message");
281                     if (properties.getProperty("sip2.service.feePaid").equalsIgnoreCase("yes")) {
282                         response = this.sendRequestToOle(requestData, loginUserId);
283                     } else {
284                         OLESIP2FeePaidTurnedOffResponse olesip2FeePaidTurnedOffResponse = new OLESIP2FeePaidTurnedOffResponse();
285                         response = olesip2FeePaidTurnedOffResponse.getOLESIP2FeePaidTurnedOffResponse(requestData);
286                     }
287 
288                     break;
289                 case "65":
290 
291                     LOG.info("Request Type :  Renew All");
292                     if (properties.getProperty("sip2.service.renewAll").equalsIgnoreCase("yes")) {
293                         response = this.sendRequestToOle(requestData, loginUserId);
294 
295                     } else {
296                         OLESIP2RenewAllTurnedOffResponse renewAllTurnedOffResponse = new OLESIP2RenewAllTurnedOffResponse();
297                         response = renewAllTurnedOffResponse.getOLESIP2RenewAllTurnedOffResponse(requestData);
298                     }
299 
300                     break;
301                 case "19":
302 
303                     LOG.info("Request Type :  Item Status Update");
304                     if (properties.getProperty("sip2.service.itemStatusUpdate").equalsIgnoreCase("yes")) {
305                         response = this.sendRequestToOle(requestData, loginUserId);
306                     } else {
307                         OLESIP2ItemStatusUpdateTurnedOffResponse itemStatusUpdateTurnedOffResponse = new OLESIP2ItemStatusUpdateTurnedOffResponse();
308                         response = itemStatusUpdateTurnedOffResponse.getOLESIP2ItemStatusUpdateTurnedOffResponse(requestData);
309                     }
310 
311                     break;
312 
313 
314                 default:
315                     LOG.info("Request Type :  *****Not a valid SIP2 request");
316                     new Throwable("Not a valid SIP2 request");
317 
318                     break;
319             }
320 
321 
322         }
323 
324 
325         LOG.info("Exit OLENettyServerHandler.analysisRequestType(String requestData)");
326         return response;
327     }
328 
329 
330     public String sendRequestToOle(String requestData, String loginUserId) {
331         LOG.info("Entry OLENettyServerHandler.sendRequestToOle(restRequestURL, clientRequest, requestRResponseType)");
332         String url = "";
333         try {
334             if (loginUserId != null && !loginUserId.equalsIgnoreCase("")) {
335                 url = serverURL + circulationService + "sipService&requestData=" + URLEncoder.encode(requestData, "UTF-8") + "&loginUser=" + loginUserId;
336             } else {
337                 url = serverURL + circulationService + "sipService&requestData=" + URLEncoder.encode(requestData, "UTF-8");
338             }
339         } catch (UnsupportedEncodingException e1) {
340             // TODO Auto-generated catch block
341             e1.printStackTrace();
342         }
343         ;
344         LOG.info("URL  : " + url);
345         String response = "";
346         try {
347             response = this.httpGet(url, requestData);
348         } catch (Exception e) {
349             LOG.error(e.getMessage(), e);
350         }
351         LOG.info("Exit OLENettyServerHandler.sendRequestToOle(restRequestURL, clientRequest, requestRResponseType)");
352         return response;
353 
354     }
355 
356 
357     @Override
358     public void channelReadComplete(ChannelHandlerContext channelHandlerContext) {
359         LOG.info("Entry OLENettyServerHandler.channelReadComplete(channelHandlerContext)");
360         channelHandlerContext.flush();
361         LOG.info("Exit OLENettyServerHandler.channelReadComplete(channelHandlerContext)");
362     }
363 
364 
365     @Override
366     public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
367             throws Exception {
368         LOG.info("Entry OLENettyServerHandler.exceptionCaught(channelHandlerContext, cause)");
369         // TODO Auto-generated method stub
370         //super.exceptionCaught(ctx, cause);
371         LOG.error("Client (" + clientIP + ") disconnected from server.");
372         LOG.info("Exit OLENettyServerHandler.exceptionCaught(channelHandlerContext, cause)");
373     }
374 
375 
376     public String httpGet(String url, String requestData) {
377         LOG.info("Entry OLENettyServerHandler.httpGet(url, requestRResponseType)");
378 
379 
380         String response = null;
381         CloseableHttpClient httpclient = null;
382         HttpGet httpget = null;
383         ResponseHandler<String> responseHandler = null;
384         try {
385 
386             httpclient = HttpClients.createDefault();
387 
388             httpget = new HttpGet(url);
389             LOG.info("Executing request " + httpget.getRequestLine());
390 
391             // Create a custom response handler
392             responseHandler = new ResponseHandler<String>() {
393 
394                 public String handleResponse(
395                         final HttpResponse response) throws ClientProtocolException {
396                     int status = response.getStatusLine().getStatusCode();
397                     //if (status >= 200 && status < 300) {
398                     HttpEntity entity = response.getEntity();
399                     try {
400                         return entity != null ? EntityUtils.toString(entity) : null;
401                     } catch (IOException e) {
402                         e.printStackTrace();
403                         return null;
404                     }
405                     /*} else {
406                         throw new ClientProtocolException("Unexpected response status: " + status);
407                     }*/
408                 }
409             };
410             response = httpclient.execute(httpget, responseHandler);
411         } catch (Exception ex) {
412 
413             if (requestData.startsWith("99")) {
414 
415                 response = this.scStatusNegativeResponse(requestData);
416             } else {
417                 ex.printStackTrace();
418             }
419 
420         } finally {
421             try {
422                 httpclient.close();
423                 if (requestData.startsWith("99") && !response.startsWith("98")) {
424 
425                     response = this.scStatusNegativeResponse(requestData);
426                 } else {
427                     return response;
428                 }
429 
430             } catch (Exception ex) {
431                 ex.printStackTrace();
432 
433             }
434         }
435 
436         LOG.info("Exit OLENettyServerHandler.httpGet(url, requestRResponseType)");
437         return response;
438     }
439 
440     private String scStatusNegativeResponse(String requestData) {
441 
442         LOG.info("Entry OLENettyServerHandler.scStatusNegativeResponse()");
443         requestData = requestData.trim();
444 
445         StringBuilder builder = new StringBuilder();
446         builder.append(98);
447         builder.append("N");
448         builder.append("N");
449         builder.append("N");
450         builder.append("N");
451         builder.append("N");
452         builder.append("N");
453         builder.append("010");
454         builder.append("003");
455         builder.append(MessageUtil.getSipDateTime());
456         builder.append("2.00");
457         builder.append("AO");
458         builder.append("InId");
459         builder.append("|AM");
460         builder.append(INSTITUTION);
461 
462         if (requestData.length() == 19) {
463             if (requestData.substring(10, 12).equalsIgnoreCase("AY")) {
464                 builder.append("|AY");
465                 builder.append(requestData.substring(12, 15));
466                 builder.append(MessageUtil.computeChecksum(builder.toString()));
467 
468             }
469         }
470 
471 
472         LOG.info("Exit OLENettyServerHandler.scStatusNegativeResponse()");
473         return builder.toString() + '\r';
474     }
475 
476 
477     private String removeSeqNumFromResponse(String lastResponse) {
478 
479         StringBuilder builder = new StringBuilder();
480 
481         if (lastResponse.contains("AY")) {
482             int indexOfSeqNum = lastResponse.indexOf("AY");
483             builder.append(MessageUtil.computeChecksum(lastResponse.replace(lastResponse.substring(indexOfSeqNum, indexOfSeqNum + 5), "")));
484         }
485         return builder.toString() + '\r';
486 
487     }
488 
489     public String getLoginUserId(String requestData) {
490 
491         String[] requestDataArray = requestData.split("\\|");
492         String loginUser = "";
493         try {
494             for (String data : requestDataArray) {
495                 if (data.startsWith("93")) {
496                     loginUser = data.substring(6);
497                     break;
498                 }
499             }
500 
501         } catch (Exception e) {
502             LOG.error(e.getMessage(), e);
503         }
504         return loginUser;
505     }
506 
507 
508 }