View Javadoc

1   /*
2    * Copyright (c) 2005 The University of Reading
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met:
8    * 1. Redistributions of source code must retain the above copyright
9    *    notice, this list of conditions and the following disclaimer.
10   * 2. Redistributions in binary form must reproduce the above copyright
11   *    notice, this list of conditions and the following disclaimer in the
12   *    documentation and/or other materials provided with the distribution.
13   * 3. Neither the name of the University of Reading, nor the names of the
14   *    authors or contributors may be used to endorse or promote products
15   *    derived from this software without specific prior written permission.
16   * 
17   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20   * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27   */
28  
29  package uk.ac.rdg.resc.jstyx.gridservice.server;
30  
31  import java.io.InputStream;
32  import java.io.IOException;
33  import java.io.FileNotFoundException;
34  import java.io.File;
35  
36  import org.apache.log4j.Logger;
37  
38  import uk.ac.rdg.resc.jstyx.server.StyxFile;
39  import uk.ac.rdg.resc.jstyx.server.StyxFileClient;
40  import uk.ac.rdg.resc.jstyx.server.StyxServerProtocolHandler;
41  import uk.ac.rdg.resc.jstyx.messages.RerrorMessage;
42  import uk.ac.rdg.resc.jstyx.StyxException;
43  
44  /***
45   * When a client gets data from one of the StyxGridService's data streams (e.g.
46   * out and err), it does so via an instance of this class.
47   * In this class, the entire contents of the stream are written to a file on
48   * the local file system (this file is the cache).  Greater performance might be
49   * achieved by caching the data in memory (although the underlying OS will have
50   * its own caching strategy).  The performance of this class might be adequate
51   * if the speed of hard disk access is greater than the speed of network traffic,
52   * which is probably a reasonable assumption in most cases.
53   *
54   * @author Jon Blower
55   * $Revision: 286 $
56   * $Date: 2005-05-27 18:05:07 +0100 (Fri, 27 May 2005) $
57   * $Log$
58   * Revision 1.8  2005/05/27 17:05:07  jonblower
59   * Changes to incorporate GeneralCachingStreamReader
60   *
61   * Revision 1.7  2005/05/26 20:31:11  jonblower
62   * Changed behaviour such that clients can start trying to read from the stream before the service is started
63   *
64   * Revision 1.6  2005/05/16 11:00:53  jonblower
65   * Changed SGS config XML file structure: separated input and output streams and changed some tag names
66   *
67   * Revision 1.5  2005/03/24 14:47:47  jonblower
68   * Provided default read() and write() methods for StyxFile so it is no longer abstract
69   *
70   * Revision 1.4  2005/03/24 09:48:31  jonblower
71   * Changed 'count' from long to int throughout for reading and writing
72   *
73   * Revision 1.3  2005/03/21 17:59:49  jonblower
74   * Fixed bug with size of RandomAccessFile
75   *
76   * Revision 1.2  2005/03/18 13:56:00  jonblower
77   * Improved freeing of ByteBuffers, and bug fixes
78   *
79   * Revision 1.1  2005/03/16 22:16:44  jonblower
80   * Added Styx Grid Service classes to core module
81   *
82   * Revision 1.3  2005/03/16 17:59:35  jonblower
83   * Changed following changes to core JStyx library (replacement of java.nio.ByteBuffers with MINA's ByteBuffers)
84   *
85   * Revision 1.2  2005/03/11 09:07:15  jonblower
86   * Changes related to switch from Netty to MINA
87   *
88   * Revision 1.1  2005/02/16 19:22:31  jonblower
89   * Commit adding of SGS files to CVS
90   *
91   */
92  class CachingStreamReader extends StyxFile
93  {
94      private static final Logger log = Logger.getLogger(CachingStreamReader.class);
95      
96      private StyxGridServiceInstance sgsInstance; // The SGS instance that owns this
97      private GeneralCachingStreamReader reader;
98      
99      /***
100      * Creates a new CachingStreamReader.
101      * @param inst The StyxGridServiceInstance that owns this CachingStreamReader
102      * @param name The name for this file as it will appear on the Styx server
103      * @throws StyxException if the file could not be created.
104      */
105     public CachingStreamReader(StyxGridServiceInstance inst, String name) throws StyxException
106     {
107         super(name, 0444); // This is a read-only file
108         this.reader = new SFCachingStreamReader();
109     }
110     
111     /***
112      * Sets the input stream from which the CachingStreamReader gets data
113      * and immediately starts reading from this stream
114      * @throws IllegalStateException if this object is already reading from a stream
115      * @throws IOException if the cache file could not be created
116      * and should not happen)
117      */
118     public void startReading(InputStream is) throws IOException
119     {
120         this.reader.startReading(is);
121     }
122     
123     public void setCacheFile(File file) throws FileNotFoundException
124     {
125         this.reader.setCacheFile(file);
126     }
127     
128     /***
129      * Get data from the stream's cache.
130      * @param offset The offset <b>relative to the start of the whole stream</b> of
131      * the first byte of data requested.
132      * @param count The maximum amount of data to return
133      */
134     public void read(StyxFileClient client, long offset, int count, int tag)
135         throws StyxException
136     {
137         this.reader.read(new SFDataRequest(client, offset, count, tag));
138     }
139     
140     private class SFCachingStreamReader extends GeneralCachingStreamReader
141     {
142         
143         public void newData(DataRequest originalRequest, byte[] data,
144             int offset, int count)
145         {
146             SFDataRequest dr = (SFDataRequest)originalRequest;
147             StyxFileClient c = (StyxFileClient)dr.client;
148             replyRead(c, data, offset, count, dr.tag);
149         }
150         
151         public void error(DataRequest originalRequest, Exception e)
152         {
153             RerrorMessage rErrMsg = new RerrorMessage("error reading from stream: " +
154                 e.getMessage());
155             SFDataRequest dr = (SFDataRequest)originalRequest;
156             StyxFileClient c = (StyxFileClient)dr.client;
157             StyxServerProtocolHandler.reply(c.getSession(), rErrMsg, dr.tag);
158         }
159     }
160     
161     private static class SFDataRequest extends GeneralCachingStreamReader.DataRequest
162     {
163         private int tag;
164         public SFDataRequest(StyxFileClient client, long offset, int count, int tag)
165         {
166             super(client, offset, count);
167             this.tag = tag;
168         }
169     }
170     
171     /***
172      * Called when the file is removed from the server. This deletes the
173      * underlying cache file.
174      */
175     protected synchronized void delete()
176     {
177         this.reader.delete();
178     }
179     
180 }