From: Dave B. <bla...@us...> - 2012-02-22 12:28:50
|
Update of /cvsroot/sblim/jsr48-client/src/org/sblim/cimclient/internal/wbem/indications In directory vz-cvs-3.sog:/tmp/cvs-serv14303/src/org/sblim/cimclient/internal/wbem/indications Modified Files: CIMIndicationHandler.java ReliableIndicationHandler.java Added Files: RIHandlerTest.txt Log Message: 3484022 - Turn reliable indication mode on and off based on SC/SN Index: CIMIndicationHandler.java =================================================================== RCS file: /cvsroot/sblim/jsr48-client/src/org/sblim/cimclient/internal/wbem/indications/CIMIndicationHandler.java,v retrieving revision 1.27 retrieving revision 1.28 diff -u -d -r1.27 -r1.28 --- CIMIndicationHandler.java 20 Feb 2012 18:59:36 -0000 1.27 +++ CIMIndicationHandler.java 22 Feb 2012 12:28:48 -0000 1.28 @@ -38,6 +38,7 @@ * 3390724 2011-08-12 blaschke-oss Problem with Reliable Indication support in the Listener * 3459036 2011-12-13 blaschke-oss Linked list for RI queue not efficient for many LDs * 3485074 2012-02-06 blaschke-oss An Indication trace request + * 3484022 2012-02-08 blaschke-oss Turn reliable indication mode on and off based on SC/SN */ package org.sblim.cimclient.internal.wbem.indications; @@ -108,17 +109,14 @@ private boolean iRIInitialized = false; - private boolean iRISupported = false; - private ReliableIndicationHandler iRIHandler; public IndicationServer() { // initialize() does the work } - public void initialize(boolean pRISupported, ReliableIndicationHandler pRIHandler) { + public void initialize(ReliableIndicationHandler pRIHandler) { this.iRIInitialized = true; - this.iRISupported = pRISupported; this.iRIHandler = pRIHandler; } @@ -126,10 +124,6 @@ return this.iRIInitialized; } - public boolean isRISupported() { - return this.iRISupported; - } - public ReliableIndicationHandler getRIHandler() { return this.iRIHandler; } @@ -516,43 +510,8 @@ server = getIndicationServerFromTable(pInetAddress, pId); } - // Nothing to do if reliable indications initialized but not supported, - // go ahead and deliver - if (server.isInitialized() && !server.isRISupported()) return true; - - // Get reliable indication properties from indication - CIMProperty<?> seqCtxProp = pIndication.getProperty("SequenceContext"); - CIMProperty<?> seqNumProp = pIndication.getProperty("SequenceNumber"); - - // Initialize (if not yet done so) to check if indication is reliable + // Initialize if not yet done so if (!server.isInitialized()) { - // Initial indication does not contain reliable indication - // properties, disable support and go ahead and deliver - if (seqCtxProp == null || seqNumProp == null) { - server.initialize(false, null); - - this.iLogger - .trace( - Level.FINE, - "Reliable indication support disabled, initial indication does not contain SequenceContext and SequenceNumber properties"); - - return true; - } - - // Initial indication does not contain reliable indication - // properties with non-null values, disable support and go ahead - // and deliver - if (seqCtxProp.getValue() == null || seqNumProp.getValue() == null) { - server.initialize(false, null); - - this.iLogger - .trace( - Level.FINE, - "Reliable indication support disabled, initial indication does not contain SequenceContext and SequenceNumber properties with non-null values"); - - return true; - } - // Validate DeliveryRetryAttempts property long attempts = this.iSessionProperties.getListenerDeliveryRetryAttempts(); if (attempts <= 0 || attempts > 1000) { @@ -575,42 +534,18 @@ // Create new ReliableIndicationHandler for this // CIMIndicationHandler - server.initialize(true, new ReliableIndicationHandler(this.iDispatcher, attempts - * interval * 10 * 1000)); - - this.iLogger.trace(Level.FINE, - "Reliable indication support enabled, DeliveryRetryAttempts=" + attempts - + ", DeliveryRetryInterval=" + interval); - - // Let ReliableIndicationHandler deliver it - server.getRIHandler().handleIndication(pIndication, seqCtxProp, seqNumProp, pId, - pInetAddress); - return false; - } - - // Reliable indication support is enabled but indication does not - // contain both properties, go ahead and deliver - if (seqCtxProp == null || seqNumProp == null) { - this.iLogger.trace(Level.FINE, - "Reliable indication support enabled but sequence property missing:\n" - + pIndication.toString()); - - return true; - } - - // Reliable indication support is enabled but indication does not - // contain both properties with non-null values, go ahead and deliver - if (seqCtxProp.getValue() == null || seqNumProp.getValue() == null) { - this.iLogger.trace(Level.FINE, - "Reliable indication support enabled but sequence property has null value:\n" - + pIndication.toString()); + server.initialize(new ReliableIndicationHandler(this.iDispatcher, attempts * interval + * 10 * 1000)); - return true; + this.iLogger + .trace(Level.FINE, "Reliable indication support enabled for IP " + + pInetAddress.getHostAddress() + " and URL " + pId + + ", DeliveryRetryAttempts=" + attempts + ", DeliveryRetryInterval=" + + interval); } // Let ReliableIndicationHandler deliver it - server.getRIHandler().handleIndication(pIndication, seqCtxProp, seqNumProp, pId, - pInetAddress); + server.getRIHandler().handleIndication(pIndication, pId, pInetAddress); return false; } --- NEW FILE: RIHandlerTest.txt --- This text file contains Java code that can be inserted into CIMIndicationHandler.java in the dispatchIndications method between the following two lines: CIMInstance indicationInst = (CIMInstance) cimEvent; and: String path = pReader.getMethod().getFile(); This Java code will alter incoming indications to produce out-of-order, duplicate and missing indications as well as context switches and switches from SC/SN on to off and SC/SN off to on. Either Jsr48PegasusIndicationSample or Jsr48SfcbIndicationSample can be used to exercise this Java code, simply alter the samples to: 1) generate 35 indications instead of 1 2) move Thread.sleep(5000) out of loop to end and increase to 30000 3) set sblim.wbem.listenerDeliveryRetryAttempts=1 and sblim.wbem.listenerDeliveryRetryInterval=1 Java code snippet #1 tests just about everything, starting with SC/SN on: CIMProperty<?> seqNumProp = indicationInst.getProperty("SequenceNumber"); Long seqNum = (Long) seqNumProp.getValue(); long seqNumVal = seqNum.longValue(); // 2,3,4 out of order until 5 arrives // 7 missing // 9 duplicate // 11-14 new context, #'s 11-14 // 15-18 null context // 19-24 new context, #'s 0-5 // 25-27 null context // 28+ new context, out of order until 6 arrives String newCtx1 = new String("MyShinyNewContext"); String newCtx2 = new String("MyBrandSpankingShinyNewContext"); String newCtx3 = new String("MyLastAndFinalBrandSpankingShinyNewContext"); if (seqNumVal == 2) { CIMProperty<?> n[] = { new CIMProperty<Long>("SequenceNumber", CIMDataType.SINT64_T, new Long("3")) }; indicationInst = indicationInst.deriveInstance(n); } else if (seqNumVal == 3) { CIMProperty<?> n[] = { new CIMProperty<Long>("SequenceNumber", CIMDataType.SINT64_T, new Long("4")) }; indicationInst = indicationInst.deriveInstance(n); } else if (seqNumVal == 4) { CIMProperty<?> n[] = { new CIMProperty<Long>("SequenceNumber", CIMDataType.SINT64_T, new Long("5")) }; indicationInst = indicationInst.deriveInstance(n); } else if (seqNumVal == 5) { CIMProperty<?> n[] = { new CIMProperty<Long>("SequenceNumber", CIMDataType.SINT64_T, new Long("2")) }; indicationInst = indicationInst.deriveInstance(n); } else if (seqNumVal == 7) { CIMProperty<?> n[] = { new CIMProperty<Long>("SequenceNumber", CIMDataType.SINT64_T, new Long("9")) }; indicationInst = indicationInst.deriveInstance(n); } else if (seqNumVal >= 11 && seqNumVal <= 14) { CIMProperty<?> n[] = { new CIMProperty<String>("SequenceContext", CIMDataType.STRING_T, newCtx1) }; indicationInst = indicationInst.deriveInstance(n); } else if (seqNumVal >= 15 && seqNumVal <= 18) { CIMProperty<?> n[] = { new CIMProperty<String>("SequenceContext", CIMDataType.STRING_T, null) }; indicationInst = indicationInst.deriveInstance(n); } else if (seqNumVal >= 19 && seqNumVal <= 24) { CIMProperty<?> n[] = { new CIMProperty<String>("SequenceContext", CIMDataType.STRING_T, newCtx2), new CIMProperty<Long>("SequenceNumber", CIMDataType.SINT64_T, new Long(seqNumVal - 19)) }; indicationInst = indicationInst.deriveInstance(n); } else if (seqNumVal >= 25 && seqNumVal <= 27) { CIMProperty<?> n[] = { new CIMProperty<String>("SequenceContext", CIMDataType.STRING_T, null) }; indicationInst = indicationInst.deriveInstance(n); } else if (seqNumVal == 28) { CIMProperty<?> n[] = { new CIMProperty<String>("SequenceContext", CIMDataType.STRING_T, newCtx3), new CIMProperty<Long>("SequenceNumber", CIMDataType.SINT64_T, new Long("1")) }; indicationInst = indicationInst.deriveInstance(n); } else if (seqNumVal == 29) { CIMProperty<?> n[] = { new CIMProperty<String>("SequenceContext", CIMDataType.STRING_T, newCtx3), new CIMProperty<Long>("SequenceNumber", CIMDataType.SINT64_T, new Long("0")) }; indicationInst = indicationInst.deriveInstance(n); } else if (seqNumVal == 30) { CIMProperty<?> n[] = { new CIMProperty<String>("SequenceContext", CIMDataType.STRING_T, newCtx3), new CIMProperty<Long>("SequenceNumber", CIMDataType.SINT64_T, new Long("3")) }; indicationInst = indicationInst.deriveInstance(n); } else if (seqNumVal == 31) { CIMProperty<?> n[] = { new CIMProperty<String>("SequenceContext", CIMDataType.STRING_T, newCtx3), new CIMProperty<Long>("SequenceNumber", CIMDataType.SINT64_T, new Long("2")) }; indicationInst = indicationInst.deriveInstance(n); } else if (seqNumVal == 32) { CIMProperty<?> n[] = { new CIMProperty<String>("SequenceContext", CIMDataType.STRING_T, newCtx3), new CIMProperty<Long>("SequenceNumber", CIMDataType.SINT64_T, new Long("5")) }; indicationInst = indicationInst.deriveInstance(n); } else if (seqNumVal == 33) { CIMProperty<?> n[] = { new CIMProperty<String>("SequenceContext", CIMDataType.STRING_T, newCtx3), new CIMProperty<Long>("SequenceNumber", CIMDataType.SINT64_T, new Long("4")) }; indicationInst = indicationInst.deriveInstance(n); } else if (seqNumVal == 34) { CIMProperty<?> n[] = { new CIMProperty<String>("SequenceContext", CIMDataType.STRING_T, newCtx3), new CIMProperty<Long>("SequenceNumber", CIMDataType.SINT64_T, new Long("6")) }; indicationInst = indicationInst.deriveInstance(n); } Java code snippet #2 tests starting with SC/SN off: CIMProperty<?> seqNumProp = indicationInst.getProperty("SequenceNumber"); Long seqNum = (Long) seqNumProp.getValue(); long seqNumVal = seqNum.longValue(); // 0-18 null context // 19-34 new context, #'s 0-16 if (seqNumVal >= 0 && seqNumVal <= 18) { CIMProperty<?> n[] = { new CIMProperty<String>("SequenceContext", CIMDataType.STRING_T, null) }; indicationInst = indicationInst.deriveInstance(n); } else if (seqNumVal >= 19 && seqNumVal <= 34) { CIMProperty<?> n[] = { new CIMProperty<Long>("SequenceNumber", CIMDataType.SINT64_T, new Long(seqNumVal - 19)) }; indicationInst = indicationInst.deriveInstance(n); } Index: ReliableIndicationHandler.java =================================================================== RCS file: /cvsroot/sblim/jsr48-client/src/org/sblim/cimclient/internal/wbem/indications/ReliableIndicationHandler.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -d -r1.3 -r1.4 --- ReliableIndicationHandler.java 10 Aug 2011 12:03:30 -0000 1.3 +++ ReliableIndicationHandler.java 22 Feb 2012 12:28:48 -0000 1.4 @@ -1,5 +1,5 @@ /** - * (C) Copyright IBM Corp. 2011 + * (C) Copyright IBM Corp. 2011, 2012 * * THIS FILE IS PROVIDED UNDER THE TERMS OF THE ECLIPSE PUBLIC LICENSE * ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS FILE @@ -16,6 +16,7 @@ *------------------------------------------------------------------------------- * 3288721 2011-05-20 blaschke-oss Need the function of indication reordering * 3376657 2011-07-24 blaschke-oss Get reliable indication properties once + * 3484022 2012-02-08 blaschke-oss Turn reliable indication mode on and off based on SC/SN */ package org.sblim.cimclient.internal.wbem.indications; @@ -187,6 +188,8 @@ private long iExpectedSequenceNumber = 0; + private boolean iIsFirstIndication = true; + /** * Constructs a <code>ReliableIndicationHandler</code> instance that uses * the specified event dispatcher and sequence identifier lifetime to handle @@ -331,7 +334,7 @@ } /** - * Adds a reliable indication to the . + * Adds a reliable indication to the sequence identifier cache. * * @param pSequenceContext * Sequence context of reliable indication to be cached. @@ -482,30 +485,52 @@ * Main worker routine for <code>ReliableIndicationHandler</code>. The * indication is either sent directly to the <code>CIMEventDispatcher</code> * or placed in the indication delivery queue to be dispatched later. All - * indications are placed in the sequence identifier cache. + * reliable indications are placed in the sequence identifier cache. * * @param pIndication - * Reliable indication. - * @param pSeqCtxProp - * SequenceContext property. - * @param pSeqNumProp - * SequenceNumber property. + * Indication. * @param pId - * Path portion of reliable indication URL. + * Indication destination URL. * @param pInetAddress - * Host portion of reliable indication URL. + * Indication server IP. */ - public synchronized void handleIndication(CIMInstance pIndication, CIMProperty<?> pSeqCtxProp, - CIMProperty<?> pSeqNumProp, String pId, InetAddress pInetAddress) { + public synchronized void handleIndication(CIMInstance pIndication, String pId, + InetAddress pInetAddress) { // Get current time long arrivalTime = System.currentTimeMillis(); + // Get reliable indication properties from indication + CIMProperty<?> seqCtxProp = pIndication.getProperty("SequenceContext"); + CIMProperty<?> seqNumProp = pIndication.getProperty("SequenceNumber"); + + // At this point indication is reliable or not reliable + + // Indication is not reliable, handle appropriately and deliver + if (seqCtxProp == null || seqNumProp == null || seqCtxProp.getValue() == null + || seqNumProp.getValue() == null) { + // Handle switch from reliable to not reliable + if (this.iLastSequenceContext != null) { + // Deliver all enqueued indications from previous context + flushQueue(); + + this.iLastSequenceContext = null; + this.iLastSequenceNumber = null; + } + + // Deliver indication + this.iDispatcher.dispatchEvent(new CIMEvent(pIndication, pId, pInetAddress)); + this.iIsFirstIndication = false; + return; + } + + // At this point indication is reliable + // Initial indication arrived, save knowledge about sequence identifier // and deliver - if (this.iLastSequenceNumber == null) { + if (this.iIsFirstIndication) { // Remember sequence context/number and arrival time - this.iLastSequenceContext = (String) pSeqCtxProp.getValue(); - this.iLastSequenceNumber = (Long) pSeqNumProp.getValue(); + this.iLastSequenceContext = (String) seqCtxProp.getValue(); + this.iLastSequenceNumber = (Long) seqNumProp.getValue(); this.iExpectedSequenceNumber = this.iLastSequenceNumber.longValue() + 1; // this.iLastArrivalTime = arrivalTime; @@ -515,11 +540,15 @@ // Deliver indication this.iDispatcher.dispatchEvent(new CIMEvent(pIndication, pId, pInetAddress)); + this.iIsFirstIndication = false; return; } - String seqCtx = (String) pSeqCtxProp.getValue(); - Long seqNum = (Long) pSeqNumProp.getValue(); + // At this point indication is reliable and previous indication was + // reliable + + String seqCtx = (String) seqCtxProp.getValue(); + Long seqNum = (Long) seqNumProp.getValue(); long seqNumVal = seqNum.longValue(); // Indication arrived after sequence identifier lifetime of previous @@ -550,7 +579,7 @@ // } // Indication arrived with different sequence context than expected - if (seqCtx.compareTo(this.iLastSequenceContext) != 0) { + if (this.iLastSequenceContext == null || seqCtx.compareTo(this.iLastSequenceContext) != 0) { // Cached sequence context indicates this indication arrived // out-of-order from previous context, log and ignore if (isInCache(seqCtx)) { |