From: Dave B. <bla...@us...> - 2011-08-12 20:43:17
|
Update of /cvsroot/sblim/jsr48-client/src/org/sblim/cimclient/internal/wbem/indications In directory vz-cvs-3.sog:/tmp/cvs-serv11722/src/org/sblim/cimclient/internal/wbem/indications Modified Files: Tag: Experimental CIMIndicationHandler.java Log Message: 3390724 - Problem with Reliable Indication support in the Listener Index: CIMIndicationHandler.java =================================================================== RCS file: /cvsroot/sblim/jsr48-client/src/org/sblim/cimclient/internal/wbem/indications/CIMIndicationHandler.java,v retrieving revision 1.10.2.16 retrieving revision 1.10.2.17 diff -u -d -r1.10.2.16 -r1.10.2.17 --- CIMIndicationHandler.java 24 Jul 2011 16:47:15 -0000 1.10.2.16 +++ CIMIndicationHandler.java 12 Aug 2011 20:43:15 -0000 1.10.2.17 @@ -35,6 +35,7 @@ * 3304953 2011-05-20 blaschke-oss Indication URL mapped to lower case * 3374206 2011-07-22 blaschke-oss NullPointerException caused by Indication * 3376657 2011-07-24 blaschke-oss Get reliable indication properties once + * 3390724 2011-08-12 blaschke-oss Problem with Reliable Indication support in the Listener */ package org.sblim.cimclient.internal.wbem.indications; @@ -44,6 +45,7 @@ import java.io.InputStreamReader; import java.net.InetAddress; import java.util.Iterator; +import java.util.LinkedList; import java.util.Vector; import java.util.Map.Entry; import java.util.logging.Level; @@ -80,6 +82,67 @@ */ public class CIMIndicationHandler extends HttpContentHandler { + /** + * <code>IndicationServer</code> represents an entry in the linked list of + * servers handled by this <code>CIMIndicationHandler</code> instance. Each + * entry in the list will have a unique serverIP/destinationURL pair along + * with its own <code>ReliableIndicationHandler</code>. This is done to + * handle multiple contexts from the same server. + * + * NOTE: Multiple contexts from the same server will not be handled + * correctly if the user creates multiple + * <code>CIM_ListenerDestination</code> instances with the same + * <code>Destination</code> property. While this is poor programming + * practice (two different instances with same pertinent information), the + * real issue is that there is no way for the Client to differentiate + * between a context switch and two different contexts if the + * serverIP/destinationURL are the same. This issue it is not covered by + * DSP1054 1.2. + */ + private class IndicationServer { + + private boolean iRIInitialized = false; + + private boolean iRISupported = false; + + private InetAddress iInetAddress; + + private String iDestinationUrl; + + private ReliableIndicationHandler iRIHandler; + + public IndicationServer(InetAddress pInetAddress, String pDestinationUrl) { + this.iInetAddress = pInetAddress; + this.iDestinationUrl = pDestinationUrl; + } + + public void initialize(boolean pRISupported, ReliableIndicationHandler pRIHandler) { + this.iRIInitialized = true; + this.iRISupported = pRISupported; + this.iRIHandler = pRIHandler; + } + + public boolean isInitialized() { + return this.iRIInitialized; + } + + public boolean isRISupported() { + return this.iRISupported; + } + + public InetAddress getInetAddress() { + return this.iInetAddress; + } + + public String getDestinationUrl() { + return this.iDestinationUrl; + } + + public ReliableIndicationHandler getRIHandler() { + return this.iRIHandler; + } + } + private CIMEventDispatcher iDispatcher = null; private int iMessageId = 0; @@ -90,11 +153,7 @@ private boolean iReliableIndicationsDisabled = true; - private boolean iRIInitialized = false; - - private boolean iRISupported = false; - - private ReliableIndicationHandler iRIHandler; + private LinkedList<IndicationServer> iServerList = new LinkedList<IndicationServer>(); /** * Ctor. @@ -223,36 +282,67 @@ } /** + * Returns the corresponding indication server if the server is already + * present in the linked list, otherwise appends the server to the linked + * list and returns the new entry. + * + * @param pInetAddress + * Address of indication server. + * @param pDestinationUrl + * Destination URL of indication. + * @return <code>IndicationServer</code> with given address. + */ + private IndicationServer getIndicationServer(InetAddress pInetAddress, String pDestinationUrl) { + IndicationServer server; + Iterator<IndicationServer> iterator = this.iServerList.iterator(); + while (iterator.hasNext()) { + server = iterator.next(); + if (server.getInetAddress().equals(pInetAddress) + && server.getDestinationUrl().equalsIgnoreCase(pDestinationUrl)) return server; + } + server = new IndicationServer(pInetAddress, pDestinationUrl); + this.iServerList.add(server); + this.iLogger.trace(Level.FINE, "Creating reliable indication handler for server IP " + + server.getInetAddress().toString() + ", destination URL " + + server.getDestinationUrl()); + + return server; + } + + /** * deliverIndication handles reliable indications and returns a boolean * indicating whether the indication should be delivered or not * * @param pIndication * Indication. * @param pId - * Path portion of indication URL. + * Indication destination URL. * @param pInetAddress - * Host portion of indication URL. + * Indication server IP. * @return <code>true</code> if indication should be delivered, * <code>false</code> if <code>ReliableIndicationHandler</code> will * deliver indication */ - private boolean deliverIndication(CIMInstance pIndication, String pId, InetAddress pInetAddress) { + private synchronized boolean deliverIndication(CIMInstance pIndication, String pId, + InetAddress pInetAddress) { + // Each serverIP/destinationURL pair needs its own + // ReliableIndicationHandler in order to handle multiple contexts + IndicationServer server = getIndicationServer(pInetAddress, pId); + // Nothing to do if reliable indications initialized but not supported, // go ahead and deliver - if (this.iRIInitialized && !this.iRISupported) return true; + 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 - if (!this.iRIInitialized) { - this.iRIInitialized = true; - + if (!server.isInitialized()) { // Initial indication does not contain reliable indication // properties, disable support and go ahead and deliver if (seqCtxProp == null || seqNumProp == null) { - this.iRISupported = false; + server.initialize(false, null); this.iLogger .trace( @@ -263,10 +353,10 @@ } // Initial indication does not contain reliable indication - // properties with non-null values, disable support and go ahead and - // deliver + // properties with non-null values, disable support and go ahead + // and deliver if (seqCtxProp.getValue() == null || seqNumProp.getValue() == null) { - this.iRISupported = false; + server.initialize(false, null); this.iLogger .trace( @@ -276,9 +366,6 @@ return true; } - // Reliable indication found, enable support - this.iRISupported = true; - // Validate DeliveryRetryAttempts property long attempts = this.iSessionProperties.getListenerDeliveryRetryAttempts(); if (attempts <= 0 || attempts > 1000) { @@ -302,18 +389,17 @@ // Create new ReliableIndicationHandler for this // CIMIndicationHandler - this.iRIHandler = new ReliableIndicationHandler(this.iDispatcher, attempts * interval - * 10 * 1000); + 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 - this.iRIHandler - .handleIndication(pIndication, seqCtxProp, seqNumProp, pId, pInetAddress); + server.getRIHandler().handleIndication(pIndication, seqCtxProp, seqNumProp, pId, + pInetAddress); return false; - } // Reliable indication support is enabled but indication does not @@ -337,7 +423,8 @@ } // Let ReliableIndicationHandler deliver it - this.iRIHandler.handleIndication(pIndication, seqCtxProp, seqNumProp, pId, pInetAddress); + server.getRIHandler().handleIndication(pIndication, seqCtxProp, seqNumProp, pId, + pInetAddress); return false; } |