You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by pe...@apache.org on 2020/07/05 11:41:42 UTC
svn commit: r1879521 [10/37] - in
/river/jtsk/modules/modularize/apache-river: ./ browser/
browser/src/main/java/org/apache/river/example/browser/ extra/
groovy-config/ river-activation/ river-collections/
river-collections/src/main/java/org/apache/riv...
Modified: river/jtsk/modules/modularize/apache-river/river-services/fiddler/fiddler-dl/src/main/java/org/apache/river/fiddler/proxy/FiddlerLeaseMap.java
URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/fiddler/fiddler-dl/src/main/java/org/apache/river/fiddler/proxy/FiddlerLeaseMap.java?rev=1879521&r1=1879520&r2=1879521&view=diff
==============================================================================
--- river/jtsk/modules/modularize/apache-river/river-services/fiddler/fiddler-dl/src/main/java/org/apache/river/fiddler/proxy/FiddlerLeaseMap.java (original)
+++ river/jtsk/modules/modularize/apache-river/river-services/fiddler/fiddler-dl/src/main/java/org/apache/river/fiddler/proxy/FiddlerLeaseMap.java Sun Jul 5 11:41:39 2020
@@ -1,417 +1,417 @@
-/*
- * 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 org.apache.river.fiddler;
-
-import org.apache.river.proxy.ConstrainableProxyUtil;
-import java.lang.reflect.Method;
-import java.rmi.RemoteException;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import net.jini.core.constraint.MethodConstraints;
-import net.jini.core.constraint.RemoteMethodControl;
-import net.jini.core.lease.Lease;
-import net.jini.core.lease.LeaseMap;
-import net.jini.core.lease.LeaseMapException;
-import net.jini.id.Uuid;
-import org.apache.river.lease.AbstractIDLeaseMap;
-
-/**
- * When clients request a registration with the Fiddler implementation of
- * the lookup discovery service, leases of type FiddlerLease are granted
- * on those registrations. Under certain circumstances it may be desirable
- * to collect multiple granted leases in a set which implements the
- * <code>net.jini.core.lease.LeaseMap</code> interface.
- * <p>
- * This class is the implementation class of the <code>LeaseMap</code>
- * interface that is employed by the Fiddler implementation of the lookup
- * discovery service. When a client wishes to "batch" leases granted by
- * that service, the are placed in an instance of this class.
- * <p>
- * Clients only see instances of this class via the <code>LeaseMap</code>
- * interface.
- *
- * @author Sun Microsystems, Inc.
- *
- */
-class FiddlerLeaseMap extends AbstractIDLeaseMap<FiddlerLease> {
-
- /**
- * The reference to the back-end server of the lookup discovery service
- *
- * @serial
- */
- final Fiddler server;
- /**
- * The unique ID associated with the server referenced in this class
- * (used to compare server references).
- *
- * @serial
- */
- final Uuid serverID;
-
- /**
- * Static factory method that creates and returns an instance of
- * <code>FiddlerLeaseMap</code>. If the lease input to this method
- * is and instance of <code>ConstrainableFiddlerLease</code>, then
- * the object returned by this method will be an instance of
- * <code>ConstrainableFiddlerLeaseMap</code>.
- *
- * Note that because of the way the <code>Lease</code> class for the
- * associated service is implemented, together with the way the
- * <code>canBatch</code> method of that class is implemented, if the
- * <code>lease</code> object input to this method implements
- * <code>ConstrainableFiddlerLease</code>, then the <code>server</code>
- * object referenced in this class will implement
- * <code>RemoteMethodControl</code> as well.
- *
- * @param lease reference to a lease to add to the map as a key value
- * @param duration the duration of the corresponding lease. This value
- * is the "mapped" value corresponding to the lease key.
- *
- * @return an instance of <code>FiddlerLeaseMap</code>, or an instance
- * of <code>ConstrainableFiddlerLeaseMap</code> if the given
- * <code>lease</code> is an instance of
- * <code>ConstrainableFiddlerLease</code>.
- */
- static FiddlerLeaseMap createLeaseMap(FiddlerLease lease, long duration) {
- if(lease instanceof FiddlerLease.ConstrainableFiddlerLease) {
- MethodConstraints leaseConstraints =
- ((FiddlerLease.ConstrainableFiddlerLease)lease).getConstraints();
-
- return new ConstrainableFiddlerLeaseMap(lease.getServer(),
- lease,
- duration,
- leaseConstraints);
- } else {
- return new FiddlerLeaseMap(lease.getServer(), lease, duration);
- }//endif
- }//end createLeaseMap
-
- /**
- * Constructs a new instance of FiddlerLeaseMap.
- *
- * @param server reference to the server object through which
- * communication occurs between the client-side and
- * server-side of the associated service.
- * @param lease reference to a lease to add to the map as a key value
- * @param duration the duration of the corresponding lease. This value
- * is the "mapped" value corresponding to the lease key.
- */
- private FiddlerLeaseMap(Fiddler server, FiddlerLease lease, long duration){
- super();
- this.server = server;
- this.serverID = lease.getServerID();
- put(lease, duration);
- }//end constructor
-
- /**
- * Examines the input parameter to determine if that parameter will be
- * accepted or rejected by this map as a "legal" key value.
- * <p>
- * This method will return true if the <code>key</code> parameter is
- * the type of lease which can be "batch-wise" renewed and cancelled
- * along with all of the other leases in the map.
- * <p>
- * For the Fiddler implementation of the lookup discovery service, two
- * leases can be batched (placed in the same </code>FiddlerLeaseMap</code>)
- * if they are both instances of <code>FiddlerLease</code> and they
- * were both granted by the same Fiddler implementation of the lookup
- * discovery service. That is, they are the same type, and they were
- * granted by the same server.
- *
- * @param key reference to the object that this method examines to
- * determine if this map will accept or reject it as a key
- *
- * @return true if this map will accept the <code>key</code> parameter,
- * false otherwise
- *
- * @see net.jini.core.lease.Lease#canBatch
- */
- public boolean canContainKey(Object key) {
- return ( (key instanceof FiddlerLease)
- && (serverID.equals(((FiddlerLease)key).getServerID())) );
- }
-
- /**
- * Renews all leases in this map. For each lease (key) in the map, the
- * duration used to renew the lease is the lease's corresponding map
- * value. If all renewal attempts are successful, this method returns
- * normally; otherwise, this method removes from this map all leases
- * that could not be renewed, and throws a <code>LeaseMapException</code>.
- *
- * @throws net.jini.core.lease.LeaseMapException this exception is thrown
- * when one or more leases in the map could not be renewed.
- *
- * @throws java.rmi.RemoteException typically, this exception occurs when
- * there is a communication failure between the client and the
- * server. When this exception does occur, the leases in the map
- * may or may not have been renewed successfully.
- */
- public void renewAll() throws LeaseMapException, RemoteException {
- if (isEmpty()) return;
- List<FiddlerLease> keys = new LinkedList<FiddlerLease>();
- List<Uuid> registrationIDs = new LinkedList<Uuid>();
- List<Uuid> leaseIDs = new LinkedList<Uuid>();
- List<Long> durations = new LinkedList<Long>();
- Iterator<Entry<FiddlerLease,Long>> it = entrySet().iterator();
- while (it.hasNext()){
- Entry<FiddlerLease,Long> e = it.next();
- FiddlerLease ls = e.getKey();
- keys.add(ls);
- registrationIDs.add(ls.getRegistrationID());
- leaseIDs.add(ls.getLeaseID());
- durations.add(e.getValue());
- }
- long [] dur = new long[durations.size()];
- int i = 0;
- for (Iterator<Long> durIt = durations.iterator(); durIt.hasNext(); i++){
- dur[i] = durIt.next().intValue();
- }
- FiddlerRenewResults results = server.renewLeases(
- registrationIDs.toArray(new Uuid[registrationIDs.size()]),
- leaseIDs.toArray(new Uuid[leaseIDs.size()]),
- dur
- );
- long now = System.currentTimeMillis();
- HashMap<Lease,Exception> emap = (results.exceptions != null) ?
- new HashMap<Lease,Exception>(2 * results.exceptions.length + 1) : null;
- i = 0;
- int j = 0;
- for (Iterator<FiddlerLease> iter = keys.iterator(); iter.hasNext(); i++) {
- FiddlerLease e = iter.next();
- long duration = results.durations[i];
- if (duration >= 0) {
- // Mutation of volatile field
- e.setExpiration(duration + now);
- } else {
- emap.put(e, results.exceptions[j++]);
- remove(e);
- }
- }
- if (emap != null) {
- throw new LeaseMapException("lease renewal failures", emap);
- }
- }
-
- /**
- * Cancels all leases in this map. If all cancellation attempts are
- * successful, this method returns normally; otherwise, this method
- * removes from this map all leases that could not be cancelled, and
- * throws a <code>LeaseMapException</code>.
- * <p>
- * Note that a lease is removed from this map only when an attempt to
- * cancel it fails; that is, every lease that is successfully cancelled
- * is left in the map.
- *
- * @throws net.jini.core.lease.LeaseMapException this exception is thrown
- * when one or more leases in the map could not be cancelled.
- *
- * @throws java.rmi.RemoteException typically, this exception occurs when
- * there is a communication failure between the client and the
- * server. When this exception does occur, the leases in the map
- * may or may not have been cancelled successfully.
- */
- public void cancelAll() throws LeaseMapException, RemoteException {
- if( isEmpty()) return;
- List<FiddlerLease> leases = new LinkedList<FiddlerLease>();
- List<Uuid> registrationIDs = new LinkedList<Uuid>();
- List<Uuid> leaseIDs = new LinkedList<Uuid>();
- int i = 0;
- for (Iterator<FiddlerLease> iter = keySet().iterator(); iter.hasNext(); i++) {
- FiddlerLease ls = iter.next();
- leases.add(ls);
- registrationIDs.add(ls.getRegistrationID());
- leaseIDs.add(ls.getLeaseID());
- }
- Exception[] exceptions = server.cancelLeases(
- registrationIDs.toArray(new Uuid[registrationIDs.size()]),
- leaseIDs.toArray(new Uuid[leaseIDs.size()])
- );
- if (exceptions == null) {
- return;
- }
- i = 0;
- Map<Lease,Exception> emap = new HashMap<Lease,Exception>(13);
- for (Iterator<FiddlerLease> iter = leases.iterator(); iter.hasNext(); i++) {
- FiddlerLease ls = iter.next();
- Exception ex = exceptions[i];
- if (ex != null) {
- emap.put(ls, ex);
- remove(ls);
- }
- }
- throw new LeaseMapException("lease cancellation failures", emap);
- }
-
- /** The constrainable version of the class <code>FiddlerLeaseMap</code>.
- *
- * @since 2.0
- */
- static final class ConstrainableFiddlerLeaseMap extends FiddlerLeaseMap {
-
- /* Convenience fields containing, respectively, the renew and cancel
- * methods defined in the Lease interface. These fields are used in
- * the method mapping array, and when retrieving method constraints
- * for comparison in canContainKey().
- */
- private static final Method renewMethod =
- ProxyUtil.getMethod(Lease.class,
- "renew",
- new Class[] {long.class} );
- private static final Method cancelMethod =
- ProxyUtil.getMethod(Lease.class,
- "cancel",
- new Class[] {} );
-
- /* When a <code>LeaseMap</code> is created, an implicit set of
- * constraints is generated and associated with that lease map.
- * The constraints that are generated are based on the constraints
- * on the first lease placed in that lease map. As such, the array
- * defined here contains element pairs in which each pair of elements
- * represents a correspondence 'mapping' between two methods having
- * the following characteristics:
- * - the first element in the pair is one of the public, remote
- * method(s) that may be invoked by the client through a lease
- * proxy, and which has method constraints that are intended
- * to apply to the corresponding method that is invoked on
- * server's backend
- * - the second element in the pair is the method, implemented
- * in the backend server class, that is intended to be
- * executed with the same method constraints as its corresponding
- * method, specified in the first element of the pair
- */
- private static final Method[] methodMapArray =
- {
- renewMethod, ProxyUtil.getMethod(Fiddler.class,
- "renewLeases",
- new Class[] {Uuid[].class,
- Uuid[].class,
- long[].class}),
-
- cancelMethod, ProxyUtil.getMethod(Fiddler.class,
- "cancelLeases",
- new Class[] {Uuid[].class,
- Uuid[].class})
- };//end methodMapArray
-
- /** In order to determine if a given lease will be accepted by this
- * map as a "legal" key value, the method <code>canContainKey</code>
- * must verify that the corresponding methods of the initial
- * lease used to create this map and the lease input to
- * <code>canContainKey</code> have equivalent constraints. The
- * array defined here contains the set of methods whose constraints
- * will be compared in <code>canContainKey</code>.
- */
- private static final Method[] canContainKeyMethodMapArray =
- { renewMethod, renewMethod,
- cancelMethod, cancelMethod
- };//end canContainKeyMethodMapArray
-
- /** Client constraints placed on this proxy (may be <code>null</code>).
- *
- * @serial
- */
- private MethodConstraints methodConstraints;
-
- /** Constructs a new <code>ConstrainableFiddlerLeaseMap</code>
- * instance.
- * <p>
- * For a description of all but the <code>methodConstraints</code>
- * argument (provided below), refer to the description for the
- * constructor of this class' super class.
- *
- * @param methodConstraints the client method constraints to place on
- * this proxy (may be <code>null</code>).
- */
- private ConstrainableFiddlerLeaseMap
- (Fiddler server,
- FiddlerLease lease,
- long duration,
- MethodConstraints methodConstraints)
- {
- super(constrainServer(server, methodConstraints), lease, duration);
- this.methodConstraints = methodConstraints;
- }//end constructor
-
- /**
- * Examines the input parameter to determine if that parameter will
- * be accepted or rejected by this map as a "legal" key value.
- * <p>
- * This method will return true if the <code>key</code> parameter is
- * the type of lease which can be "batch-wise" renewed and cancelled
- * along with all of the other leases in the map.
- * <p>
- * For this implementation of the service, two leases can be
- * batched (placed in the same service-specific instance of
- * <code>LeaseMap</code>) if those leases satisfy the following
- * conditions:
- * <p><ul>
- * <li> the leases are the same type; that is, the leases are
- * both instances of the same, constrainable, service-specific
- * <code>Lease</code> implementation
- * <li> the leases were granted by the same backend server
- * <li> the leases have the same constraints
- *
- * @param key reference to the object that this method examines to
- * determine if this map will accept or reject it as a key
- *
- * @return <code>true</code> if this map will accept the
- * <code>key</code> parameter, <code>false</code> otherwise
- *
- * @see net.jini.core.lease.Lease#canBatch
- * @see net.jini.core.lease.LeaseMap#canContainKey
- */
- public boolean canContainKey(Object key) {
- if( !(super.canContainKey(key)) ) return false;
- /* Non-constrainable criteria satisfied, now handle constrainable
- * case.
- */
- if( !(key instanceof FiddlerLease.ConstrainableFiddlerLease) ) {
- return false;
- }//endif
- /* Compare constraints */
- MethodConstraints keyConstraints =
- ((FiddlerLease.ConstrainableFiddlerLease)key).getConstraints();
- return ConstrainableProxyUtil.equivalentConstraints
- ( methodConstraints,
- keyConstraints,
- canContainKeyMethodMapArray );
- }//end ConstrainableFiddlerLeaseMap.canContainKey
-
- /** Returns a copy of the given server proxy having the client method
- * constraints that result after the specified method mapping is
- * applied to the given client method constraints.
- */
- private static Fiddler constrainServer( Fiddler server,
- MethodConstraints constraints )
- {
- MethodConstraints newConstraints
- = ConstrainableProxyUtil.translateConstraints(constraints,
- methodMapArray);
- RemoteMethodControl constrainedServer =
- ((RemoteMethodControl)server).setConstraints(newConstraints);
-
- return ((Fiddler)constrainedServer);
- }//end constrainServer
-
- }//end class ConstrainableFiddlerLeaseMap
-
-}//end class FiddlerLeaseMap
+/*
+ * 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 org.apache.river.fiddler.proxy;
+
+import org.apache.river.proxy.ConstrainableProxyUtil;
+import java.lang.reflect.Method;
+import java.rmi.RemoteException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import net.jini.core.constraint.MethodConstraints;
+import net.jini.core.constraint.RemoteMethodControl;
+import net.jini.core.lease.Lease;
+import net.jini.core.lease.LeaseMap;
+import net.jini.core.lease.LeaseMapException;
+import net.jini.id.Uuid;
+import org.apache.river.lease.AbstractIDLeaseMap;
+
+/**
+ * When clients request a registration with the Fiddler implementation of
+ * the lookup discovery service, leases of type FiddlerLease are granted
+ * on those registrations. Under certain circumstances it may be desirable
+ * to collect multiple granted leases in a set which implements the
+ * <code>net.jini.core.lease.LeaseMap</code> interface.
+ * <p>
+ * This class is the implementation class of the <code>LeaseMap</code>
+ * interface that is employed by the Fiddler implementation of the lookup
+ * discovery service. When a client wishes to "batch" leases granted by
+ * that service, the are placed in an instance of this class.
+ * <p>
+ * Clients only see instances of this class via the <code>LeaseMap</code>
+ * interface.
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ */
+class FiddlerLeaseMap extends AbstractIDLeaseMap<FiddlerLease> {
+
+ /**
+ * The reference to the back-end server of the lookup discovery service
+ *
+ * @serial
+ */
+ final Fiddler server;
+ /**
+ * The unique ID associated with the server referenced in this class
+ * (used to compare server references).
+ *
+ * @serial
+ */
+ final Uuid serverID;
+
+ /**
+ * Static factory method that creates and returns an instance of
+ * <code>FiddlerLeaseMap</code>. If the lease input to this method
+ * is and instance of <code>ConstrainableFiddlerLease</code>, then
+ * the object returned by this method will be an instance of
+ * <code>ConstrainableFiddlerLeaseMap</code>.
+ *
+ * Note that because of the way the <code>Lease</code> class for the
+ * associated service is implemented, together with the way the
+ * <code>canBatch</code> method of that class is implemented, if the
+ * <code>lease</code> object input to this method implements
+ * <code>ConstrainableFiddlerLease</code>, then the <code>server</code>
+ * object referenced in this class will implement
+ * <code>RemoteMethodControl</code> as well.
+ *
+ * @param lease reference to a lease to add to the map as a key value
+ * @param duration the duration of the corresponding lease. This value
+ * is the "mapped" value corresponding to the lease key.
+ *
+ * @return an instance of <code>FiddlerLeaseMap</code>, or an instance
+ * of <code>ConstrainableFiddlerLeaseMap</code> if the given
+ * <code>lease</code> is an instance of
+ * <code>ConstrainableFiddlerLease</code>.
+ */
+ static FiddlerLeaseMap createLeaseMap(FiddlerLease lease, long duration) {
+ if(lease instanceof FiddlerLease.ConstrainableFiddlerLease) {
+ MethodConstraints leaseConstraints =
+ ((FiddlerLease.ConstrainableFiddlerLease)lease).getConstraints();
+
+ return new ConstrainableFiddlerLeaseMap(lease.getServer(),
+ lease,
+ duration,
+ leaseConstraints);
+ } else {
+ return new FiddlerLeaseMap(lease.getServer(), lease, duration);
+ }//endif
+ }//end createLeaseMap
+
+ /**
+ * Constructs a new instance of FiddlerLeaseMap.
+ *
+ * @param server reference to the server object through which
+ * communication occurs between the client-side and
+ * server-side of the associated service.
+ * @param lease reference to a lease to add to the map as a key value
+ * @param duration the duration of the corresponding lease. This value
+ * is the "mapped" value corresponding to the lease key.
+ */
+ private FiddlerLeaseMap(Fiddler server, FiddlerLease lease, long duration){
+ super();
+ this.server = server;
+ this.serverID = lease.getServerID();
+ put(lease, duration);
+ }//end constructor
+
+ /**
+ * Examines the input parameter to determine if that parameter will be
+ * accepted or rejected by this map as a "legal" key value.
+ * <p>
+ * This method will return true if the <code>key</code> parameter is
+ * the type of lease which can be "batch-wise" renewed and cancelled
+ * along with all of the other leases in the map.
+ * <p>
+ * For the Fiddler implementation of the lookup discovery service, two
+ * leases can be batched (placed in the same </code>FiddlerLeaseMap</code>)
+ * if they are both instances of <code>FiddlerLease</code> and they
+ * were both granted by the same Fiddler implementation of the lookup
+ * discovery service. That is, they are the same type, and they were
+ * granted by the same server.
+ *
+ * @param key reference to the object that this method examines to
+ * determine if this map will accept or reject it as a key
+ *
+ * @return true if this map will accept the <code>key</code> parameter,
+ * false otherwise
+ *
+ * @see net.jini.core.lease.Lease#canBatch
+ */
+ public boolean canContainKey(Object key) {
+ return ( (key instanceof FiddlerLease)
+ && (serverID.equals(((FiddlerLease)key).getServerID())) );
+ }
+
+ /**
+ * Renews all leases in this map. For each lease (key) in the map, the
+ * duration used to renew the lease is the lease's corresponding map
+ * value. If all renewal attempts are successful, this method returns
+ * normally; otherwise, this method removes from this map all leases
+ * that could not be renewed, and throws a <code>LeaseMapException</code>.
+ *
+ * @throws net.jini.core.lease.LeaseMapException this exception is thrown
+ * when one or more leases in the map could not be renewed.
+ *
+ * @throws java.rmi.RemoteException typically, this exception occurs when
+ * there is a communication failure between the client and the
+ * server. When this exception does occur, the leases in the map
+ * may or may not have been renewed successfully.
+ */
+ public void renewAll() throws LeaseMapException, RemoteException {
+ if (isEmpty()) return;
+ List<FiddlerLease> keys = new LinkedList<FiddlerLease>();
+ List<Uuid> registrationIDs = new LinkedList<Uuid>();
+ List<Uuid> leaseIDs = new LinkedList<Uuid>();
+ List<Long> durations = new LinkedList<Long>();
+ Iterator<Entry<FiddlerLease,Long>> it = entrySet().iterator();
+ while (it.hasNext()){
+ Entry<FiddlerLease,Long> e = it.next();
+ FiddlerLease ls = e.getKey();
+ keys.add(ls);
+ registrationIDs.add(ls.getRegistrationID());
+ leaseIDs.add(ls.getLeaseID());
+ durations.add(e.getValue());
+ }
+ long [] dur = new long[durations.size()];
+ int i = 0;
+ for (Iterator<Long> durIt = durations.iterator(); durIt.hasNext(); i++){
+ dur[i] = durIt.next().intValue();
+ }
+ FiddlerRenewResults results = server.renewLeases(
+ registrationIDs.toArray(new Uuid[registrationIDs.size()]),
+ leaseIDs.toArray(new Uuid[leaseIDs.size()]),
+ dur
+ );
+ long now = System.currentTimeMillis();
+ HashMap<Lease,Exception> emap = (results.exceptions != null) ?
+ new HashMap<Lease,Exception>(2 * results.exceptions.length + 1) : null;
+ i = 0;
+ int j = 0;
+ for (Iterator<FiddlerLease> iter = keys.iterator(); iter.hasNext(); i++) {
+ FiddlerLease e = iter.next();
+ long duration = results.durations[i];
+ if (duration >= 0) {
+ // Mutation of volatile field
+ e.setExpiration(duration + now);
+ } else {
+ emap.put(e, results.exceptions[j++]);
+ remove(e);
+ }
+ }
+ if (emap != null) {
+ throw new LeaseMapException("lease renewal failures", emap);
+ }
+ }
+
+ /**
+ * Cancels all leases in this map. If all cancellation attempts are
+ * successful, this method returns normally; otherwise, this method
+ * removes from this map all leases that could not be cancelled, and
+ * throws a <code>LeaseMapException</code>.
+ * <p>
+ * Note that a lease is removed from this map only when an attempt to
+ * cancel it fails; that is, every lease that is successfully cancelled
+ * is left in the map.
+ *
+ * @throws net.jini.core.lease.LeaseMapException this exception is thrown
+ * when one or more leases in the map could not be cancelled.
+ *
+ * @throws java.rmi.RemoteException typically, this exception occurs when
+ * there is a communication failure between the client and the
+ * server. When this exception does occur, the leases in the map
+ * may or may not have been cancelled successfully.
+ */
+ public void cancelAll() throws LeaseMapException, RemoteException {
+ if( isEmpty()) return;
+ List<FiddlerLease> leases = new LinkedList<FiddlerLease>();
+ List<Uuid> registrationIDs = new LinkedList<Uuid>();
+ List<Uuid> leaseIDs = new LinkedList<Uuid>();
+ int i = 0;
+ for (Iterator<FiddlerLease> iter = keySet().iterator(); iter.hasNext(); i++) {
+ FiddlerLease ls = iter.next();
+ leases.add(ls);
+ registrationIDs.add(ls.getRegistrationID());
+ leaseIDs.add(ls.getLeaseID());
+ }
+ Exception[] exceptions = server.cancelLeases(
+ registrationIDs.toArray(new Uuid[registrationIDs.size()]),
+ leaseIDs.toArray(new Uuid[leaseIDs.size()])
+ );
+ if (exceptions == null) {
+ return;
+ }
+ i = 0;
+ Map<Lease,Exception> emap = new HashMap<Lease,Exception>(13);
+ for (Iterator<FiddlerLease> iter = leases.iterator(); iter.hasNext(); i++) {
+ FiddlerLease ls = iter.next();
+ Exception ex = exceptions[i];
+ if (ex != null) {
+ emap.put(ls, ex);
+ remove(ls);
+ }
+ }
+ throw new LeaseMapException("lease cancellation failures", emap);
+ }
+
+ /** The constrainable version of the class <code>FiddlerLeaseMap</code>.
+ *
+ * @since 2.0
+ */
+ static final class ConstrainableFiddlerLeaseMap extends FiddlerLeaseMap {
+
+ /* Convenience fields containing, respectively, the renew and cancel
+ * methods defined in the Lease interface. These fields are used in
+ * the method mapping array, and when retrieving method constraints
+ * for comparison in canContainKey().
+ */
+ private static final Method renewMethod =
+ ProxyUtil.getMethod(Lease.class,
+ "renew",
+ new Class[] {long.class} );
+ private static final Method cancelMethod =
+ ProxyUtil.getMethod(Lease.class,
+ "cancel",
+ new Class[] {} );
+
+ /* When a <code>LeaseMap</code> is created, an implicit set of
+ * constraints is generated and associated with that lease map.
+ * The constraints that are generated are based on the constraints
+ * on the first lease placed in that lease map. As such, the array
+ * defined here contains element pairs in which each pair of elements
+ * represents a correspondence 'mapping' between two methods having
+ * the following characteristics:
+ * - the first element in the pair is one of the public, remote
+ * method(s) that may be invoked by the client through a lease
+ * proxy, and which has method constraints that are intended
+ * to apply to the corresponding method that is invoked on
+ * server's backend
+ * - the second element in the pair is the method, implemented
+ * in the backend server class, that is intended to be
+ * executed with the same method constraints as its corresponding
+ * method, specified in the first element of the pair
+ */
+ private static final Method[] methodMapArray =
+ {
+ renewMethod, ProxyUtil.getMethod(Fiddler.class,
+ "renewLeases",
+ new Class[] {Uuid[].class,
+ Uuid[].class,
+ long[].class}),
+
+ cancelMethod, ProxyUtil.getMethod(Fiddler.class,
+ "cancelLeases",
+ new Class[] {Uuid[].class,
+ Uuid[].class})
+ };//end methodMapArray
+
+ /** In order to determine if a given lease will be accepted by this
+ * map as a "legal" key value, the method <code>canContainKey</code>
+ * must verify that the corresponding methods of the initial
+ * lease used to create this map and the lease input to
+ * <code>canContainKey</code> have equivalent constraints. The
+ * array defined here contains the set of methods whose constraints
+ * will be compared in <code>canContainKey</code>.
+ */
+ private static final Method[] canContainKeyMethodMapArray =
+ { renewMethod, renewMethod,
+ cancelMethod, cancelMethod
+ };//end canContainKeyMethodMapArray
+
+ /** Client constraints placed on this proxy (may be <code>null</code>).
+ *
+ * @serial
+ */
+ private MethodConstraints methodConstraints;
+
+ /** Constructs a new <code>ConstrainableFiddlerLeaseMap</code>
+ * instance.
+ * <p>
+ * For a description of all but the <code>methodConstraints</code>
+ * argument (provided below), refer to the description for the
+ * constructor of this class' super class.
+ *
+ * @param methodConstraints the client method constraints to place on
+ * this proxy (may be <code>null</code>).
+ */
+ private ConstrainableFiddlerLeaseMap
+ (Fiddler server,
+ FiddlerLease lease,
+ long duration,
+ MethodConstraints methodConstraints)
+ {
+ super(constrainServer(server, methodConstraints), lease, duration);
+ this.methodConstraints = methodConstraints;
+ }//end constructor
+
+ /**
+ * Examines the input parameter to determine if that parameter will
+ * be accepted or rejected by this map as a "legal" key value.
+ * <p>
+ * This method will return true if the <code>key</code> parameter is
+ * the type of lease which can be "batch-wise" renewed and cancelled
+ * along with all of the other leases in the map.
+ * <p>
+ * For this implementation of the service, two leases can be
+ * batched (placed in the same service-specific instance of
+ * <code>LeaseMap</code>) if those leases satisfy the following
+ * conditions:
+ * <p><ul>
+ * <li> the leases are the same type; that is, the leases are
+ * both instances of the same, constrainable, service-specific
+ * <code>Lease</code> implementation
+ * <li> the leases were granted by the same backend server
+ * <li> the leases have the same constraints
+ *
+ * @param key reference to the object that this method examines to
+ * determine if this map will accept or reject it as a key
+ *
+ * @return <code>true</code> if this map will accept the
+ * <code>key</code> parameter, <code>false</code> otherwise
+ *
+ * @see net.jini.core.lease.Lease#canBatch
+ * @see net.jini.core.lease.LeaseMap#canContainKey
+ */
+ public boolean canContainKey(Object key) {
+ if( !(super.canContainKey(key)) ) return false;
+ /* Non-constrainable criteria satisfied, now handle constrainable
+ * case.
+ */
+ if( !(key instanceof FiddlerLease.ConstrainableFiddlerLease) ) {
+ return false;
+ }//endif
+ /* Compare constraints */
+ MethodConstraints keyConstraints =
+ ((FiddlerLease.ConstrainableFiddlerLease)key).getConstraints();
+ return ConstrainableProxyUtil.equivalentConstraints
+ ( methodConstraints,
+ keyConstraints,
+ canContainKeyMethodMapArray );
+ }//end ConstrainableFiddlerLeaseMap.canContainKey
+
+ /** Returns a copy of the given server proxy having the client method
+ * constraints that result after the specified method mapping is
+ * applied to the given client method constraints.
+ */
+ private static Fiddler constrainServer( Fiddler server,
+ MethodConstraints constraints )
+ {
+ MethodConstraints newConstraints
+ = ConstrainableProxyUtil.translateConstraints(constraints,
+ methodMapArray);
+ RemoteMethodControl constrainedServer =
+ ((RemoteMethodControl)server).setConstraints(newConstraints);
+
+ return ((Fiddler)constrainedServer);
+ }//end constrainServer
+
+ }//end class ConstrainableFiddlerLeaseMap
+
+}//end class FiddlerLeaseMap
Modified: river/jtsk/modules/modularize/apache-river/river-services/fiddler/fiddler-dl/src/main/java/org/apache/river/fiddler/proxy/FiddlerProxy.java
URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/fiddler/fiddler-dl/src/main/java/org/apache/river/fiddler/proxy/FiddlerProxy.java?rev=1879521&r1=1879520&r2=1879521&view=diff
==============================================================================
--- river/jtsk/modules/modularize/apache-river/river-services/fiddler/fiddler-dl/src/main/java/org/apache/river/fiddler/proxy/FiddlerProxy.java (original)
+++ river/jtsk/modules/modularize/apache-river/river-services/fiddler/fiddler-dl/src/main/java/org/apache/river/fiddler/proxy/FiddlerProxy.java Sun Jul 5 11:41:39 2020
@@ -1,483 +1,483 @@
-/*
- * 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 org.apache.river.fiddler;
-
-import org.apache.river.proxy.ConstrainableProxyUtil;
-
-import net.jini.admin.Administrable;
-import net.jini.discovery.LookupDiscoveryService;
-import net.jini.discovery.LookupDiscoveryRegistration;
-import net.jini.id.ReferentUuid;
-import net.jini.id.ReferentUuids;
-import net.jini.id.Uuid;
-import net.jini.security.proxytrust.ProxyTrustIterator;
-import net.jini.security.proxytrust.SingletonProxyTrustIterator;
-
-import net.jini.core.constraint.MethodConstraints;
-import net.jini.core.constraint.RemoteMethodControl;
-import net.jini.core.discovery.LookupLocator;
-import net.jini.core.event.RemoteEventListener;
-
-import java.lang.reflect.Method;
-import java.io.InvalidObjectException;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.Serializable;
-import java.rmi.RemoteException;
-import java.rmi.MarshalledObject;
-
-/**
- * This class is a proxy for a lookup discovery service. Clients only see
- * instances of this class via the LookupDiscoveryService interface (and
- * the FiddlerAdmin interface if needed).
- *
- * @author Sun Microsystems, Inc.
- *
- */
-class FiddlerProxy implements Administrable, LookupDiscoveryService,
- ReferentUuid, Serializable
-{
- private static final long serialVersionUID = 2L;
- /**
- * The reference through which communication occurs between the
- * client-side and the server-side of the lookup discovery service
- *
- * @serial
- */
- final Fiddler server;
- /**
- * The unique identifier assigned to the current instance of this
- * proxy class by the lookup discovery service. This ID is used to
- * determine equality between proxies.
- *
- * @serial
- */
- final Uuid proxyID;
-
- /**
- * Public static factory method that creates and returns an instance of
- * <code>FiddlerProxy</code>. If the server associated with this proxy
- * implements <code>RemoteMethodControl</code>, then the object returned by
- * this method will also implement <code>RemoteMethodControl</code>.
- *
- * @param server reference to the server object through which
- * communication occurs between the client-side and
- * server-side of the associated service.
- * @param proxyID the unique identifier assigned by the service to each
- * instance of this proxy
- *
- * @return an instance of <code>FiddlerProxy</code> that implements
- * <code>RemoteMethodControl</code> if the given <code>server</code>
- * does.
- */
- public static FiddlerProxy createServiceProxy(Fiddler server,
- Uuid proxyID)
- {
- if(server instanceof RemoteMethodControl) {
- return new ConstrainableFiddlerProxy(server, proxyID, null);
- } else {
- return new FiddlerProxy(server, proxyID);
- }//endif
- }//end createServiceProxy
-
- /**
- * Constructs a new instance of FiddlerProxy.
- *
- * @param server reference to the server object through which
- * communication occurs between the client-side and
- * server-side of the associated service
- * @param proxyID the unique identifier assigned by the service to each
- * instance of this proxy
- */
- private FiddlerProxy(Fiddler server, Uuid proxyID) {
- this.server = server;
- this.proxyID = proxyID;
- }//end constructor
-
- /* From net.jini.admin.Administrable */
- /**
- * Returns a proxy object through which the lookup discovery service
- * for which the object on which this method is invoked serves as
- * proxy may be administered
- *
- * @return a proxy object through which the lookup discovery service
- * may be administered.
- *
- * @throws java.rmi.RemoteException typically, this exception occurs when
- * there is a communication failure between the client and the
- * server.
- *
- * @see net.jini.admin.Administrable
- */
- public Object getAdmin() throws RemoteException {
- return server.getAdmin();
- }
-
- /* From net.jini.discovery.LookupDiscoveryService */
- /**
- * Registers with the lookup discovery service. When a client invokes
- * this method, it requests that the lookup discovery service perform
- * discovery processing on its behalf.
- *
- * @param groups String array, none of whose elements may be null,
- * consisting of zero or more names of groups to
- * which lookup services to discover belong.
- * A null value or an empty array
- * (net.jini.discovery.LookupDiscovery.ALL_GROUPS
- * or net.jini.discovery.LookupDiscovery.NO_GROUPS)
- * are both acceptable.
- *
- * @param locators array of zero or more non-null LookupLocator
- * objects, each corresponding to a specific lookup
- * service to discover. If either the empty array
- * or null is passed to this argument, then no
- * locator discovery will be performed for the
- * associated registration.
- *
- * @param listener a non-null instance of RemoteEventListener. This
- * argument specifies the entity that will receive
- * events notifying the registration that a lookup
- * service of interest has been discovered. A
- * non-null value must be passed to this argument,
- * otherwise a NullPointerException will be thrown
- * and the registration.
- *
- * @param handback null or an instance of MarshalledObject. This
- * argument specifies an object that will be
- * included in the notification event that the
- * lookup discovery service sends to the registered
- * listener.
- *
- * @param leaseDuration long value representing the amount of time (in
- * milliseconds) for which the resources of the
- * lookup discovery service are being requested.
- *
- * @return an instance of the LookupDiscoveryRegistration interface.
- *
- * @throws java.rmi.RemoteException typically, this exception occurs when
- * there is a communication failure between the client and the
- * server. When this exception does occur, the registration may
- * or may not have completed successfully.
- *
- * @throws java.lang.NullPointerException this exception occurs when
- * null is input to the listener parameter.
- *
- * @see net.jini.discovery.LookupDiscoveryService
- */
- public LookupDiscoveryRegistration register(String[] groups,
- LookupLocator[] locators,
- RemoteEventListener listener,
- MarshalledObject handback,
- long leaseDuration)
- throws RemoteException
- {
- return server.register(groups,
- locators,
- listener,
- handback,
- leaseDuration);
- }
-
- /* From net.jini.id.ReferentUuid */
- /**
- * Returns the universally unique identifier that has been assigned to the
- * resource this proxy represents.
- *
- * @return the instance of <code>Uuid</code> that is associated with the
- * resource this proxy represents. This method will not return
- * <code>null</code>.
- *
- * @see net.jini.id.ReferentUuid
- */
- public Uuid getReferentUuid() {
- return proxyID;
- }
-
- /**
- * For any instance of this class, returns the hashcode value generated
- * by the hashCode method of the proxy ID associated with the current
- * instance of this proxy.
- *
- * @return <code>int</code> value representing the hashcode for an
- * instance of this class.
- */
- public int hashCode() {
- return proxyID.hashCode();
- }
-
- /**
- * For any instance of this class, indicates whether the object input
- * to this method is equal to the current instance of this class; where
- * equality of proxies to a lookup discovery service is defined by
- * reference equality. That is, two proxies are equal if they reference
- * (are proxies to) the same backend server.
- *
- * @param obj reference to the object that is to be compared to the
- * object on which this method is invoked.
- *
- * @return <code>true</code> if the object input is referentially
- * equal to the object on which this method is invoked;
- * <code>false</code> otherwise.
- */
- public boolean equals(Object obj) {
- return ReferentUuids.compare(this,obj);
- }
-
- /** When an instance of this class is deserialized, this method is
- * automatically invoked. This implementation of this method validates
- * the state of the deserialized instance.
- *
- * @throws <code>InvalidObjectException</code> if the state of the
- * deserialized instance of this class is found to be invalid.
- */
- private void readObject(ObjectInputStream s)
- throws IOException, ClassNotFoundException
- {
- s.defaultReadObject();
- /* Verify server */
- if(server == null) {
- throw new InvalidObjectException("FiddlerProxy.readObject "
- +"failure - server "
- +"field is null");
- }//endif
- /* Verify proxyID */
- if(proxyID == null) {
- throw new InvalidObjectException("FiddlerProxy.readObject "
- +"failure - proxyID "
- +"field is null");
- }//endif
- }//end readObject
-
- /** During deserialization of an instance of this class, if it is found
- * that the stream contains no data, this method is automatically
- * invoked. Because it is expected that the stream should always
- * contain data, this implementation of this method simply declares
- * that something must be wrong.
- *
- * @throws <code>InvalidObjectException</code> to indicate that there
- * was no data in the stream during deserialization of an
- * instance of this class; declaring that something is wrong.
- */
- private void readObjectNoData() throws InvalidObjectException {
- throw new InvalidObjectException("no data found when attempting to "
- +"deserialize FiddlerProxy instance");
- }//end readObjectNoData
-
- /** The constrainable version of the class <code>FiddlerProxy</code>.
- * <p>
- * When a client obtains an instance of this proxy class, the client
- * should not attempt to use the proxy until the client is assured
- * that the proxy can be trusted. In addition to implementing the
- * methods and mechanisms required by <code>RemoteMethodControl</code>,
- * this class - in conjunction with the service's
- * <code>ProxyVerifier</code> class, helps provide a mechanism
- * for verifying trust in the proxy on behalf of a client.
- * <p>
- * In order to verify that an instance of this class is trusted,
- * trust must be verified in all subsidiary objects (contained in that
- * instance) through which the client ultimately makes calls (local or
- * remote). With respect to this class, the <code>server</code> field
- * is a proxy object through which the client makes remote calls to the
- * service's backend. Therefore, trust in that object must be
- * verified. Additionally, this class also contains a field of type
- * <code>Uuid</code> (<code>proxyID</code> which should be
- * tested for trust. Consider the following diagram:
- * <p>
- * <pre>
- * FiddlerProxy {
- * Fiddler server
- * Uuid proxyID
- * }//end FiddlerProxy
- * </pre>
- * <p>
- * Thus, in order to verify that an instance of this class is trusted,
- * trust must be verified in the following objects from the diagram
- * above:
- * <ul><li> server
- * <li> proxyID
- * </ul>
- *
- * When a client obtains an instance of this proxy class, the
- * deserialization process which delivers the proxy to the client
- * invokes the <code>readObject</code> method of this class. Part of
- * trust verification is performed in the <code>readObject</code> method,
- * and part is performed when the client prepares the proxy. Thus, this
- * class' participation in the trust verification process can be
- * summarized as follows:
- * <p>
- * <ul>
- * <li> server
- * <ul>
- * <li> readObject
- * <ul>
- * <li> verify server != null
- * <li> verify server implements RemoteMethodControl
- * <li> verify server's method constraints are the same
- * as those placed on the corresponding public Remote
- * methods of its outer proxy class
- * </ul>
- * <li> proxy preparation
- * <ul>
- * <li> Security.verifyObjectTrust() which calls
- * <li> ProxyVerifier.isTrustedObject() which calls
- * <li> canonicalServerObject.checkTrustEquivalence(server)
- * (whose implementation is supplied by the particular
- * RMI implementation that was used to export the server)
- * </ul>
- * </ul>
- * <li> proxyID
- * <ul><li> readObject
- * <ul><li> verify proxyID != null</ul>
- * </ul>
- * </ul>
- *
- * @since 2.0
- */
- static final class ConstrainableFiddlerProxy extends FiddlerProxy
- implements RemoteMethodControl
- {
- static final long serialVersionUID = 2L;
-
- /* Array containing element pairs in which each pair of elements
- * represents a correspondence 'mapping' between two methods having
- * the following characteristics:
- * - the first element in the pair is one of the public, remote
- * method(s) that may be invoked by the client through the proxy
- * class that this class extends
- * - the second element in the pair is the method, implemented
- * in the backend server class, that is ultimately executed in
- * the server's backend when the client invokes the corresponding
- * method in this proxy
- */
- private static final Method[] methodMapArray =
- {
- ProxyUtil.getMethod(Administrable.class,
- "getAdmin", new Class[] {} ),
- ProxyUtil.getMethod(Administrable.class,
- "getAdmin", new Class[] {} ),
-
- ProxyUtil.getMethod(LookupDiscoveryService.class,
- "register",
- new Class[] {String[].class,
- LookupLocator[].class,
- RemoteEventListener.class,
- MarshalledObject.class,
- long.class} ),
- ProxyUtil.getMethod(Fiddler.class,
- "register",
- new Class[] {String[].class,
- LookupLocator[].class,
- RemoteEventListener.class,
- MarshalledObject.class,
- long.class} )
- };//end methodMapArray
-
- /** Client constraints placed on this proxy (may be <code>null</code>).
- *
- * @serial
- */
- private MethodConstraints methodConstraints;
-
- /** Constructs a new <code>ConstrainableFiddlerProxy</code> instance.
- * <p>
- * For a description of all but the <code>methodConstraints</code>
- * argument (provided below), refer to the description for the
- * constructor of this class' super class.
- *
- * @param methodConstraints the client method constraints to place on
- * this proxy (may be <code>null</code>).
- */
- private ConstrainableFiddlerProxy(Fiddler server,
- Uuid proxyID,
- MethodConstraints methodConstraints)
- {
- super( constrainServer(server, methodConstraints), proxyID);
- this.methodConstraints = methodConstraints;
- }//end constructor
-
- /** Returns a copy of the given server proxy having the client method
- * constraints that result after the specified method mapping is
- * applied to the given client method constraints.
- */
- private static Fiddler constrainServer( Fiddler server,
- MethodConstraints constraints )
- {
- MethodConstraints newConstraints
- = ConstrainableProxyUtil.translateConstraints(constraints,
- methodMapArray);
- RemoteMethodControl constrainedServer =
- ((RemoteMethodControl)server).setConstraints(newConstraints);
-
- return ((Fiddler)constrainedServer);
- }//end constrainServer
-
- /** Returns a new copy of this proxy class
- * (<code>ConstrainableFiddlerProxy</code>) with its client
- * constraints set to the specified constraints. A <code>null</code>
- * value is interpreted as mapping all methods to empty constraints.
- */
- public RemoteMethodControl setConstraints
- (MethodConstraints constraints)
- {
- return ( new ConstrainableFiddlerProxy
- (server, proxyID, constraints) );
- }//end setConstraints
-
- /** Returns the client constraints placed on the current instance
- * of this proxy class (<code>ConstrainableFiddlerProxy</code>).
- * The value returned by this method can be <code>null</code>,
- * which is interpreted as mapping all methods to empty constraints.
- */
- public MethodConstraints getConstraints() {
- return methodConstraints;
- }//end getConstraints
-
- /** Returns a proxy trust iterator that is used in
- * <code>ProxyTrustVerifier</code> to retrieve this object's
- * trust verifier.
- */
- private ProxyTrustIterator getProxyTrustIterator() {
- return new SingletonProxyTrustIterator(server);
- }//end getProxyTrustIterator
-
- /** Performs various functions related to the trust verification
- * process for the current instance of this proxy class, as
- * detailed in the description for this class.
- *
- * @throws <code>InvalidObjectException</code> if any of the
- * requirements for trust verification (as detailed in the
- * class description) are not satisfied.
- */
- private void readObject(ObjectInputStream s)
- throws IOException, ClassNotFoundException
- {
- /* Note that basic validation of the fields of this class was
- * already performed in the readObject() method of this class'
- * super class.
- */
- s.defaultReadObject();
- /* Verify the server and its constraints */
- ConstrainableProxyUtil.verifyConsistentConstraints
- (methodConstraints,
- server,
- methodMapArray);
- }//end readObject
-
- }//end class ConstrainableFiddlerProxy
-
-}//end class FiddlerProxy
+/*
+ * 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 org.apache.river.fiddler.proxy;
+
+import org.apache.river.proxy.ConstrainableProxyUtil;
+
+import net.jini.admin.Administrable;
+import net.jini.discovery.LookupDiscoveryService;
+import net.jini.discovery.LookupDiscoveryRegistration;
+import net.jini.id.ReferentUuid;
+import net.jini.id.ReferentUuids;
+import net.jini.id.Uuid;
+import net.jini.security.proxytrust.ProxyTrustIterator;
+import net.jini.security.proxytrust.SingletonProxyTrustIterator;
+
+import net.jini.core.constraint.MethodConstraints;
+import net.jini.core.constraint.RemoteMethodControl;
+import net.jini.core.discovery.LookupLocator;
+import net.jini.core.event.RemoteEventListener;
+
+import java.lang.reflect.Method;
+import java.io.InvalidObjectException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
+import java.rmi.RemoteException;
+import java.rmi.MarshalledObject;
+
+/**
+ * This class is a proxy for a lookup discovery service. Clients only see
+ * instances of this class via the LookupDiscoveryService interface (and
+ * the FiddlerAdmin interface if needed).
+ *
+ * @author Sun Microsystems, Inc.
+ *
+ */
+public class FiddlerProxy implements Administrable, LookupDiscoveryService,
+ ReferentUuid, Serializable
+{
+ private static final long serialVersionUID = 2L;
+ /**
+ * The reference through which communication occurs between the
+ * client-side and the server-side of the lookup discovery service
+ *
+ * @serial
+ */
+ final Fiddler server;
+ /**
+ * The unique identifier assigned to the current instance of this
+ * proxy class by the lookup discovery service. This ID is used to
+ * determine equality between proxies.
+ *
+ * @serial
+ */
+ final Uuid proxyID;
+
+ /**
+ * Public static factory method that creates and returns an instance of
+ * <code>FiddlerProxy</code>. If the server associated with this proxy
+ * implements <code>RemoteMethodControl</code>, then the object returned by
+ * this method will also implement <code>RemoteMethodControl</code>.
+ *
+ * @param server reference to the server object through which
+ * communication occurs between the client-side and
+ * server-side of the associated service.
+ * @param proxyID the unique identifier assigned by the service to each
+ * instance of this proxy
+ *
+ * @return an instance of <code>FiddlerProxy</code> that implements
+ * <code>RemoteMethodControl</code> if the given <code>server</code>
+ * does.
+ */
+ public static FiddlerProxy createServiceProxy(Fiddler server,
+ Uuid proxyID)
+ {
+ if(server instanceof RemoteMethodControl) {
+ return new ConstrainableFiddlerProxy(server, proxyID, null);
+ } else {
+ return new FiddlerProxy(server, proxyID);
+ }//endif
+ }//end createServiceProxy
+
+ /**
+ * Constructs a new instance of FiddlerProxy.
+ *
+ * @param server reference to the server object through which
+ * communication occurs between the client-side and
+ * server-side of the associated service
+ * @param proxyID the unique identifier assigned by the service to each
+ * instance of this proxy
+ */
+ private FiddlerProxy(Fiddler server, Uuid proxyID) {
+ this.server = server;
+ this.proxyID = proxyID;
+ }//end constructor
+
+ /* From net.jini.admin.Administrable */
+ /**
+ * Returns a proxy object through which the lookup discovery service
+ * for which the object on which this method is invoked serves as
+ * proxy may be administered
+ *
+ * @return a proxy object through which the lookup discovery service
+ * may be administered.
+ *
+ * @throws java.rmi.RemoteException typically, this exception occurs when
+ * there is a communication failure between the client and the
+ * server.
+ *
+ * @see net.jini.admin.Administrable
+ */
+ public Object getAdmin() throws RemoteException {
+ return server.getAdmin();
+ }
+
+ /* From net.jini.discovery.LookupDiscoveryService */
+ /**
+ * Registers with the lookup discovery service. When a client invokes
+ * this method, it requests that the lookup discovery service perform
+ * discovery processing on its behalf.
+ *
+ * @param groups String array, none of whose elements may be null,
+ * consisting of zero or more names of groups to
+ * which lookup services to discover belong.
+ * A null value or an empty array
+ * (net.jini.discovery.LookupDiscovery.ALL_GROUPS
+ * or net.jini.discovery.LookupDiscovery.NO_GROUPS)
+ * are both acceptable.
+ *
+ * @param locators array of zero or more non-null LookupLocator
+ * objects, each corresponding to a specific lookup
+ * service to discover. If either the empty array
+ * or null is passed to this argument, then no
+ * locator discovery will be performed for the
+ * associated registration.
+ *
+ * @param listener a non-null instance of RemoteEventListener. This
+ * argument specifies the entity that will receive
+ * events notifying the registration that a lookup
+ * service of interest has been discovered. A
+ * non-null value must be passed to this argument,
+ * otherwise a NullPointerException will be thrown
+ * and the registration.
+ *
+ * @param handback null or an instance of MarshalledObject. This
+ * argument specifies an object that will be
+ * included in the notification event that the
+ * lookup discovery service sends to the registered
+ * listener.
+ *
+ * @param leaseDuration long value representing the amount of time (in
+ * milliseconds) for which the resources of the
+ * lookup discovery service are being requested.
+ *
+ * @return an instance of the LookupDiscoveryRegistration interface.
+ *
+ * @throws java.rmi.RemoteException typically, this exception occurs when
+ * there is a communication failure between the client and the
+ * server. When this exception does occur, the registration may
+ * or may not have completed successfully.
+ *
+ * @throws java.lang.NullPointerException this exception occurs when
+ * null is input to the listener parameter.
+ *
+ * @see net.jini.discovery.LookupDiscoveryService
+ */
+ public LookupDiscoveryRegistration register(String[] groups,
+ LookupLocator[] locators,
+ RemoteEventListener listener,
+ MarshalledObject handback,
+ long leaseDuration)
+ throws RemoteException
+ {
+ return server.register(groups,
+ locators,
+ listener,
+ handback,
+ leaseDuration);
+ }
+
+ /* From net.jini.id.ReferentUuid */
+ /**
+ * Returns the universally unique identifier that has been assigned to the
+ * resource this proxy represents.
+ *
+ * @return the instance of <code>Uuid</code> that is associated with the
+ * resource this proxy represents. This method will not return
+ * <code>null</code>.
+ *
+ * @see net.jini.id.ReferentUuid
+ */
+ public Uuid getReferentUuid() {
+ return proxyID;
+ }
+
+ /**
+ * For any instance of this class, returns the hashcode value generated
+ * by the hashCode method of the proxy ID associated with the current
+ * instance of this proxy.
+ *
+ * @return <code>int</code> value representing the hashcode for an
+ * instance of this class.
+ */
+ public int hashCode() {
+ return proxyID.hashCode();
+ }
+
+ /**
+ * For any instance of this class, indicates whether the object input
+ * to this method is equal to the current instance of this class; where
+ * equality of proxies to a lookup discovery service is defined by
+ * reference equality. That is, two proxies are equal if they reference
+ * (are proxies to) the same backend server.
+ *
+ * @param obj reference to the object that is to be compared to the
+ * object on which this method is invoked.
+ *
+ * @return <code>true</code> if the object input is referentially
+ * equal to the object on which this method is invoked;
+ * <code>false</code> otherwise.
+ */
+ public boolean equals(Object obj) {
+ return ReferentUuids.compare(this,obj);
+ }
+
+ /** When an instance of this class is deserialized, this method is
+ * automatically invoked. This implementation of this method validates
+ * the state of the deserialized instance.
+ *
+ * @throws <code>InvalidObjectException</code> if the state of the
+ * deserialized instance of this class is found to be invalid.
+ */
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException
+ {
+ s.defaultReadObject();
+ /* Verify server */
+ if(server == null) {
+ throw new InvalidObjectException("FiddlerProxy.readObject "
+ +"failure - server "
+ +"field is null");
+ }//endif
+ /* Verify proxyID */
+ if(proxyID == null) {
+ throw new InvalidObjectException("FiddlerProxy.readObject "
+ +"failure - proxyID "
+ +"field is null");
+ }//endif
+ }//end readObject
+
+ /** During deserialization of an instance of this class, if it is found
+ * that the stream contains no data, this method is automatically
+ * invoked. Because it is expected that the stream should always
+ * contain data, this implementation of this method simply declares
+ * that something must be wrong.
+ *
+ * @throws <code>InvalidObjectException</code> to indicate that there
+ * was no data in the stream during deserialization of an
+ * instance of this class; declaring that something is wrong.
+ */
+ private void readObjectNoData() throws InvalidObjectException {
+ throw new InvalidObjectException("no data found when attempting to "
+ +"deserialize FiddlerProxy instance");
+ }//end readObjectNoData
+
+ /** The constrainable version of the class <code>FiddlerProxy</code>.
+ * <p>
+ * When a client obtains an instance of this proxy class, the client
+ * should not attempt to use the proxy until the client is assured
+ * that the proxy can be trusted. In addition to implementing the
+ * methods and mechanisms required by <code>RemoteMethodControl</code>,
+ * this class - in conjunction with the service's
+ * <code>ProxyVerifier</code> class, helps provide a mechanism
+ * for verifying trust in the proxy on behalf of a client.
+ * <p>
+ * In order to verify that an instance of this class is trusted,
+ * trust must be verified in all subsidiary objects (contained in that
+ * instance) through which the client ultimately makes calls (local or
+ * remote). With respect to this class, the <code>server</code> field
+ * is a proxy object through which the client makes remote calls to the
+ * service's backend. Therefore, trust in that object must be
+ * verified. Additionally, this class also contains a field of type
+ * <code>Uuid</code> (<code>proxyID</code> which should be
+ * tested for trust. Consider the following diagram:
+ * <p>
+ * <pre>
+ * FiddlerProxy {
+ * Fiddler server
+ * Uuid proxyID
+ * }//end FiddlerProxy
+ * </pre>
+ * <p>
+ * Thus, in order to verify that an instance of this class is trusted,
+ * trust must be verified in the following objects from the diagram
+ * above:
+ * <ul><li> server
+ * <li> proxyID
+ * </ul>
+ *
+ * When a client obtains an instance of this proxy class, the
+ * deserialization process which delivers the proxy to the client
+ * invokes the <code>readObject</code> method of this class. Part of
+ * trust verification is performed in the <code>readObject</code> method,
+ * and part is performed when the client prepares the proxy. Thus, this
+ * class' participation in the trust verification process can be
+ * summarized as follows:
+ * <p>
+ * <ul>
+ * <li> server
+ * <ul>
+ * <li> readObject
+ * <ul>
+ * <li> verify server != null
+ * <li> verify server implements RemoteMethodControl
+ * <li> verify server's method constraints are the same
+ * as those placed on the corresponding public Remote
+ * methods of its outer proxy class
+ * </ul>
+ * <li> proxy preparation
+ * <ul>
+ * <li> Security.verifyObjectTrust() which calls
+ * <li> ProxyVerifier.isTrustedObject() which calls
+ * <li> canonicalServerObject.checkTrustEquivalence(server)
+ * (whose implementation is supplied by the particular
+ * RMI implementation that was used to export the server)
+ * </ul>
+ * </ul>
+ * <li> proxyID
+ * <ul><li> readObject
+ * <ul><li> verify proxyID != null</ul>
+ * </ul>
+ * </ul>
+ *
+ * @since 2.0
+ */
+ static final class ConstrainableFiddlerProxy extends FiddlerProxy
+ implements RemoteMethodControl
+ {
+ static final long serialVersionUID = 2L;
+
+ /* Array containing element pairs in which each pair of elements
+ * represents a correspondence 'mapping' between two methods having
+ * the following characteristics:
+ * - the first element in the pair is one of the public, remote
+ * method(s) that may be invoked by the client through the proxy
+ * class that this class extends
+ * - the second element in the pair is the method, implemented
+ * in the backend server class, that is ultimately executed in
+ * the server's backend when the client invokes the corresponding
+ * method in this proxy
+ */
+ private static final Method[] methodMapArray =
+ {
+ ProxyUtil.getMethod(Administrable.class,
+ "getAdmin", new Class[] {} ),
+ ProxyUtil.getMethod(Administrable.class,
+ "getAdmin", new Class[] {} ),
+
+ ProxyUtil.getMethod(LookupDiscoveryService.class,
+ "register",
+ new Class[] {String[].class,
+ LookupLocator[].class,
+ RemoteEventListener.class,
+ MarshalledObject.class,
+ long.class} ),
+ ProxyUtil.getMethod(Fiddler.class,
+ "register",
+ new Class[] {String[].class,
+ LookupLocator[].class,
+ RemoteEventListener.class,
+ MarshalledObject.class,
+ long.class} )
+ };//end methodMapArray
+
+ /** Client constraints placed on this proxy (may be <code>null</code>).
+ *
+ * @serial
+ */
+ private MethodConstraints methodConstraints;
+
+ /** Constructs a new <code>ConstrainableFiddlerProxy</code> instance.
+ * <p>
+ * For a description of all but the <code>methodConstraints</code>
+ * argument (provided below), refer to the description for the
+ * constructor of this class' super class.
+ *
+ * @param methodConstraints the client method constraints to place on
+ * this proxy (may be <code>null</code>).
+ */
+ private ConstrainableFiddlerProxy(Fiddler server,
+ Uuid proxyID,
+ MethodConstraints methodConstraints)
+ {
+ super( constrainServer(server, methodConstraints), proxyID);
+ this.methodConstraints = methodConstraints;
+ }//end constructor
+
+ /** Returns a copy of the given server proxy having the client method
+ * constraints that result after the specified method mapping is
+ * applied to the given client method constraints.
+ */
+ private static Fiddler constrainServer( Fiddler server,
+ MethodConstraints constraints )
+ {
+ MethodConstraints newConstraints
+ = ConstrainableProxyUtil.translateConstraints(constraints,
+ methodMapArray);
+ RemoteMethodControl constrainedServer =
+ ((RemoteMethodControl)server).setConstraints(newConstraints);
+
+ return ((Fiddler)constrainedServer);
+ }//end constrainServer
+
+ /** Returns a new copy of this proxy class
+ * (<code>ConstrainableFiddlerProxy</code>) with its client
+ * constraints set to the specified constraints. A <code>null</code>
+ * value is interpreted as mapping all methods to empty constraints.
+ */
+ public RemoteMethodControl setConstraints
+ (MethodConstraints constraints)
+ {
+ return ( new ConstrainableFiddlerProxy
+ (server, proxyID, constraints) );
+ }//end setConstraints
+
+ /** Returns the client constraints placed on the current instance
+ * of this proxy class (<code>ConstrainableFiddlerProxy</code>).
+ * The value returned by this method can be <code>null</code>,
+ * which is interpreted as mapping all methods to empty constraints.
+ */
+ public MethodConstraints getConstraints() {
+ return methodConstraints;
+ }//end getConstraints
+
+ /** Returns a proxy trust iterator that is used in
+ * <code>ProxyTrustVerifier</code> to retrieve this object's
+ * trust verifier.
+ */
+ private ProxyTrustIterator getProxyTrustIterator() {
+ return new SingletonProxyTrustIterator(server);
+ }//end getProxyTrustIterator
+
+ /** Performs various functions related to the trust verification
+ * process for the current instance of this proxy class, as
+ * detailed in the description for this class.
+ *
+ * @throws <code>InvalidObjectException</code> if any of the
+ * requirements for trust verification (as detailed in the
+ * class description) are not satisfied.
+ */
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException
+ {
+ /* Note that basic validation of the fields of this class was
+ * already performed in the readObject() method of this class'
+ * super class.
+ */
+ s.defaultReadObject();
+ /* Verify the server and its constraints */
+ ConstrainableProxyUtil.verifyConsistentConstraints
+ (methodConstraints,
+ server,
+ methodMapArray);
+ }//end readObject
+
+ }//end class ConstrainableFiddlerProxy
+
+}//end class FiddlerProxy