You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@excalibur.apache.org by le...@apache.org on 2004/08/05 17:12:11 UTC

svn commit: rev 35740 - in excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client: . http

Author: leif
Date: Thu Aug  5 08:12:10 2004
New Revision: 35740

Modified:
   excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/InstrumentManagerConnection.java
   excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/InstrumentManagerData.java
   excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleFrame.java
   excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPData.java
   excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPElementData.java
   excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPInstrumentSampleElementData.java
   excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentManagerConnection.java
   excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentManagerData.java
   excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentSampleData.java
   excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentSampleSnapshotData.java
Log:
Significantly improve performance by taking advantange of batched updates and batched snapshot requests when connected to servers that support the features.  Still works great with only deployed servers.

Modified: excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/InstrumentManagerConnection.java
==============================================================================
--- excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/InstrumentManagerConnection.java	(original)
+++ excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/InstrumentManagerConnection.java	Thu Aug  5 08:12:10 2004
@@ -128,15 +128,7 @@
                     
                     m_frame.updateConnectionTab( this );
                     
-                    // Update each of the InstrumentSampleFrames belonging to this connection.
-                    if ( isConnected() )
-                    {
-                        InstrumentSampleFrame[] frames = getSampleFrameArray();
-                        for( int i = 0; i < frames.length; i++ )
-                        {
-                            frames[i].update();
-                        }
-                    }
+                    updateSampleFrames();
                 }
                 catch( Throwable t )
                 {
@@ -451,6 +443,22 @@
     }
     
     /**
+     * Updates all registered SampleFrames with the latest data from the
+     *  server.  The status of all Sample Frames is also handled by this
+     *  method, so it must handle disconnected connections and missing or
+     *  expired samples correctly.
+     */
+    public void updateSampleFrames()
+    {
+        InstrumentSampleFrame[] frames = getSampleFrameArray();
+        for ( int i = 0; i < frames.length; i++ )
+        {
+            InstrumentSampleFrame frame = frames[i];
+            frame.update();
+        }
+    }
+    
+    /**
      * Returns the TreeModel which contains the entire Instrument tree for
      *  this connection.
      *
@@ -591,7 +599,7 @@
      *
      * @return A thread save array representation of the InstrumentSampleFrames.
      */
-    private InstrumentSampleFrame[] getSampleFrameArray()
+    protected InstrumentSampleFrame[] getSampleFrameArray()
     {
         InstrumentSampleFrame[] array = m_sampleFrameArray;
         if ( array == null )
@@ -635,6 +643,7 @@
 
             // Now create the frame
             sampleFrame = new InstrumentSampleFrame( sampleFrameState, this, m_frame );
+            sampleFrame.enableLogging( getLogger() );
             addSampleFrame( sampleName, sampleFrame );
             sampleFrame.addToDesktop( m_frame.getDesktopPane() );
         }
@@ -656,6 +665,7 @@
             if ( sampleFrame == null )
             {
                 sampleFrame = new InstrumentSampleFrame( this, sampleName, m_frame );
+                sampleFrame.enableLogging( getLogger() );
                 addSampleFrame( sampleName, sampleFrame );
                 sampleFrame.addToDesktop( m_frame.getDesktopPane() );
             }
@@ -770,7 +780,7 @@
             m_maintainedSampleLeaseMap.put( sampleName, sampleLease );
             m_maintainedSampleLeaseArray = null;
 
-            // Reset te last lease renewal time so that the leases along with this
+            // Reset the last lease renewal time so that the leases along with this
             //  new one will be renewed right away.
             m_lastLeaseRenewalTime = 0;
 
@@ -870,18 +880,32 @@
         if ( now - m_lastLeaseRenewalTime > 30000 )
         {
             getLogger().debug( "Renew Leases:" );
+            
             MaintainedSampleLease[] leases = getMaintainedSampleLeaseArray();
+            String[] instrumentNames = new String[leases.length];
+            String[] descriptions = new String[leases.length];
+            long[] intervals = new long[leases.length];
+            int[] sampleCounts = new int[leases.length];
+            long[] leaseTimes = new long[leases.length];
+            int[] sampleTypes = new int[leases.length];
             for ( int i = 0; i < leases.length; i++ )
             {
                 MaintainedSampleLease lease = leases[i];
                 getLogger().debug( " lease: " + lease.getSampleName() );
                 
-                // Regardless of whether the sample already exists or not, it is created
-                //  or extended the same way.
-                getInstrumentManager().createInstrumentSample( lease.getInstrumentName(),
-                    lease.getDescription(), lease.getInterval(), lease.getSize(),
-                    lease.getLeaseDuration(), lease.getType() );
+                instrumentNames[i] = lease.getInstrumentName();
+                descriptions[i] = lease.getDescription();
+                intervals[i] = lease.getInterval();
+                sampleCounts[i] = lease.getSize();
+                leaseTimes[i] = lease.getLeaseDuration();
+                sampleTypes[i] = lease.getType();
             }
+            
+            // Regardless of whether the samples already exists or not, they
+            //  are created or extended the same way.  This way the client
+            //  will recreate a sample if it has expored.
+            getInstrumentManager().createInstrumentSamples(
+                instrumentNames, descriptions, intervals, sampleCounts, leaseTimes, sampleTypes );
 
             // Also, take this oportunity to update all of the leased samples in
             //  the model.

Modified: excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/InstrumentManagerData.java
==============================================================================
--- excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/InstrumentManagerData.java	(original)
+++ excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/InstrumentManagerData.java	Thu Aug  5 08:12:10 2004
@@ -50,7 +50,8 @@
      * @param description Description to assign to the new sample.
      * @param interval Sample interval of the new sample.
      * @param sampleCount Number of samples in the new sample.
-     * @param leaseTime Requested lease time.  The server may not grant the full lease.
+     * @param leaseTime Requested lease time.  The server may not grant the
+     *                  full lease.
      * @param sampleType The type of sample to be created.
      */
     void createInstrumentSample( String instrumentName,
@@ -59,4 +60,24 @@
                                  int sampleCount,
                                  long leaseTime,
                                  int sampleType );
+    
+    /**
+     * Requests that a set of samples be created or that their leases be
+     *  updated.  All array parameters must be of the same length.
+     *
+     * @param instrumentNames The full names of the instruments whose sample
+     *                        are to be created or updated.
+     * @param descriptions Descriptions to assign to the new samples.
+     * @param intervals Sample intervals of the new samples.
+     * @param sampleCounts Number of samples in each the new samples.
+     * @param leaseTimes Requested lease times.  The server may not grant the
+     *                   full leases.
+     * @param sampleTypes The types of samples to be created.
+     */
+    void createInstrumentSamples( String[] instrumentNames,
+                                  String[] descriptions,
+                                  long[] intervals,
+                                  int[] sampleCounts,
+                                  long[] leaseTimes,
+                                  int[] sampleTypes );
 }

Modified: excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleFrame.java
==============================================================================
--- excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleFrame.java	(original)
+++ excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/InstrumentSampleFrame.java	Thu Aug  5 08:12:10 2004
@@ -36,7 +36,7 @@
  * @version CVS $Revision: 1.4 $ $Date: 2004/02/28 11:47:23 $
  * @since 4.1
  */
-class InstrumentSampleFrame
+public class InstrumentSampleFrame
     extends AbstractInternalFrame
 {
     public static final String FRAME_TYPE = "sample-frame";
@@ -55,6 +55,15 @@
     private InstrumentManagerConnection m_connection;
     private String m_instrumentSampleName;
     private String m_fullName;
+    
+    /** The last time that a snapshot was received.  This is the time in the
+     *   snapshot and is always in Server time.  Not the time on this system. */
+    private long m_lastSnapshotTime;
+    
+    /** A buffered set of sample values.  May be null. */
+    private int[] m_samples;
+    
+    /** The LineChart currently visible in the Frame.  May be null. */
     private LineChart m_lineChart;
 
     /*---------------------------------------------------------------
@@ -142,12 +151,23 @@
      *
      * @return The name of the sample being displayed.
      */
-    String getInstrumentSampleName()
+    public String getInstrumentSampleName()
     {
         return m_instrumentSampleName;
     }
     
     /**
+     * The last time that a snapshot was received.  This is the time in the
+     *  snapshot and is always in Server time.  Not the time on this system.
+     *
+     * @return The last snapshot time.
+     */
+    public long getLastSnapshotTime()
+    {
+        return m_lastSnapshotTime;
+    }
+    
+    /**
      * Update the icon that is displayed for the frame.
      */
     private void updateIcon()
@@ -269,7 +289,7 @@
     private void initChart( InstrumentSampleSnapshotData snapshot )
     {
         // Decide on a line interval based on the interval of the sample.
-        long interval = snapshot.getInterval();
+        long interval = Math.max( 1, snapshot.getInterval() );
         int hInterval;
         String format;
         String detailFormat;
@@ -341,16 +361,91 @@
             m_state = STATE_SNAPSHOT;
             
             updateTitle();
-            updateIcon();
+        }
+
+        int size = snapshot.getSize();
+        
+        // The new samples that came in the snapshot may or may not be a complete
+        //  set.  They usually will be partial.
+        int[] newSamples = snapshot.getSamples();
+        if ( newSamples.length == size )
+        {
+            // We got a full sample set.  Just replace the internal sample buffer.
+            m_samples = newSamples;
+        }
+        else if ( newSamples.length > size )
+        {
+            // Should never happen.  But protect against it to avoid errors.
+            //  Only use the last {size} samples.
+            m_samples = new int[size];
+            System.arraycopy( newSamples, newSamples.length - size, m_samples, 0, size );
         }
         else
         {
-            // Update the contents of the chart.
-            m_lineChart.setValues( snapshot.getSamples(), snapshot.getTime() );
+            // We received a partial sample set, so we need to adjust the existing
+            //  data then copy the new data over the array.
             
-            // Icon can change.
-            updateIcon();
+            // Make sure that the local buffer is the correct size.
+            if ( m_samples == null )
+            {
+                m_samples = new int[size];
+            }
+            else if ( m_samples.length != size )
+            {
+                // The sample size changed on the server.
+                int[] tmpSamples = new int[size];
+                if ( m_samples.length > size )
+                {
+                    // Got smaller.  The beginning of the existing array gets trimmed.
+                    System.arraycopy( m_samples, m_samples.length - size, tmpSamples, 0, size );
+                }
+                else
+                {
+                    // Got larger.  The beginning of the new array will be all 0s.
+                    System.arraycopy(
+                        m_samples, 0, tmpSamples, size - m_samples.length, m_samples.length );
+                }
+                m_samples = tmpSamples;
+            }
+            
+            // Calculate the age of the buffered samples.
+            long age = snapshot.getTime() - m_lastSnapshotTime;
+            int intervalAge = (int)( age / snapshot.getInterval() );
+            if ( intervalAge > m_samples.length )
+            {
+                intervalAge = m_samples.length;
+            }
+            
+            // Move existing values down in the buffer as necessary.
+            if ( ( intervalAge > 0 ) && ( intervalAge < m_samples.length ) )
+            {
+                // We are moving down in the array so we can do this withtout a temp array.
+                System.arraycopy( m_samples, intervalAge, m_samples, 0, size - intervalAge );
+            }
+            
+            // This will only happen if there is a timing problem, but fill in any
+            //  space between the old and new values with 0s.
+            if ( intervalAge > newSamples.length )
+            {
+                for ( int i = size - intervalAge; i < size - newSamples.length; i++ )
+                {
+                    m_samples[i] = 0;
+                }
+            }
+            
+            // Copy the new samples over the end of the sample buffer.
+            System.arraycopy(
+                newSamples, 0, m_samples, size - newSamples.length, newSamples.length );
         }
+        
+        // Update the contents of the chart.
+        m_lineChart.setValues( m_samples, snapshot.getTime() );
+            
+        // Store the time of this snapshot.
+        m_lastSnapshotTime = snapshot.getTime();
+        
+        // Icon can change.
+        updateIcon();
     }
 
     /**
@@ -420,11 +515,12 @@
         }
     }
     
-    
     /**
-     * Called once per second to prompt the sample frame to refresh itself.
+     * Called to update the frame when a snapshot is already available.
+     *
+     * @param snapshot Snapshot to update the frame with.  Null if unavailable.
      */
-    void update()
+    public void updateSnapshot( InstrumentSampleSnapshotData snapshot )
     {
         if ( m_connection.isDeleted() )
         {
@@ -438,9 +534,6 @@
                 m_lineChart.setAntialias( getFrame().isAntialias() );
             }
             
-            // Request a snapshot from the connection
-            InstrumentSampleSnapshotData snapshot =
-                m_connection.getSampleSnapshot( m_instrumentSampleName );
             if ( snapshot == null )
             {
                 // A sample was not available.  Why.
@@ -465,6 +558,20 @@
                 setStateSnapshot( snapshot );
             }
         }
+    }
+    
+    /**
+     * Called to update the frame and request a new snapshot from the server.
+     */
+    void update()
+    {
+        InstrumentSampleSnapshotData snapshot = null;
+        if ( !m_connection.isDeleted() )
+        {
+            snapshot = m_connection.getSampleSnapshot( m_instrumentSampleName );
+        }
+        
+        updateSnapshot( snapshot );
     }
 }
 

Modified: excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPData.java
==============================================================================
--- excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPData.java	(original)
+++ excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPData.java	Thu Aug  5 08:12:10 2004
@@ -17,9 +17,6 @@
 
 package org.apache.excalibur.instrument.client.http;
 
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.configuration.ConfigurationException;
 import org.apache.avalon.framework.logger.AbstractLogEnabled;
@@ -52,6 +49,7 @@
     /**
      * Creates a new AbstractHTTPData.
      *
+     * @param connection The connection used to communicate with the server.
      * @param description An initial description.
      */
     protected AbstractHTTPData( HTTPInstrumentManagerConnection connection,
@@ -108,21 +106,19 @@
     protected void update( Configuration configuration )
         throws ConfigurationException
     {
-        m_description = configuration.getAttribute( "description" );
-        m_stateVersion = configuration.getAttributeAsInteger( "state-version" );
+        m_description = configuration.getAttribute( "description", "" );
+        m_stateVersion = configuration.getAttributeAsInteger( "state-version", 0 );
     }
     
+    /**
+     * URL encode the specified string.
+     *
+     * @param val String to be URL encoded.
+     *
+     * @return The URL encoded string.
+     */
     protected String urlEncode( String val )
     {
-        try
-        {
-            return URLEncoder.encode( val, "UTF8" );
-        }
-        catch ( UnsupportedEncodingException e )
-        {
-            // Should never happen.
-            getLogger().error( "Bad encoding.", e );
-            return val;
-        }
+        return m_connection.urlEncode( val );
     }
 }

Modified: excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPElementData.java
==============================================================================
--- excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPElementData.java	(original)
+++ excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPElementData.java	Thu Aug  5 08:12:10 2004
@@ -71,7 +71,9 @@
     /**
      * Creates a new AbstractHTTPElementData.
      *
-     * @param description An initial description.
+     * @param connection The connection used to communicate with the server.
+     * @param parent The parent data element.
+     * @param name The name of the data element.
      */
     protected AbstractHTTPElementData( HTTPInstrumentManagerConnection connection,
                                        AbstractHTTPData parent,
@@ -131,6 +133,6 @@
     {
         super.update( configuration );
         
-        m_configured = configuration.getAttributeAsBoolean( "configured" );
+        m_configured = configuration.getAttributeAsBoolean( "configured", false );
     }
 }

Modified: excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPInstrumentSampleElementData.java
==============================================================================
--- excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPInstrumentSampleElementData.java	(original)
+++ excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/AbstractHTTPInstrumentSampleElementData.java	Thu Aug  5 08:12:10 2004
@@ -49,6 +49,10 @@
      *-------------------------------------------------------------*/
     /**
      * Creates a new AbstractHTTPInstrumentSampleElementData.
+     *
+     * @param connection The connection used to communicate with the server.
+     * @param parent The parent data element.
+     * @param name The name of the data element.
      */
     AbstractHTTPInstrumentSampleElementData( HTTPInstrumentManagerConnection connection,
                                              AbstractHTTPData parent,

Modified: excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentManagerConnection.java
==============================================================================
--- excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentManagerConnection.java	(original)
+++ excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentManagerConnection.java	Thu Aug  5 08:12:10 2004
@@ -19,9 +19,11 @@
 
 import java.io.InputStream;
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
 import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
 import java.net.URL;
+import java.net.URLEncoder;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -36,6 +38,7 @@
 import org.apache.excalibur.instrument.client.InstrumentManagerConnection;
 import org.apache.excalibur.instrument.client.InstrumentManagerConnectionListener;
 import org.apache.excalibur.instrument.client.InstrumentManagerData;
+import org.apache.excalibur.instrument.client.InstrumentSampleFrame;
 
 /**
  * A Connection to the remote InstrumentManager which connects using
@@ -179,26 +182,118 @@
     }
     
     /**
-     * Gets a thread-safe snapshot of the leased sample list.
+     * URL encode the specified string.
      *
-     * @return A thread-safe snapshot of the leased sample list.
+     * @param val String to be URL encoded.
+     *
+     * @return The URL encoded string.
+     */
+    String urlEncode( String val )
+    {
+        try
+        {
+            return URLEncoder.encode( val, "UTF8" );
+        }
+        catch ( UnsupportedEncodingException e )
+        {
+            // Should never happen.
+            getLogger().error( "Bad encoding.", e );
+            return val;
+        }
+    }
+    
+    /**
+     * Updates all registered SampleFrames with the latest data from the
+     *  server.  The status of all Sample Frames is also handled by this
+     *  method, so it must handle disconnected connections and missing or
+     *  expired samples correctly.
+     *
+     * This method overrides the default to implement a batch update to
+     *  get all snapshots from the server in a single request.
      */
-    /*
-    public InstrumentSampleData[] getLeasedSamples()
+    public void updateSampleFrames()
     {
-        InstrumentSampleData[] samples = m_leasedSampleAry;
-        if ( samples == null )
+        InstrumentSampleFrame[] frames = getSampleFrameArray();
+        if ( frames.length == 0 )
         {
-            synchronized ( m_leasedSamples )
+            // Nothing to do.
+            return;
+        }
+        
+        // Build up a set of arrays so that all of the snapshots can be requested at once.
+        String[] names = new String[frames.length];
+        long[] lastTimes = new long[frames.length];
+        HTTPInstrumentSampleSnapshotData[] snapshots =
+            new HTTPInstrumentSampleSnapshotData[frames.length];
+        for ( int i = 0; i < frames.length; i++ )
+        {
+            InstrumentSampleFrame frame = frames[i];
+            names[i] = frame.getInstrumentSampleName();
+            lastTimes[i] = frame.getLastSnapshotTime();
+        }
+        
+        // Request the snapshots.  Don't bother if we know we are not connected.
+        if ( isConnected() )
+        {
+            StringBuffer sb = new StringBuffer();
+            sb.append( "snapshots.xml?packed=true&compact=true" );
+            for ( int i = 0; i < frames.length; i++ )
+            {
+                sb.append( "&name=" );
+                sb.append( this.urlEncode( names[i] ) );
+                sb.append( "&base-time=" );
+                sb.append( lastTimes[i] );
+            }
+            Configuration configuration = getState( sb.toString() );
+            if ( configuration != null )
             {
-                m_leasedSampleAry = new InstrumentSampleData[m_leasedSamples.size()];
-                m_leasedSamples.toArray( m_leasedSampleAry );
-                samples = m_leasedSampleAry;
+                Configuration[] snapshotConfs = configuration.getChildren( "sample" );
+                for ( int i = 0; i < snapshotConfs.length; i++ )
+                {
+                    Configuration snapshotConf = snapshotConfs[i];
+                    String name = snapshotConf.getAttribute( "name", null );
+                    if ( name != null )
+                    {
+                        boolean expired = snapshotConf.getAttributeAsBoolean( "expired", false );
+                        if ( !expired )
+                        {
+                            // Look for the specified sample frame.  Should always exist.
+                            for ( int j = 0; j < frames.length; j++ )
+                            {
+                                if ( name.equals( names[j] ) )
+                                {
+                                    snapshots[j] =
+                                        new HTTPInstrumentSampleSnapshotData( this, name );
+                                    snapshots[j].enableLogging( getLogger() );
+                                    try
+                                    {
+                                        snapshots[j].update( snapshotConf );
+                                    }
+                                    catch ( ConfigurationException e )
+                                    {
+                                        // Should not happen.
+                                        getLogger().info( "Snapshot update failed.", e );
+                                        getLogger().info( " URL: " + sb.toString() );
+                                        getLogger().info( " i:" + i + " j:" + j );
+                                        snapshots[j] = null;
+                                    }
+                                    break;
+                                }
+                            }
+                        }
+                    }
+                }
             }
         }
-        return samples;
+        
+        // Now we should have all available snapshots.  Loop back over the frames
+        //  and update them as is appropriate.
+        for ( int i = 0; i < frames.length; i++ )
+        {
+            InstrumentSampleFrame frame = frames[i];
+            frame.updateSnapshot( snapshots[i] );
+        }
     }
-    */
     
     /*---------------------------------------------------------------
      * Methods
@@ -333,16 +428,4 @@
             return null;
         }
     }
-    
-    /*
-    private void updateLeasedSamples()
-    {
-        InstrumentSampleData[] samples = getLeasedSamples();
-        for ( int i = 0; i < samples.length; i++ )
-        {
-            InstrumentSampleData sample = samples[i];
-            sample.updateLease();
-        }
-    }
-    */
 }

Modified: excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentManagerData.java
==============================================================================
--- excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentManagerData.java	(original)
+++ excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentManagerData.java	Thu Aug  5 08:12:10 2004
@@ -35,6 +35,12 @@
     /* Name of the remote object. */
     private String m_name;
     
+    /* Flag which keeps track of whether the manager supports batched lease updates. */
+    private boolean m_batchedUpdates;
+    
+    /* Flag which keeps track of whether the manager is read only or not. */
+    private boolean m_readOnly;
+    
     private List m_instrumentables = new ArrayList();
     private HTTPInstrumentableData[] m_instrumentableAry;
     private Map m_instrumentableMap = new HashMap();
@@ -71,6 +77,12 @@
         
         m_name = configuration.getAttribute( "name" );
         
+        // Support for batched lease creates and renewals added in version 1.2.
+        m_batchedUpdates = configuration.getAttributeAsBoolean( "batched-updates", false );
+        
+        // read-only attribute added in version 1.2.
+        m_readOnly = configuration.getAttributeAsBoolean( "read-only", false );
+        
         if ( getLogger().isDebugEnabled() )
         {
             getLogger().debug(
@@ -158,6 +170,32 @@
     }
     
     /**
+     * Returns true if the InstrumentManager on the server is operating in
+     *  read-only mode.
+     *
+     * @return True if read-only.
+     *
+     * @since 1.2
+     */
+    public boolean isReadOnly()
+    {
+        return m_readOnly;
+    }
+    
+    /**
+     * Returns true if batched lease creates and renewals are implemented on
+     *  the server.
+     *
+     * @return True if read-only.
+     *
+     * @since 1.2
+     */
+    private boolean isSupportsBatchedUpdates()
+    {
+        return m_batchedUpdates;
+    }
+    
+    /**
      * Gets a thread-safe snapshot of the instrumentable list.
      *
      * @return A thread-safe snapshot of the instrumentable list.
@@ -216,7 +254,8 @@
      * @param description Description to assign to the new sample.
      * @param interval Sample interval of the new sample.
      * @param sampleCount Number of samples in the new sample.
-     * @param leaseTime Requested lease time.  The server may not grant the full lease.
+     * @param leaseTime Requested lease time.  The server may not grant the
+     *                  full lease.
      * @param sampleType The type of sample to be created.
      */
     public void createInstrumentSample( String instrumentName,
@@ -232,6 +271,76 @@
         connection.getState( "create-sample.xml?name=" + urlEncode( instrumentName )
             + "&description=" + urlEncode( description ) + "&interval=" + interval
             + "&size=" + sampleCount + "&lease=" + leaseTime + "&type=" + sampleType );
+    }
+    
+    /**
+     * Requests that a set of samples be created or that their leases be
+     *  updated.  All array parameters must be of the same length.
+     *
+     * @param instrumentNames The full names of the instruments whose sample
+     *                        are to be created or updated.
+     * @param descriptions Descriptions to assign to the new samples.
+     * @param intervals Sample intervals of the new samples.
+     * @param sampleCounts Number of samples in each the new samples.
+     * @param leaseTimes Requested lease times.  The server may not grant the
+     *                   full leases.
+     * @param sampleTypes The types of samples to be created.
+     */
+    public void createInstrumentSamples( String[] instrumentNames,
+                                         String[] descriptions,
+                                         long[] intervals,
+                                         int[] sampleCounts,
+                                         long[] leaseTimes,
+                                         int[] sampleTypes )
+    {
+        HTTPInstrumentManagerConnection connection =
+            (HTTPInstrumentManagerConnection)getConnection();
+        
+        // Validate the arguments to avoid errors from misuse.
+        if ( ( instrumentNames.length != descriptions.length )
+            || ( instrumentNames.length != intervals.length )
+            || ( instrumentNames.length != sampleCounts.length )
+            || ( instrumentNames.length != leaseTimes.length )
+            || ( instrumentNames.length != sampleTypes.length ) )
+        {
+            throw new IllegalArgumentException( "Array lengths of all parameters must be equal." );
+        }
+        
+        // If batched updates are not supported, then do them individually
+        if ( isSupportsBatchedUpdates() )
+        {
+            StringBuffer sb = new StringBuffer();
+            sb.append( "create-samples.xml?" );
+            for ( int i = 0; i < instrumentNames.length; i++ )
+            {
+                if ( i > 0 )
+                {
+                    sb.append( "&" );
+                }
+                sb.append( "name=" );
+                sb.append( urlEncode( instrumentNames[i] ) );
+                sb.append( "&description=" );
+                sb.append( urlEncode( descriptions[i] ) );
+                sb.append( "&interval=" );
+                sb.append( intervals[i] );
+                sb.append( "&size=" );
+                sb.append( sampleCounts[i] );
+                sb.append( "&lease=" );
+                sb.append( leaseTimes[i] );
+                sb.append( "&type=" );
+                sb.append( sampleTypes[i] );
+            }
+            
+            connection.getState( sb.toString() );
+        }
+        else
+        {
+            for ( int i = 0; i < instrumentNames.length; i++ )
+            {
+                createInstrumentSample( instrumentNames[i], descriptions[i], intervals[i],
+                    sampleCounts[i], leaseTimes[i], sampleTypes[i] );
+            }
+        }
     }
     
     /*---------------------------------------------------------------

Modified: excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentSampleData.java
==============================================================================
--- excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentSampleData.java	(original)
+++ excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentSampleData.java	Thu Aug  5 08:12:10 2004
@@ -111,8 +111,11 @@
      */
     public InstrumentSampleSnapshotData getSnapshot()
     {
+        HTTPInstrumentManagerConnection connection =
+            (HTTPInstrumentManagerConnection)getConnection();
+        
         HTTPInstrumentSampleSnapshotData snapshot =
-            new HTTPInstrumentSampleSnapshotData( this, getName() );
+            new HTTPInstrumentSampleSnapshotData( connection, getName() );
         snapshot.enableLogging( getLogger() );
         if ( snapshot.update() )
         {

Modified: excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentSampleSnapshotData.java
==============================================================================
--- excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentSampleSnapshotData.java	(original)
+++ excalibur/trunk/containerkit/instrument/client/src/java/org/apache/excalibur/instrument/client/http/HTTPInstrumentSampleSnapshotData.java	Thu Aug  5 08:12:10 2004
@@ -19,6 +19,7 @@
 
 import java.util.StringTokenizer;
 
+import org.apache.excalibur.instrument.client.Data;
 import org.apache.excalibur.instrument.client.InstrumentSampleSnapshotData;
 
 import org.apache.avalon.framework.configuration.Configuration;
@@ -36,17 +37,30 @@
      *-------------------------------------------------------------*/
     /**
      * Creates a new HTTPInstrumentSampleSnapshotData.
+     *
+     * @param connection The connection used to communicate with the server.
+     * @param name The name of the data element.
      */
-    HTTPInstrumentSampleSnapshotData( HTTPInstrumentSampleData parent,
+    HTTPInstrumentSampleSnapshotData( HTTPInstrumentManagerConnection connection,
                                       String name )
     {
-        super( (HTTPInstrumentManagerConnection)parent.getConnection(), parent, name );
+        super( connection, null, name );
     }
     
     /*---------------------------------------------------------------
      * AbstractHTTPElementData Methods
      *-------------------------------------------------------------*/
     /**
+     * Returns the parent data object.
+     *
+     * @return The parent data object.
+     */
+    public Data getParent()
+    {
+        throw new IllegalStateException( "getParent() can not be called for snapshots." );
+    }
+    
+    /**
      * Update the contents of the object using values from the Configuration object.
      *
      * @param configuration Configuration object to load from.
@@ -64,7 +78,10 @@
                 + "to version " + getStateVersion() );
         }
         
-        m_samples = new int[getSize()];
+        // Get the actual number of samples returned.
+        int count = configuration.getAttributeAsInteger( "count", getSize() );
+        
+        m_samples = new int[count];
         
         String rawSamples = configuration.getChild( "values" ).getValue( "" );
         StringTokenizer st = new StringTokenizer( rawSamples, ", " );

---------------------------------------------------------------------
To unsubscribe, e-mail: scm-unsubscribe@excalibur.apache.org
For additional commands, e-mail: scm-help@excalibur.apache.org