/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.sun.jini.discovery;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.Socket;
import java.util.Collection;
import net.jini.core.constraint.InvocationConstraints;
import net.jini.io.UnsupportedConstraintException;
/**
* Class providing methods for participating in versions 1 and 2 of the
* discovery protocol. <p>
*
* <b><font size="+1">Logging</font></b> <p>
*
* This implementation uses the {@link java.util.logging.Logger}s named
* <code>com.sun.jini.discovery.DiscoveryV1</code> and
* <code>com.sun.jini.discovery.DiscoveryV2</code> to log information at the
* following logging levels: <p>
*
* <table border="1" cellpadding="5"
* summary="Describes logging performed by the
* Discovery class to the DiscoveryV1 logger at various
* logging levels">
*
* <caption halign="center" valign="top"><b><code>
* com.sun.jini.discovery.DiscoveryV1</code></b></caption>
*
* <tr> <th scope="col"> Level <th scope="col"> Description
*
* <tr> <td> {@link java.util.logging.Level#FINEST FINEST}
* <td> Encoding and decoding of discovery protocol version 1 multicast
* requests, multicast announcements, and unicast responses
*
* </table> <p>
*
* <table border="1" cellpadding="5"
* summary="Describes logging performed by the
* Discovery class to the DiscoveryV2 logger at various logging
* levels">
*
* <caption halign="center" valign="top"><b><code>
* com.sun.jini.discovery.DiscoveryV2</code></b></caption>
*
* <tr> <th scope="col"> Level <th scope="col"> Description
*
* <tr> <td> {@link java.util.logging.Level#WARNING WARNING}
* <td> Truncation of unicast request format ID list due to length;
* discovery format providers that are unusable or have conflicting
* discovery format IDs
*
* <tr> <td> {@link com.sun.jini.logging.Levels#HANDLED HANDLED}
* <td> Constraint check failures encountered during the unicast discovery
* handshake when determining a suitable discovery format to use
*
* <tr> <td> {@link java.util.logging.Level#FINEST FINEST}
* <td> Encoding and decoding of discovery protocol version 2 multicast
* requests, multicast announcements, and unicast responses; also,
* access of <code>Discovery</code> instances implementing protocol
* version 2
*
* </table>
*
* @author Sun Microsystems, Inc.
* @since 2.0
*/
public abstract class Discovery {
/** The version number for discovery protocol version 1. */
public static final int PROTOCOL_VERSION_1 = 1;
/** The version number for discovery protocol version 2. */
public static final int PROTOCOL_VERSION_2 = 2;
static final int MIN_MAX_PACKET_SIZE = 512;
/**
* Returns an instance implementing protocol version 1.
*
* @return an instance implementing protocol version 1
*/
public static Discovery getProtocol1() {
return DiscoveryV1.getInstance();
}
/**
* Returns an instance implementing protocol version 2 which uses providers
* loaded from the given class loader, or the current context class loader
* if the given loader is <code>null</code>. Available providers are
* determined by interpreting any resources of the indicated class loader
* named
* <code>"META-INF/services/com.sun.jini.discovery.DiscoveryFormatProvider"</code>
* as files containing names of provider classes, with one name per line.
*
* @param loader class loader from which to load providers, or
* <code>null</code> to indicate the current context class loader
* @return an instance implementing protocol version 2
*/
public static Discovery getProtocol2(ClassLoader loader) {
return DiscoveryV2.getInstance(loader);
}
/**
* Returns an instance implementing protocol version 2 which uses the given
* providers. Contents of arrays are copied; <code>null</code> array
* values are equivalent to empty arrays.
*
* @param mre providers for encoding multicast requests
* @param mrd providers for decoding multicast requests
* @param mae providers for encoding multicast announcements
* @param mad providers for decoding multicast announcements
* @param udc providers for performing the client side of unicast discovery
* @param uds providers for performing the server side of unicast discovery
* @return an instance implementing protocol version 2
*/
public static Discovery getProtocol2(MulticastRequestEncoder[] mre,
MulticastRequestDecoder[] mrd,
MulticastAnnouncementEncoder[] mae,
MulticastAnnouncementDecoder[] mad,
UnicastDiscoveryClient[] udc,
UnicastDiscoveryServer[] uds)
{
return DiscoveryV2.getInstance(mre, mrd, mae, mad, udc, uds);
}
/**
* Returns an iterator which can be used to encode the given multicast
* request data into sets of {@link DatagramPacket}s, each bounded in
* length by the specified maximum packet size, in a manner that satisfies
* the given constraints. <code>null</code> constraints are considered
* equivalent to empty constraints. The destination of each
* <code>DatagramPacket</code> produced by the returned iterator is set to
* the address returned by
* {@link net.jini.discovery.Constants#getRequestAddress}, with the value
* of {@link net.jini.discovery.Constants#discoveryPort} used as the
* destination port.
*
* @param request the request data to encode
* @param maxPacketSize the maximum size of packets to produce
* @param constraints the constraints to apply when encoding the data, or
* <code>null</code>
* @return an iterator to use for encoding the data
* @throws NullPointerException if <code>request</code> is
* <code>null</code>
*/
public abstract EncodeIterator encodeMulticastRequest(
MulticastRequest request,
int maxPacketSize,
InvocationConstraints constraints);
/**
* Decodes the multicast request data contained in the given datagram in a
* manner that satisfies the specified constraints and client subject
* checker (if any), returning a {@link MulticastRequest} instance that
* contains the decoded data. <code>null</code> constraints are considered
* equivalent to empty constraints. All the specified constraints are
* checked before this method returns.
*
* @param packet the packet to decode
* @param constraints the constraints to apply when decoding the packet, or
* <code>null</code>
* @param checker the object to use to check the client subject, or
* <code>null</code>
* @return the decoded multicast request data
* @throws IOException if an error occurs in interpreting the data
* @throws UnsupportedConstraintException if unable to satisfy the
* specified constraints
* @throws SecurityException if the given constraints cannot be satisfied
* due to insufficient caller permissions, or if the client subject check
* fails
* @throws NullPointerException if <code>packet</code> is <code>null</code>
*/
public abstract MulticastRequest decodeMulticastRequest(
DatagramPacket packet,
InvocationConstraints constraints,
ClientSubjectChecker checker)
throws IOException;
/**
* Decodes the multicast request data contained in the given datagram in a
* manner that satisfies the specified constraints and client subject
* checker (if any), returning a {@link MulticastRequest} instance that
* contains the decoded data, with constraint checking optionally
* delayed. <code>null</code> constraints are considered
* equivalent to empty constraints.
* <p>The <code>delayConstraintCheck</code> flag is used to control delayed
* constraint checking. Delayed constraint checking is useful for
* potentially delaying the expense of complete constraint checking, until
* other checks have been made on the returned
* <code>MulticastRequest</code> for preliminary validation.
* Implementations may ignore the flag, in which case, the behavior is
* equivalent to that of {@link
* Discovery#decodeMulticastRequest(DatagramPacket, InvocationConstraints,
* ClientSubjectChecker) decodeMulticastRequest}.
* <p>If <code>delayConstraintCheck</code> is <code>true</code>, the method
* behaves as follows:<ul>
* <li> Some of the specified constraints may not be checked before this
* method returns; the returned <code>MulticastRequest</code>'s
* {@link MulticastRequest#checkConstraints checkConstraints}
* method must be invoked to complete checking of all the constraints.
* <li> Constraints which must be checked before accessor methods of the
* returned <code>MulticastRequest</code> can be invoked are always
* checked before this method returns.</ul>
* <p>If <code>delayConstraintCheck</code> is <code>false</code>, all the
* specified constraints are checked before this method returns.
* <p><code>Discovery</code> implements this method to simply invoke {@link
* Discovery#decodeMulticastRequest(DatagramPacket, InvocationConstraints,
* ClientSubjectChecker) decodeMulticastRequest}, and thus checks all the
* specified constraints before returning.
*
* @param packet the packet to decode
* @param constraints the constraints to apply when decoding the packet, or
* <code>null</code>
* @param checker the object to use to check the client subject, or
* <code>null</code>
* @param delayConstraintCheck flag to control delayed constraint checking
* @return the decoded multicast request data.
* @throws IOException if an error occurs in interpreting the data
* @throws SecurityException if the given constraints cannot be satisfied
* due to insufficient caller permissions, or if the client subject check
* fails
* @throws NullPointerException if <code>packet</code> is <code>null</code>
* @since 2.1
*/
public MulticastRequest decodeMulticastRequest(
DatagramPacket packet,
InvocationConstraints constraints,
ClientSubjectChecker checker,
boolean delayConstraintCheck)
throws IOException
{
return decodeMulticastRequest(packet, constraints, checker);
}
/**
* Returns an iterator which can be used to encode the given multicast
* announcement data into sets of {@link DatagramPacket}s, each bounded in
* length by the specified maximum packet size, in a manner that satisfies
* the given constraints. <code>null</code> constraints are considered
* equivalent to empty constraints. The destination of each
* <code>DatagramPacket</code> produced by the returned iterator is set to
* the address returned by
* {@link net.jini.discovery.Constants#getAnnouncementAddress}, with the
* value of {@link net.jini.discovery.Constants#discoveryPort} used as the
* destination port.
*
* @param announcement the announcement data to encode
* @param maxPacketSize the maximum size of packets to produce
* @param constraints the constraints to apply when encoding the data, or
* <code>null</code>
* @return an iterator to use for encoding the data
* @throws NullPointerException if <code>announcement</code> is
* <code>null</code>
*/
public abstract EncodeIterator encodeMulticastAnnouncement(
MulticastAnnouncement announcement,
int maxPacketSize,
InvocationConstraints constraints);
/**
* Decodes the multicast announcement data contained in the given datagram
* in a manner that satisfies the specified constraints, returning a {@link
* MulticastAnnouncement} instance that contains the decoded data.
* <code>null</code> constraints are considered equivalent to empty
* constraints. All the specified constraints are checked before this
* method returns.
*
* @param packet the packet to decode
* @param constraints the constraints to apply when decoding the packet, or
* <code>null</code>
* @return the decoded multicast announcement data
* @throws IOException if an error occurs in interpreting the data
* @throws UnsupportedConstraintException if unable to satisfy the
* specified constraints
* @throws SecurityException if the given constraints cannot be satisfied
* due to insufficient caller permissions
* @throws NullPointerException if <code>packet</code> is <code>null</code>
*/
public abstract MulticastAnnouncement decodeMulticastAnnouncement(
DatagramPacket packet,
InvocationConstraints constraints)
throws IOException;
/**
* Decodes the multicast announcement data contained in the given datagram
* in a manner that satisfies the specified constraints, returning a {@link
* MulticastAnnouncement} instance that contains the decoded data, with
* constraint checking optionally delayed. <code>null</code> constraints
* are considered equivalent to empty constraints.
* <p>The <code>delayConstraintCheck</code> flag is used to control delayed
* constraint checking. Delayed constraint checking is useful for
* potentially delaying the expense of complete constraint checking, until
* other checks have been made on the returned
* <code>MulticastAnnouncement</code> for preliminary validation.
* Implementations may ignore the flag, in which case, the behavior is
* equivalent to that of {@link
* Discovery#decodeMulticastAnnouncement(DatagramPacket,
* InvocationConstraints) decodeMulticastAnnouncement}.
* <p>If <code>delayConstraintCheck</code> is <code>true</code>, the method
* behaves as follows:<ul>
* <li> Some of the specified constraints may not be checked before this
* method returns; the returned <code>MulticastAnnouncement</code>'s
* {@link MulticastAnnouncement#checkConstraints checkConstraints}
* method must be invoked to complete checking of all the constraints.
* <li> Constraints which must be checked before accessor methods of the
* returned <code>MulticastAnnouncement</code> can be invoked are always
* checked before this method returns.</ul>
* <p> If <code>delayConstraintCheck</code> is <code>false</code>,
* all the specified constraints are checked before this method returns.
* <p><code>Discovery</code> implements this method to simply invoke {@link
* Discovery#decodeMulticastAnnouncement(DatagramPacket,
* InvocationConstraints) decodeMulticastAnnouncement}, and thus checks
* all the specified constraints before returning.
*
* @param packet the packet to decode
* @param constraints the constraints to apply when decoding the packet, or
* <code>null</code>
* @param delayConstraintCheck flag to control delayed constraint checking
* @return the decoded multicast announcement data.
* @throws IOException if an error occurs in interpreting the data
* @throws UnsupportedConstraintException if unable to satisfy the
* specified constraints
* @throws SecurityException if the given constraints cannot be satisfied
* due to insufficient caller permissions.
* @throws NullPointerException if <code>packet</code> is <code>null</code>
* @since 2.1
*/
public MulticastAnnouncement decodeMulticastAnnouncement(
DatagramPacket packet,
InvocationConstraints constraints,
boolean delayConstraintCheck)
throws IOException
{
return decodeMulticastAnnouncement(packet, constraints);
}
/**
* Performs the client side of unicast discovery, obtaining the returned
* response data over the provided socket using the given default and
* codebase verifier class loaders and collection of object stream context
* objects in a manner that satisfies the specified constraints.
* <code>null</code> constraints are considered equivalent to empty
* constraints.
*
* @param socket the socket on which to perform unicast discovery
* @param constraints the constraints to apply to unicast discovery, or
* <code>null</code>
* @param defaultLoader the class loader value (possibly <code>null</code>)
* to be passed as the <code>defaultLoader</code> argument to
* <code>RMIClassLoader</code> methods when unmarshalling the registrar
* proxy
* @param verifierLoader the class loader value (possibly
* <code>null</code>) to pass to {@link
* net.jini.security.Security#verifyCodebaseIntegrity
* Security.verifyCodebaseIntegrity}, if codebase integrity verification is
* used when unmarshalling the registrar proxy
* @param context the collection of context information objects (possibly
* <code>null</code>) to use when unmarshalling the registrar proxy
* @return the received unicast response data
* @throws IOException if an error occurs in interpreting received data or
* in formatting data to send
* @throws UnsupportedConstraintException if unable to satisfy the
* specified constraints
* @throws SecurityException if the given constraints cannot be satisfied
* due to insufficient caller permissions
* @throws ClassNotFoundException if the class of the discovered registrar
* cannot be resolved
* @throws NullPointerException if <code>socket</code> is <code>null</code>
*/
public abstract UnicastResponse doUnicastDiscovery(
Socket socket,
InvocationConstraints constraints,
ClassLoader defaultLoader,
ClassLoader verifierLoader,
Collection context)
throws IOException, ClassNotFoundException;
/**
* Handles the server side of unicast discovery, transmitting the given
* response data over the provided socket using the given collection of
* object stream context objects in a manner that satisfies the specified
* constraints and client subject checker (if any). This method assumes
* that the protocol version number has already been consumed from the
* socket, but that no further processing of the connection has occurred.
* <code>null</code> constraints are considered equivalent to empty
* constraints.
*
* @param response the unicast response data to transmit
* @param socket the socket on which to handle unicast discovery
* @param constraints the constraints to apply to unicast discovery, or
* <code>null</code>
* @param checker the object to use to check the client subject, or
* <code>null</code>
* @param context the collection of context information objects to use when
* marshalling the registrar proxy
* @throws IOException if the protocol handshake fails, or if an error
* occurs in interpreting received data or in formatting data to send
* @throws UnsupportedConstraintException if unable to satisfy the
* specified constraints
* @throws SecurityException if the given constraints cannot be satisfied
* due to insufficient caller permissions, or if the client subject check
* fails
* @throws NullPointerException if <code>response</code>,
* <code>socket</code>, or <code>context</code> is <code>null</code>
*/
public abstract void handleUnicastDiscovery(
UnicastResponse response,
Socket socket,
InvocationConstraints constraints,
ClientSubjectChecker checker,
Collection context)
throws IOException;
}