1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 package net.jini.jeri;
20
21 import java.io.InputStream;
22 import java.io.OutputStream;
23 import java.util.Collection;
24 import net.jini.core.constraint.ConstraintAlternatives;
25 import net.jini.core.constraint.Integrity;
26 import net.jini.core.constraint.InvocationConstraints;
27
28 /**
29 * Represents a request that is being sent and the corresponding
30 * response received in reply.
31 *
32 * <p>An <code>OutboundRequest</code> can be used to write out the
33 * contents of the request and to read in the response.
34 *
35 * <p>The communication protocol used by the implementation of this
36 * interface must guarantee that for each instance of this interface,
37 * any request data must only be delivered to the recipient (in the
38 * form of an <code>InboundRequest</code> passed to {@link
39 * RequestDispatcher#dispatch RequestDispatcher.dispatch}) <i>at most
40 * once</i>. The {@link #getDeliveryStatus getDeliveryStatus} method
41 * can be used to determine whether or not at least partial delivery
42 * of the request might have occurred.
43 *
44 * <p>When finished using an <code>OutboundRequest</code>, in order to
45 * allow the implementation to free resources associated with the
46 * request, users should either invoke <code>close</code> on the
47 * streams returned by the <code>getRequestOutputStream</code> and
48 * <code>getResponseInputStream</code> methods, or invoke the
49 * <code>abort</code> method.
50 *
51 * @author Sun Microsystems, Inc.
52 * @see InboundRequest
53 * @since 2.0
54 **/
55 public interface OutboundRequest {
56
57 /**
58 * Populates the supplied collection with context information
59 * representing this request.
60 *
61 * @param context the context collection to populate
62 *
63 * @throws NullPointerException if <code>context</code> is
64 * <code>null</code>
65 *
66 * @throws UnsupportedOperationException if <code>context</code>
67 * is unmodifiable and if any elements need to be added
68 **/
69 void populateContext(Collection context);
70
71 /**
72 * Returns the requirements that must be at least partially
73 * implemented by higher layers in order to fully satisfy the
74 * requirements for this request. This method may also return
75 * preferences that must be at least partially implemented by
76 * higher layers in order to fully satisfy some of the preferences
77 * for this request.
78 *
79 * <p>For any given constraint, there must be a clear delineation
80 * of which aspects (if any) must be implemented by the transport
81 * layer. This method must not return a constraint (as a
82 * requirement or a preference, directly or as an element of
83 * another constraint) unless this request implements all of those
84 * aspects. Also, this method must not return a constraint for
85 * which all aspects must be implemented by the transport layer.
86 * Most of the constraints in the {@link net.jini.core.constraint}
87 * package must be fully implemented by the transport layer and
88 * thus must not be returned by this method; the one exception is
89 * {@link Integrity}, for which the transport layer is responsible
90 * for the data integrity aspect and higher layers are responsible
91 * for the code integrity aspect.
92 *
93 * <p>For any {@link ConstraintAlternatives} in the constraints
94 * for this request, this method should only return a
95 * corresponding constraint if all of the alternatives satisfied
96 * by this request need to be at least partially implemented by
97 * higher layers in order to be fully satisfied.
98 *
99 * @return the constraints for this request that must be partially
100 * or fully implemented by higher layers
101 **/
102 InvocationConstraints getUnfulfilledConstraints();
103
104 /**
105 * Returns an <code>OutputStream</code> to write the request data
106 * to. The sequence of bytes written to the returned stream will
107 * be the sequence of bytes sent as the body of this request.
108 *
109 * <p>After the entirety of the request has been written to the
110 * stream, the stream's <code>close</code> method must be invoked
111 * to ensure complete delivery of the request. It is possible
112 * that none of the data written to the returned stream will be
113 * delivered before <code>close</code> has been invoked (even if
114 * the stream's <code>flush</code> method had been invoked at any
115 * time). Note, however, that some or all of the data written to
116 * the stream may be delivered to (and processed by) the recipient
117 * before the stream's <code>close</code> method has been invoked.
118 *
119 * <p>After the stream's <code>close</code> method has been
120 * invoked, no more data may be written to the stream; writes
121 * subsequent to a <code>close</code> invocation will fail with an
122 * <code>IOException</code>.
123 *
124 * <p>If this method is invoked more than once, it will always
125 * return the identical stream object that it returned the first
126 * time (although the stream may be in a different state than it
127 * was upon return from the first invocation).
128 *
129 * @return the output stream to write request data to
130 **/
131 OutputStream getRequestOutputStream();
132
133 /**
134 * Returns an <code>InputStream</code> to read the response data
135 * from. The sequence of bytes produced by reading from the
136 * returned stream will be the sequence of bytes received as the
137 * response data. When the entirety of the response has been
138 * successfully read, reading from the stream will indicate an
139 * EOF.
140 *
141 * <p>Users of an <code>OutboundRequest</code> must not expect any
142 * data to be available from the returned stream before the
143 * <code>close</code> method has been invoked on the stream
144 * returned by <code>getRequestOutputStream</code>; in other
145 * words, the user's request/response protocol must not require
146 * any part of a request to be a function of any part of its
147 * response.
148 *
149 * <p>It is possible, however, for data to be available from the
150 * returned stream before the <code>close</code> method has been
151 * invoked on, or even before the entirety of the request has been
152 * written to, the stream returned by
153 * <code>getRequestOutputStream</code>. Because such an early
154 * response might indicate, depending on the user's
155 * request/response protocol, that the recipient will not consider
156 * the entirety of the request, perhaps due to an error or other
157 * abnormal condition, the user may wish to process it
158 * expeditiously, rather than continuing to write the remainder of
159 * the request.
160 *
161 * <p>Invoking the <code>close</code> method of the returned
162 * stream will cause any subsequent read operations on the stream
163 * to fail with an <code>IOException</code>, although it will not
164 * terminate this request as a whole; in particular, the request
165 * may still be subsequently written to the stream returned by the
166 * <code>getRequestOutputStream</code> method. After
167 * <code>close</code> has been invoked on both the returned stream
168 * and the stream returned by <code>getRequestOutputStream</code>,
169 * the implementation may free all resources associated with this
170 * request.
171 *
172 * <p>If this method is invoked more than once, it will always
173 * return the identical stream object that it returned the first
174 * time (although the stream may be in a different state than it
175 * was upon return from the first invocation).
176 *
177 * @return the input stream to read response data from
178 **/
179 InputStream getResponseInputStream();
180
181 /**
182 * Returns <code>false</code> if it is guaranteed that no data
183 * written for this request has been processed by the recipient.
184 * This guarantee remains valid until any subsequent I/O operation
185 * has been attempted on this request.
186 *
187 * If this method returns <code>true</code>, then data written for
188 * this request may have been at least partially processed by the
189 * recipient (the <code>RequestDispatcher</code> receiving the
190 * corresponding <code>InboundRequest</code>).
191 *
192 * @return <code>false</code> if data written for this request has
193 * definitely not been processed by the recipient, and
194 * <code>true</code> if data written for this request may have
195 * been at least partially processed by the recipient
196 **/
197 boolean getDeliveryStatus();
198
199 /**
200 * Terminates this request, freeing all associated resources.
201 *
202 * <p>This method may be invoked at any stage of the processing of
203 * the request.
204 *
205 * <p>After this method has been invoked, I/O operations on the
206 * streams returned by the <code>getRequestOutputStream</code> and
207 * <code>getResponseInputStream</code> methods will fail with an
208 * <code>IOException</code>, except some operations that may
209 * succeed because they only affect data in local I/O buffers.
210 *
211 * <p>If this method is invoked before the <code>close</code>
212 * method has been invoked on the stream returned by
213 * <code>getRequestOutputStream</code>, there is no guarantee that
214 * any or none of the data written to the stream so far will be
215 * delivered; the implication of such an invocation of this method
216 * is that the user is no longer interested in the successful
217 * delivery of the request.
218 **/
219 void abort();
220 }