1 20 21 package org.snmp4j; 22 23 import java.io.IOException ; 24 import java.util.*; 25 26 import org.snmp4j.event.*; 27 import org.snmp4j.log.*; 28 import org.snmp4j.mp.*; 29 import org.snmp4j.security.*; 30 import org.snmp4j.smi.*; 31 import org.snmp4j.transport.TransportMappings; 32 import org.snmp4j.transport.ConnectionOrientedTransportMapping; 33 34 138 public class Snmp implements Session, CommandResponder { 139 140 private static final LogAdapter logger = LogFactory.getLogger(Snmp.class); 141 142 private MessageDispatcher messageDispatcher; 144 145 149 private Hashtable pendingRequests = new Hashtable(50); 150 151 155 private Hashtable asyncRequests = new Hashtable(50); 156 157 private Timer timer = new Timer(true); 159 160 private transient Vector commandResponderListeners; 162 163 private TimeoutModel timeoutModel = new DefaultTimeoutModel(); 164 165 private NotificationDispatcher notificationDispatcher = null; 167 168 private ReportHandler reportHandler = new ReportProcessor(); 170 171 181 public Snmp() { 182 this.messageDispatcher = new MessageDispatcherImpl(); 183 } 184 185 192 public static interface ReportHandler { 193 void processReport(PduHandle pduHandle, CommandResponderEvent event); 194 } 195 196 protected final void initMessageDispatcher() { 197 this.messageDispatcher.addCommandResponder(this); 198 this.messageDispatcher.addMessageProcessingModel(new MPv2c()); 199 this.messageDispatcher.addMessageProcessingModel(new MPv1()); 200 this.messageDispatcher.addMessageProcessingModel(new MPv3()); 201 SecurityProtocols.getInstance().addDefaultProtocols(); 202 } 203 204 213 public Snmp(TransportMapping transportMapping) { 214 this(); 215 initMessageDispatcher(); 216 if (transportMapping != null) { 217 addTransportMapping(transportMapping); 218 } 219 } 220 221 238 public Snmp(MessageDispatcher messageDispatcher, 239 TransportMapping transportMapping) { 240 this.messageDispatcher = messageDispatcher; 241 this.messageDispatcher.addCommandResponder(this); 242 if (transportMapping != null) { 243 addTransportMapping(transportMapping); 244 } 245 } 246 247 264 public Snmp(MessageDispatcher messageDispatcher) { 265 this.messageDispatcher = messageDispatcher; 266 this.messageDispatcher.addCommandResponder(this); 267 } 268 269 275 public MessageDispatcher getMessageDispatcher() { 276 return messageDispatcher; 277 } 278 279 284 public void addTransportMapping(TransportMapping transportMapping) { 285 messageDispatcher.addTransportMapping(transportMapping); 287 transportMapping.addTransportListener(messageDispatcher); 288 } 289 290 297 public void removeTransportMapping(TransportMapping transportMapping) { 298 messageDispatcher.removeTransportMapping(transportMapping); 299 transportMapping.removeTransportListener(messageDispatcher); 300 } 301 302 320 public synchronized boolean addNotificationListener(Address listenAddress, 321 CommandResponder listener) 322 { 323 TransportMapping tm = 324 TransportMappings.getInstance().createTransportMapping(listenAddress); 325 if (tm == null) { 326 if (logger.isInfoEnabled()) { 327 logger.info("Failed to add notification listener for address: "+ 328 listenAddress); 329 } 330 return false; 331 } 332 if (tm instanceof ConnectionOrientedTransportMapping) { 333 ((ConnectionOrientedTransportMapping)tm).setConnectionTimeout(0); 334 } 335 tm.addTransportListener(messageDispatcher); 336 if (notificationDispatcher == null) { 337 notificationDispatcher = new NotificationDispatcher(); 338 addCommandResponder(notificationDispatcher); 339 } 340 notificationDispatcher.addNotificationListener(listenAddress, tm, listener); 341 try { 342 tm.listen(); 343 if (logger.isInfoEnabled()) { 344 logger.info("Added notification listener for address: "+ 345 listenAddress); 346 } 347 return true; 348 } 349 catch (IOException ex) { 350 logger.warn("Failed to initialize notification listener for address '"+ 351 listenAddress+"': "+ex.getMessage()); 352 return false; 353 } 354 } 355 356 365 public synchronized boolean removeNotificationListener(Address listenAddress) 366 { 367 if (notificationDispatcher != null) { 368 if (logger.isInfoEnabled()) { 369 logger.info("Removing notification listener for address: "+ 370 listenAddress); 371 } 372 return notificationDispatcher.removeNotificationListener(listenAddress); 373 } 374 else { 375 return false; 376 } 377 } 378 379 385 public void listen() throws IOException { 386 for (Iterator it = messageDispatcher.getTransportMappings().iterator(); 387 it.hasNext(); ) { 388 TransportMapping tm = (TransportMapping) it.next(); 389 if (!tm.isListening()) { 390 tm.listen(); 391 } 392 } 393 } 394 395 404 public int getNextRequestID() { 405 return messageDispatcher.getNextRequestID(); 406 } 407 408 421 public void close() throws IOException { 422 for (Iterator it = messageDispatcher.getTransportMappings().iterator(); 423 it.hasNext(); ) { 424 ((TransportMapping) it.next()).close(); 425 } 426 timer.cancel(); 427 for (Iterator it = pendingRequests.values().iterator(); it.hasNext(); ) { 428 PendingRequest pending = (PendingRequest) it.next(); 429 ResponseEvent e = 430 new ResponseEvent(this, null, pending.pdu, null, pending.userObject, 431 new InterruptedException ( 432 "Snmp session has been closed")); 433 pending.listener.onResponse(e); 434 } 435 if (notificationDispatcher != null) { 437 notificationDispatcher.closeAll(); 438 } 439 } 440 441 460 public ResponseEvent get(PDU pdu, Target target) throws IOException { 461 pdu.setType(PDU.GET); 462 return send(pdu, target); 463 } 464 465 486 public void get(PDU pdu, Target target, Object userHandle, 487 ResponseListener listener) throws IOException { 488 pdu.setType(PDU.GET); 489 send(pdu, target, userHandle, listener); 490 } 491 492 512 public ResponseEvent getNext(PDU pdu, Target target) throws IOException { 513 pdu.setType(PDU.GETNEXT); 514 return send(pdu, target); 515 } 516 517 538 public void getNext(PDU pdu, Target target, Object userHandle, 539 ResponseListener listener) throws IOException { 540 pdu.setType(PDU.GETNEXT); 541 send(pdu, target, userHandle, listener); 542 } 543 544 564 public ResponseEvent getBulk(PDU pdu, Target target) throws IOException { 565 pdu.setType(PDU.GETBULK); 566 return send(pdu, target); 567 } 568 569 590 public void getBulk(PDU pdu, Target target, Object userHandle, 591 ResponseListener listener) throws IOException { 592 pdu.setType(PDU.GETBULK); 593 send(pdu, target, userHandle, listener); 594 } 595 596 616 public ResponseEvent inform(PDU pdu, Target target) throws IOException { 617 pdu.setType(PDU.INFORM); 618 return send(pdu, target); 619 } 620 621 642 public void inform(PDU pdu, Target target, Object userHandle, 643 ResponseListener listener) throws IOException { 644 pdu.setType(PDU.INFORM); 645 send(pdu, target, userHandle, listener); 646 } 647 648 663 public void trap(PDUv1 pdu, Target target) throws IOException { 664 if (target.getVersion() != SnmpConstants.version1) { 665 throw new IllegalArgumentException ( 666 "SNMPv1 trap PDU must be used with SNMPv1"); 667 } 668 pdu.setType(PDU.V1TRAP); 669 send(pdu, target); 670 } 671 672 688 public void notify(PDU pdu, Target target) throws IOException { 689 if (target.getVersion() == SnmpConstants.version1) { 690 throw new IllegalArgumentException ( 691 "Notifications PDUs cannot be used with SNMPv1"); 692 } 693 pdu.setType(PDU.NOTIFICATION); 694 send(pdu, target); 695 } 696 697 698 715 public ResponseEvent set(PDU pdu, Target target) { 716 pdu.setType(PDU.SET); 717 try { 718 return send(pdu, target); 719 } 720 catch (IOException ex) { 721 return new ResponseEvent(this, null, pdu, null, target, ex); 722 } 723 } 724 725 746 public void set(PDU pdu, Target target, Object userHandle, 747 ResponseListener listener) throws IOException { 748 pdu.setType(PDU.SET); 749 send(pdu, target, userHandle, listener); 750 } 751 752 public ResponseEvent send(PDU pdu, Target target) throws IOException { 753 return send(pdu, target, null); 754 } 755 756 786 public ResponseEvent send(PDU pdu, Target target, 787 TransportMapping transport) throws IOException { 788 if (!pdu.isConfirmedPdu()) { 789 sendMessage(pdu, target, transport, null); 790 return null; 791 } 792 SyncResponseListener syncResponse = new SyncResponseListener(); 793 PendingRequest retryRequest = null; 794 synchronized (syncResponse) { 795 PduHandle handle = null; 796 PendingRequest request = 797 new PendingRequest(syncResponse, target, pdu, target, transport); 798 handle = sendMessage(pdu, target, transport, request); 799 try { 800 syncResponse.wait(); 801 retryRequest = (PendingRequest) pendingRequests.remove(handle); 802 if (logger.isDebugEnabled()) { 803 logger.debug("Removed pending request with handle: "+handle); 804 } 805 request.setFinished(); 806 request.cancel(); 807 } 808 catch (InterruptedException iex) { 809 logger.warn(iex); 810 } 812 } 813 if (retryRequest != null) { 814 synchronized (retryRequest) { 815 retryRequest.setFinished(); 816 retryRequest.cancel(); 817 } 818 } 819 return syncResponse.response; 820 } 821 822 public void send(PDU pdu, Target target, 823 Object userHandle, 824 ResponseListener listener) throws IOException { 825 send(pdu, target, null, userHandle, listener); 826 } 827 828 public void send(PDU pdu, Target target, 829 TransportMapping transport, 830 Object userHandle, 831 ResponseListener listener) throws IOException { 832 if (!pdu.isConfirmedPdu()) { 833 sendMessage(pdu, target, transport, null); 834 return; 835 } 836 PendingRequest request = 837 new AsyncPendingRequest(listener, userHandle, pdu, target, transport); 838 sendMessage(pdu, target, transport, request); 839 } 840 841 868 public PDU sendPDU(PDU pdu, Target target) throws IOException { 869 ResponseEvent e = send(pdu, target); 870 if (e != null) { 871 return e.getResponse(); 872 } 873 return null; 875 } 876 877 901 public void sendPDU(PDU pdu, 902 Target target, 903 Object userHandle, 904 ResponseListener listener) throws IOException { 905 send(pdu, target, userHandle, listener); 906 } 907 908 926 protected PduHandle sendMessage(PDU pdu, Target target, 927 TransportMapping transport, 928 PduHandleCallback pduHandleCallback) 929 throws IOException 930 { 931 PduHandle handle = null; 932 if (target instanceof SecureTarget) { 933 SecureTarget secureTarget = (SecureTarget) target; 934 handle = messageDispatcher.sendPdu(transport, 935 secureTarget.getAddress(), 936 secureTarget.getVersion(), 937 secureTarget.getSecurityModel(), 938 secureTarget.getSecurityName(). 939 getValue(), 940 secureTarget.getSecurityLevel(), 941 pdu, true, pduHandleCallback); 942 } 943 else if (target instanceof CommunityTarget) { 944 CommunityTarget communityTarget = (CommunityTarget) target; 945 int securityModel = SecurityModel.SECURITY_MODEL_SNMPv2c; 946 if (communityTarget.getVersion() == SnmpConstants.version1) { 947 securityModel = SecurityModel.SECURITY_MODEL_SNMPv1; 948 } 949 handle = messageDispatcher.sendPdu(transport, 950 communityTarget.getAddress(), 951 communityTarget.getVersion(), 952 securityModel, 953 communityTarget.getCommunity(). 954 getValue(), 955 SecurityLevel.NOAUTH_NOPRIV, 956 pdu, true, pduHandleCallback); 957 958 } 959 return handle; 960 } 961 962 public void cancel(PDU request, ResponseListener listener) { 963 AsyncRequestKey key = new AsyncRequestKey(request, listener); 964 PduHandle pending = (PduHandle) asyncRequests.remove(key); 965 if (logger.isDebugEnabled()) { 966 logger.debug("Cancelling pending request with handle " + pending); 967 } 968 if (pending != null) { 969 PendingRequest pendingRequest = 970 (PendingRequest) pendingRequests.remove(pending); 971 if (pendingRequest != null) { 972 synchronized (pendingRequest) { 973 pendingRequest.setFinished(); 974 pendingRequest.cancel(); 975 } 976 } 977 } 978 } 979 980 995 public void setLocalEngine(byte[] engineID, 996 int engineBoots, 997 int engineTime) { 998 MPv3 mpv3 = getMPv3(); 999 mpv3.setLocalEngineID(engineID); 1000 USM usm = (USM) mpv3.getSecurityModel(SecurityModel.SECURITY_MODEL_USM); 1001 usm.setLocalEngine(new OctetString(engineID), engineBoots, engineTime); 1002 } 1003 1004 1010 public byte[] getLocalEngineID() { 1011 return getMPv3().getLocalEngineID(); 1012 } 1013 1014 private MPv3 getMPv3() { 1015 MPv3 mpv3 = (MPv3) getMessageProcessingModel(MessageProcessingModel.MPv3); 1016 if (mpv3 == null) { 1017 throw new NoSuchElementException("MPv3 not available"); 1018 } 1019 return mpv3; 1020 } 1021 1022 1041 public byte[] discoverAuthoritativeEngineID(Address address, long timeout) { 1042 MPv3 mpv3 = getMPv3(); 1043 OctetString engineID = mpv3.removeEngineID(address); 1045 if (engineID != null) { 1047 USM usm = getUSM(); 1048 if (usm != null) { 1049 usm.removeEngineTime(engineID); 1050 } 1051 } 1052 ScopedPDU scopedPDU = new ScopedPDU(); 1053 scopedPDU.setType(PDU.GET); 1054 SecureTarget target = new UserTarget(); 1055 target.setTimeout(timeout); 1056 target.setAddress(address); 1057 try { 1058 send(scopedPDU, target); 1059 OctetString authoritativeEngineID = mpv3.getEngineID(address); 1060 if (authoritativeEngineID == null) { 1061 return null; 1062 } 1063 return new OctetString(authoritativeEngineID.getValue()).getValue(); 1066 } 1067 catch (IOException ex) { 1068 logger.error( 1069 "IO error while trying to discover authoritative engine ID: " + 1070 ex); 1071 return null; 1072 } 1073 } 1074 1075 1082 public USM getUSM() { 1083 return (USM) SecurityModels.getInstance().getSecurityModel( 1084 new Integer32(SecurityModel.SECURITY_MODEL_USM)); 1085 } 1086 1087 1096 public MessageProcessingModel getMessageProcessingModel(int 1097 messageProcessingModel) { 1098 return messageDispatcher.getMessageProcessingModel(messageProcessingModel); 1099 } 1100 1101 1108 public void processPdu(CommandResponderEvent event) { 1109 PduHandle handle = event.getPduHandle(); 1110 PDU pdu = event.getPDU(); 1111 if (pdu.getType() == PDU.RESPONSE) { 1112 event.setProcessed(true); 1113 PendingRequest request; 1114 if (logger.isDebugEnabled()) { 1115 logger.debug("Looking up pending request with handle " + handle); 1116 } 1117 request = (PendingRequest) pendingRequests.get(handle); 1118 if (request == null) { 1119 if (logger.isWarnEnabled()) { 1120 logger.warn("Received response that cannot be matched to any " + 1121 "outstanding request, address=" + 1122 event.getPeerAddress() + 1123 ", requestID=" + pdu.getRequestID()); 1124 } 1125 } 1126 if (request == null) { 1127 logger.warn("Received response that cannot be matched to any " + 1128 "outstanding request, address=" + 1129 event.getPeerAddress() + 1130 ", requestID=" + pdu.getRequestID()); 1131 } 1132 else { 1133 request.listener.onResponse(new ResponseEvent(this, 1134 event.getPeerAddress(), 1135 request.pdu, 1136 pdu, 1137 request.userObject)); 1138 } 1139 } 1140 else if (pdu.getType() == PDU.REPORT) { 1141 event.setProcessed(true); 1142 reportHandler.processReport(handle, event); 1143 } 1144 else { 1145 if (logger.isDebugEnabled()) { 1146 logger.debug("Fire process PDU event: " + event.toString()); 1147 } 1148 fireProcessPdu(event); 1149 } 1150 } 1151 1152 class ReportProcessor implements ReportHandler { 1153 1154 public void processReport(PduHandle handle, CommandResponderEvent e) { 1155 PDU pdu = e.getPDU(); 1156 logger.debug("Searching pending request with handle" + handle); 1157 PendingRequest request = (PendingRequest) pendingRequests.get(handle); 1158 if (request == null) { 1159 logger.warn("Unmatched report PDU received from " + e.getPeerAddress()); 1160 return; 1161 } 1162 if (pdu.size() == 0) { 1163 logger.error("Illegal report PDU received from " + e.getPeerAddress() + 1164 " missing report variable binding"); 1165 return; 1166 } 1167 VariableBinding vb = pdu.get(0); 1168 if (vb == null) { 1169 logger.error("Received illegal REPORT PDU from " + e.getPeerAddress()); 1170 return; 1171 } 1172 OID firstOID = vb.getOid(); 1173 boolean resend = false; 1174 if (request.requestStatus < request.maxRequestStatus) { 1175 switch (request.requestStatus) { 1176 case 0: 1177 if (SnmpConstants.usmStatsUnknownEngineIDs.equals(firstOID)) { 1178 resend = true; 1179 } 1180 else if (SnmpConstants.usmStatsNotInTimeWindows.equals(firstOID)) { 1181 request.requestStatus++; 1182 resend = true; 1183 } 1184 break; 1185 case 1: 1186 if (SnmpConstants.usmStatsNotInTimeWindows.equals(firstOID)) { 1187 resend = true; 1188 } 1189 break; 1190 } 1191 } 1192 if (resend) { 1194 logger.debug("Send new request after report."); 1195 request.requestStatus++; 1196 try { 1197 PduHandle resentHandle = 1200 sendMessage(request.pdu, request.target, e.getTransportMapping(), 1201 null); 1202 request.key = resentHandle; 1205 } 1206 catch (IOException iox) { 1207 logger.error("Failed to send message to " + request.target + ": " + 1208 iox.getMessage()); 1209 return; 1210 } 1211 } 1212 else { 1213 boolean intime; 1214 synchronized (request) { 1215 intime = request.cancel(); 1216 } 1217 pendingRequests.remove(handle); 1220 if (intime) { 1221 request.listener.onResponse(new ResponseEvent(this, 1223 e.getPeerAddress(), 1224 request.pdu, 1225 pdu, 1226 request.userObject)); 1227 } 1228 else { 1229 if (logger.isInfoEnabled()) { 1231 logger.info("Received late report from " + 1232 e.getPeerAddress() + 1233 " with request ID " + pdu.getRequestID()); 1234 } 1235 } 1236 } 1237 } 1238 } 1239 1240 1241 1246 public synchronized void removeCommandResponder(CommandResponder listener) { 1247 if (commandResponderListeners != null && 1248 commandResponderListeners.contains(listener)) { 1249 Vector v = (Vector) commandResponderListeners.clone(); 1250 v.removeElement(listener); 1251 commandResponderListeners = v; 1252 } 1253 } 1254 1255 1264 public synchronized void addCommandResponder(CommandResponder listener) { 1265 Vector v = (commandResponderListeners == null) ? 1266 new Vector(2) : (Vector) commandResponderListeners.clone(); 1267 if (!v.contains(listener)) { 1268 v.addElement(listener); 1269 commandResponderListeners = v; 1270 } 1271 } 1272 1273 1280 protected void fireProcessPdu(CommandResponderEvent event) { 1281 if (commandResponderListeners != null) { 1282 Vector listeners = commandResponderListeners; 1283 int count = listeners.size(); 1284 for (int i = 0; i < count; i++) { 1285 ((CommandResponder) listeners.elementAt(i)).processPdu(event); 1286 if (event.isProcessed()) { 1289 return; 1290 } 1291 } 1292 } 1293 } 1294 1295 1301 public TimeoutModel getTimeoutModel() { 1302 return timeoutModel; 1303 } 1304 1305 1312 public ReportHandler getReportHandler() { 1313 return reportHandler; 1314 } 1315 1316 1325 public void setTimeoutModel(TimeoutModel timeoutModel) { 1326 if (timeoutModel == null) { 1327 throw new NullPointerException ("Timeout model cannot be null"); 1328 } 1329 this.timeoutModel = timeoutModel; 1330 } 1331 1332 1339 public void setReportHandler(ReportHandler reportHandler) { 1340 if (reportHandler == null) { 1341 throw new IllegalArgumentException ("ReportHandler must not be null"); 1342 } 1343 this.reportHandler = reportHandler; 1344 } 1345 1346 class PendingRequest extends TimerTask implements PduHandleCallback { 1347 1348 private PduHandle key; 1349 protected int retryCount; 1350 protected ResponseListener listener; 1351 protected Object userObject; 1352 1353 protected PDU pdu; 1354 protected Target target; 1355 protected TransportMapping transport; 1356 1357 private int requestStatus = 0; 1358 private int maxRequestStatus = 2; 1361 1362 private volatile boolean finished = false; 1363 1364 1365 public PendingRequest(ResponseListener listener, 1366 Object userObject, 1367 PDU pdu, 1368 Target target, 1369 TransportMapping transport) { 1370 this.userObject = userObject; 1371 this.listener = listener; 1372 this.retryCount = target.getRetries(); 1373 this.pdu = pdu; 1374 this.target = target; 1375 this.transport = transport; 1376 } 1377 1378 private PendingRequest(PendingRequest other) { 1379 this.userObject = other.userObject; 1380 this.listener = other.listener; 1381 this.retryCount = other.retryCount - 1; 1382 this.pdu = other.pdu; 1383 this.target = other.target; 1384 this.requestStatus = other.requestStatus; 1385 } 1386 1387 protected void registerRequest(PduHandle handle) { 1388 1389 } 1390 1391 public synchronized void pduHandleAssigned(PduHandle handle, Object pdu) { 1392 if (key == null) { 1393 key = handle; 1394 pendingRequests.put(handle, this); 1395 registerRequest(handle); 1396 if (logger.isDebugEnabled()) { 1397 logger.debug("Running pending "+ 1398 ((listener instanceof SyncResponseListener) ? 1399 "sync" : "async")+ 1400 " request with handle " + handle+ 1401 " and retry count left "+retryCount); 1402 } 1403 long delay = timeoutModel.getRetryTimeout(target.getRetries() - 1404 retryCount, 1405 target.getRetries(), 1406 target.getTimeout()); 1407 if (!finished) { 1408 timer.schedule(this, delay); 1409 } 1410 } 1411 } 1412 1413 1416 public synchronized void run() { 1417 try { 1418 if ((!finished) && (retryCount > 0)) { 1419 try { 1420 PendingRequest nextRetry = new PendingRequest(this); 1421 sendMessage(pdu, target, transport, nextRetry); 1422 } 1423 catch (IOException ex) { 1424 finished = true; 1425 logger.error("Failed to send SNMP message to " + target.toString() + 1426 ": " + 1427 ex.getMessage()); 1428 messageDispatcher.releaseStateReference(target.getVersion(), key); 1429 listener.onResponse(new ResponseEvent(Snmp.this, null, 1430 pdu, null, userObject, 1431 ex)); 1432 } 1433 } 1434 else if (!finished) { 1435 finished = true; 1436 pendingRequests.remove(key); 1437 1438 if (logger.isDebugEnabled()) { 1440 logger.debug("Request timed out: " + key.getTransactionID()); 1441 } 1442 messageDispatcher.releaseStateReference(target.getVersion(), key); 1443 listener.onResponse(new ResponseEvent(Snmp.this, null, 1444 pdu, null, userObject)); 1445 } 1446 } 1447 catch (RuntimeException ex) { 1448 if (logger.isDebugEnabled()) { 1449 ex.printStackTrace(); 1450 } 1451 logger.error("Failed to process pending request " + key + 1452 " because " + ex.getMessage(), ex); 1453 throw ex; 1454 } 1455 catch (Error er) { 1456 if (logger.isDebugEnabled()) { 1457 er.printStackTrace(); 1458 } 1459 logger.fatal("Failed to process pending request " + key + 1460 " because " + er.getMessage(), er); 1461 throw er; 1462 } 1463 } 1464 1465 public synchronized boolean setFinished() { 1466 boolean currentState = finished; 1467 this.finished = true; 1468 return currentState; 1469 } 1470 1471 public void setMaxRepuestStatus(int maxRepuestStatus) { 1472 this.maxRequestStatus = maxRepuestStatus; 1473 } 1474 1475 public int getMaxRepuestStatus() { 1476 return maxRequestStatus; 1477 } 1478 1479 } 1480 1481 class AsyncPendingRequest extends PendingRequest { 1482 public AsyncPendingRequest(ResponseListener listener, 1483 Object userObject, 1484 PDU pdu, 1485 Target target, 1486 TransportMapping transport) { 1487 super(listener, userObject, pdu, target, transport); 1488 } 1489 1490 protected void registerRequest(PduHandle handle) { 1491 AsyncRequestKey key = new AsyncRequestKey(super.pdu, super.listener); 1492 asyncRequests.put(key, handle); 1493 } 1494 } 1495 1496 static class AsyncRequestKey { 1497 private PDU request; 1498 private ResponseListener listener; 1499 1500 public AsyncRequestKey(PDU request, ResponseListener listener) { 1501 this.request = request; 1502 this.listener = listener; 1503 } 1504 1505 1512 public boolean equals(Object obj) { 1513 if (obj instanceof AsyncRequestKey) { 1514 AsyncRequestKey other = (AsyncRequestKey) obj; 1515 return (request.equals(other.request) && listener.equals(other.listener)); 1516 } 1517 return false; 1518 } 1519 1520 public int hashCode() { 1521 return request.hashCode(); 1522 } 1523 } 1524 1525 static class SyncResponseListener implements ResponseListener { 1526 1527 private ResponseEvent response = null; 1528 1529 public synchronized void onResponse(ResponseEvent event) { 1530 this.response = event; 1531 this.notify(); 1532 } 1533 1534 public ResponseEvent getResponse() { 1535 return response; 1536 } 1537 1538 } 1539 1540 1548 class NotificationDispatcher implements CommandResponder { 1549 private Hashtable notificationListeners = new Hashtable(10); 1552 private Hashtable notificationTransports = new Hashtable(10); 1553 1554 protected NotificationDispatcher() { 1555 } 1556 1557 public synchronized void addNotificationListener(Address listenAddress, 1558 TransportMapping transport, 1559 CommandResponder listener){ 1560 notificationListeners.put(listenAddress, transport); 1561 notificationTransports.put(transport, listener); 1562 } 1563 1564 public synchronized boolean 1565 removeNotificationListener(Address listenAddress) 1566 { 1567 TransportMapping tm = 1568 (TransportMapping)notificationListeners.remove(listenAddress); 1569 if (tm == null) { 1570 return false; 1571 } 1572 tm.removeTransportListener(messageDispatcher); 1573 notificationTransports.remove(tm); 1574 1575 try { 1576 tm.close(); 1577 } 1578 catch (IOException ex) { 1579 logger.error(ex); 1580 if (logger.isDebugEnabled()) { 1581 ex.printStackTrace(); 1582 } 1583 } 1584 return true; 1585 } 1586 1587 public synchronized void closeAll() { 1588 notificationTransports.clear(); 1589 for (Iterator it = notificationListeners.values().iterator(); 1590 it.hasNext();) { 1591 TransportMapping tm = (TransportMapping) it.next(); 1592 try { 1593 tm.close(); 1594 } 1595 catch (IOException ex) { 1596 logger.error(ex); 1597 if (logger.isDebugEnabled()) { 1598 ex.printStackTrace(); 1599 } 1600 } 1601 } 1602 notificationListeners.clear(); 1603 } 1604 1605 public synchronized void processPdu(CommandResponderEvent event) { 1606 CommandResponder listener = (CommandResponder) 1607 notificationTransports.get(event.getTransportMapping()); 1608 if ((event.getPDU() != null) && 1609 (event.getPDU().getType() == PDU.INFORM)) { 1610 try { 1612 sendInformResponse(event); 1613 } 1614 catch (MessageException mex) { 1615 if (logger.isWarnEnabled()) { 1616 logger.warn("Failed to send response on INFORM PDU event (" + 1617 event + "): " + mex.getMessage()); 1618 } 1619 } 1620 } 1621 if (listener != null) { 1622 listener.processPdu(event); 1623 } 1624 } 1625 1626 1633 protected void sendInformResponse(CommandResponderEvent event) throws 1634 MessageException { 1635 PDU responsePDU = (PDU) event.getPDU().clone(); 1636 responsePDU.setType(PDU.RESPONSE); 1637 responsePDU.setErrorStatus(PDU.noError); 1638 responsePDU.setErrorIndex(0); 1639 messageDispatcher.returnResponsePdu(event.getMessageProcessingModel(), 1640 event.getSecurityModel(), 1641 event.getSecurityName(), 1642 event.getSecurityLevel(), 1643 responsePDU, 1644 event.getMaxSizeResponsePDU(), 1645 event.getStateReference(), 1646 new StatusInformation()); 1647 } 1648 } 1649 1650} 1651 | Popular Tags |