001    /*
002    Copyright (c) 1996-2012, Damon Hart-Davis
003    All rights reserved.
004    
005    Redistribution and use in source and binary forms, with or without
006    modification, are permitted provided that the following conditions are
007    met:
008    
009      * Redistributions of source code must retain the above copyright
010        notice, this list of conditions and the following disclaimer.
011    
012      * Redistributions in binary form must reproduce the above copyright
013        notice, this list of conditions and the following disclaimer in the
014        documentation and/or other materials provided with the
015        distribution.
016    
017    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
018    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
019    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
020    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
021    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
022    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
023    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
024    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
025    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
026    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
027    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028    */
029    package org.hd.d.pg2k.svrCore.datasource;
030    
031    import java.io.IOException;
032    import java.nio.ByteBuffer;
033    
034    import org.hd.d.pg2k.svrCore.AllExhibitImmutableData;
035    import org.hd.d.pg2k.svrCore.AllExhibitProperties;
036    import org.hd.d.pg2k.svrCore.ExhibitStaticAttr;
037    import org.hd.d.pg2k.svrCore.ExhibitThumbnails;
038    import org.hd.d.pg2k.svrCore.Name;
039    import org.hd.d.pg2k.svrCore.Name.ExhibitFull;
040    import org.hd.d.pg2k.svrCore.Stratum;
041    import org.hd.d.pg2k.svrCore.props.GenProps;
042    import org.hd.d.pg2k.svrCore.vars.SimpleVariablePipelineIF;
043    
044    /**Simple interface implemented by several stages in the Web exhibit-handling pipeline.
045     * In particular, the on-disc exhibit-data cache and backend datasource adaptors
046     * implement this.
047     * <p>
048     * The pipeline stages that implement this may well implement other interfaces
049     * in parallel to provide richer and more efficient cacheing, etc.
050     * <p>
051     * As this is in effect handling a stream of I/O on its way to a browser,
052     * IOException seems the natural way to signal errors.
053     * <p>
054     * We may make implementers of this interface Serializable so as to allow
055     * them to be persisted
056     * in servlet context for robustness and distribution, but making
057     * copies through this mechanism will upset the ability to fully track
058     * usage and efficiently share caches, etc.
059     * <p>
060     * Note that this extends the variable-handling pipeline interface,
061     * ie data pipelines also handle system variables.
062     * <p>
063     * Note that transient errors (eg caused by temporary resource shortage/congestion)
064     * and indicated by InterruptedIOException being thrown,
065     * and may indicate that a retry soon may be successful.
066     */
067    public interface SimpleExhibitPipelineIF extends SimpleVariablePipelineIF
068        {
069        /**Maximum exhibit user-driven I/O data transfer request in bytes; strictly positive.
070         * This is the limit for filesystem access, tunnel connections, etc,
071         * to avoid causing bottlenecks and out-of-memory conditions.
072         * <p>
073         * Some operations that request transfers larger than this
074         * (and where the caller has control of the size of the request),
075         * eg reading raw data from an exhibit,
076         * may be rejected with an IOException.
077         * <p>
078         * Note that this does not limit the return of large data items
079         * (eg AllExhibitProperties) whose size is not controlled by the caller.
080         * <p>
081         * This helps prevent denial-of-service by a faulty/malicious client.
082         * <p>
083         * A power of two for efficiency in various places.
084         * <p>
085         * A size of many times BULK_DATA_TRANSFER_SIZE to a few mBytes
086         * is probably reasonable.
087         */
088        public static final int MAX_USER_READ_SIZE = 1 * 1024 * 1024;
089    
090        /**Get the static attributes for a given exhibit.
091         * Returns null if the named exhibit does not exist.
092         *
093         * @throws java.io.IOException if the operation cannot be completed due to I/O
094         *     restrictions or failure
095         */
096        public ExhibitStaticAttr getStaticAttr(ExhibitFull name)
097            throws IOException;
098    
099        /**Read a chunk of the raw exhibit binary into the given buffer.
100         * The call may return less than the the buffer capacity,
101         * though will block until it has read at least one byte unless at EOF or for a zero-byte request;
102         * this will be clear from the state of the buffer.
103         *
104         * @param buf  the buffer into which to read the data;
105         *     must be non-null, in put()able state,
106         *     and with remaining capacity of at least the requested number of bytes
107         * @param exhibitName  the full name of the exhibit to read from;
108         *     never null and must be syntactically valid
109         * @param position  position/index of first byte in exhibitFile to read;
110         *     non-negative
111         * @param dontCache  if true, this is a hint not to attempt to cache this
112         *     or displace anything from extant caches for this data
113         *     as it may for example be precaching or random activity;
114         *     by default callers should leave this false to allow cacheing
115         *
116         * @throws java.lang.IllegalArgumentException  for invalid arguments such as
117         *     a null or syntactically-invalid name,
118         *     a negative position or excessive number of requested bytes,
119         *     a negative (or in some cases, non-positive) len
120         * @throws java.io.IOException for requests that cannot be fulfilled because of
121         *     I/O restrictions or problems, such as link failure or
122         *     an upper bound on the length of a request
123         */
124        public void getRawFile(ByteBuffer buf,
125                               Name.ExhibitFull exhibitName, int position, boolean dontCache)
126            throws IOException;
127    
128        /**Gets set of all static exhibit data if its timestamp is not that specified.
129         * If the time specified is negative the object will be returned unconditionally.
130         * <p>
131         * If no exhibits are currently installed a default set with a zero
132         * timestamp is returned.
133         * <p>
134         * If the caller's copy appears to be up-to-date (eg the oldStamp
135         * matches that that would have been returned) null is returned.
136         *
137         * @throws java.io.IOException if the operation cannot be completed due to I/O
138         *     restrictions or failure
139         */
140        public AllExhibitImmutableData getAllExhibitImmutableData(long oldStamp)
141            throws IOException;
142    
143        /**Gets set of all exhibit properties if its hash is not that specified; never null for -1 argument.
144         * If the hash specified is negative the object will be returned unconditionally.
145         * <p>
146         * If no exhibits are currently installed a default set with a zero
147         * timestamp is returned.
148         * <p>
149         * If the caller's copy appears to be up-to-date (eg the oldHash
150         * matches that that would have been returned) null is returned.
151         *
152         * @throws java.io.IOException if the operation cannot be completed due to I/O
153         *     restrictions or failure
154         */
155        public AllExhibitProperties getAllExhibitProperties(long oldHash)
156            throws IOException;
157    
158        /**Gets the general properties as a GenProps object if its timestamp is not that specified; never null for -1 argument.
159         * If the time specified is negative the object will be returned unconditionally.
160         * <p>
161         * If no props are currently installed/available a default set with a zero
162         * timestamp is returned.
163         * <p>
164         * If the caller's copy appears to be up-to-date (eg the oldStamp
165         * matches that that would have been returned) null is returned.
166         *
167         * @throws java.io.IOException if the operation cannot be completed due to I/O
168         *     restrictions or failure
169         */
170        public org.hd.d.pg2k.svrCore.props.GenProps getGenProps(long oldStamp)
171            throws IOException;
172    
173        /**Gets the generic security properties as a Properties object if its timestamp is not that specified.
174         * If the time specified is negative the object will be returned unconditionally.
175         * <p>
176         * If no props are currently installed/available a default set with a zero
177         * timestamp is returned.
178         * <p>
179         * If the caller's copy appears to be up-to-date (eg the oldStamp
180         * matches that that would have been returned) null is returned.
181         *
182         * @deprecated Use getProperties() for new code.
183         *
184         * @throws java.io.IOException if the operation cannot be completed due to I/O
185         *     restrictions or failure
186         */
187        @Deprecated
188        public java.util.Properties getGenSecProps(long oldStamp)
189            throws IOException;
190    
191        /**Gets the thumbnails for an exhibit.
192         * A data source is at liberty to refuse to compute thumbnails
193         * in which case it may return null, else it returns a
194         * non-null value which may include the `could-not-compute'
195         * value to indicate that a thumbnail/sample cannot be made
196         * for this exhibit and no attempt need be made in future.
197         *
198         * @param create  if true, and no thumbnail yet exists, try to
199         *     create one if possible, else if create is false
200         *     only return an existing one and return null if none is to hand
201         *
202         * @throws java.io.IOException if the operation cannot be completed due to I/O
203         *     restrictions or failure
204         */
205        public ExhibitThumbnails getThumbnails(ExhibitFull name, boolean create)
206            throws IOException;
207    
208        /**Class that holds key to Properties lookup/fetch.
209         * Immutable, and can be used as a key in a hash table.
210         */
211        public enum PropsKey
212            {
213            /**Generic security properties. */
214            GenSecProps,
215    
216            /**Properties map from IPv4 octet prefix to ccTLD/region. */
217            IPToCCTld,
218    
219            /**Location map from exhibit name (usually prefix/suffix) to Location value. */
220            NameToLocation,
221            }
222    
223        /**Get requested Properties selected by key and versionID.
224         * Fetches a Properties set unconditionally (versionID == -1)
225         * else if the versionID presented is not current.
226         *
227         * @param key  selector (with possible embedded sub-key)
228         *     for desired properties set; never null
229         * @param versionID  if -1 then map is always returned if available,
230         *     else must be non-negative and null is returned if the versionID
231         *     presented matches that of the current version
232         *     (ie if the caller has presumably got the up-to-date version);
233         *     may be a timestamp or a hash or other value,
234         *     and by convention is zero only for an empty properties set
235         *
236         * @return null, or Properties map guaranteed to contain only
237         *     String keys and values
238         */
239        public java.util.Properties getProperties(PropsKey key, long versionID)
240            throws IOException;
241    
242        /**Gets information about our stratum and upstream server; never null. */
243        public Stratum getStratum()
244            throws IOException;
245    
246    
247        /**Poll periodically (of the order of seconds) to do background work.
248         * The current generic system properties are passed in...
249         * <p>
250         * @throws java.io.IOException in case of difficulty, but even if a sub-ordinate
251         *     call throws IOException then poll() call should continue
252         *     to do as much of its remaining work as reasonably possible
253         */
254        public void poll(GenProps gp)
255            throws IOException;
256    
257        /**Shut down the data pipeline.
258         * Free resources having saved any persistent state
259         * and shut down any upstream components.
260         */
261        public void destroy();
262        }