Modified: river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/SnapshotRep.java URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/SnapshotRep.java?rev=1879521&r1=1879520&r2=1879521&view=diff ============================================================================== --- river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/SnapshotRep.java (original) +++ river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/SnapshotRep.java Sun Jul 5 11:41:39 2020 @@ -1,97 +1,97 @@ -/* - * 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.outrigger; - -import java.rmi.MarshalException; -import net.jini.core.entry.Entry; - -/** - * This class is used by the <code>snapshot</code> implementation of the - * proxy to create a <code>snapshot</code>. Here's what the JavaSpaces - * specification says about <code>snapshot</code>. - * - * The process of serializing an entry for transmission to a JavaSpaces - * service will be identical if the same entry is used twice. This is most - * likely to be an issue with templates that are used repeatedly to search - * for entries with <code>read</code> or <code>take</code>. The client-side - * implementations of <code>read</code> and <code>take</code> cannot - * reasonably avoid this duplicated effort, since they have no efficient - * way of checking whether the same template is being used without - * intervening modification. - * - * The <code>snapshot</code> method gives the JavaSpaces service implementor - * a way to reduce the impact of repeated use of the same entry. Invoking - * <code>snapshot</code> with an <code>Entry</code> will return another - * <code>Entry</code> object that contains a <i>snapshot</i> of the - * original entry. Using the returned snapshot entry is equivalent to - * using the unmodified original entry in all operations on the same - * JavaSpaces service. Modifications to the original entry will not - * affect the snapshot. You can <code>snapshot</code> a <code>null</code> - * template; <code>snapshot</code> may or may not return null given a - * <code>null</code> template. - * - * The entry returned from <code>snapshot</code> will be guaranteed - * equivalent to the original unmodified object only when used with - * the space. Using the snapshot with any other JavaSpaces service - * will generate an <code>IllegalArgumentException</code> unless the - * other space can use it because of knowledge about the JavaSpaces - * service that generated the snapshot. The snapshot will be a different - * object from the original, may or may not have the same hash code, - * and <code>equals</code> may or may not return <code>true</code> - * when invoked with the original object, even if the original - * object is unmodified. - * - * A snapshot is guaranteed to work only within the virtual machine - * in which it was generated. If a snapshot is passed to another - * virtual machine (for example, in a parameter of an RMI call), - * using it--even with the same JavaSpaces service--may generate - * an <code>IllegalArgumentException</code>. - * - * For more information, please review the appropriate specifications. - * - * @author Sun Microsystems, Inc. - * - */ -// @see SpaceProxy#snapshot -class SnapshotRep implements Entry { - static final long serialVersionUID = 5126328162389368097L; - - private final EntryRep rep; // the rep from the snapshot - - /** - * Create a new <code>SnapshotRep</code> that is a snapshot of - * <code>e</code>. - */ - SnapshotRep(Entry e) throws MarshalException { - rep = new EntryRep(e); - } - - /** - * Construct an SnapshotRep from an existing EntryRep - */ - SnapshotRep(EntryRep e) { - rep = e; - } - - /** - * Return the pre-computed <code>EntryRep</code>. - */ - EntryRep rep() { - return rep; - } -} +/* + * 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.outrigger.proxy; + +import java.rmi.MarshalException; +import net.jini.core.entry.Entry; + +/** + * This class is used by the <code>snapshot</code> implementation of the + * proxy to create a <code>snapshot</code>. Here's what the JavaSpaces + * specification says about <code>snapshot</code>. + * + * The process of serializing an entry for transmission to a JavaSpaces + * service will be identical if the same entry is used twice. This is most + * likely to be an issue with templates that are used repeatedly to search + * for entries with <code>read</code> or <code>take</code>. The client-side + * implementations of <code>read</code> and <code>take</code> cannot + * reasonably avoid this duplicated effort, since they have no efficient + * way of checking whether the same template is being used without + * intervening modification. + * + * The <code>snapshot</code> method gives the JavaSpaces service implementor + * a way to reduce the impact of repeated use of the same entry. Invoking + * <code>snapshot</code> with an <code>Entry</code> will return another + * <code>Entry</code> object that contains a <i>snapshot</i> of the + * original entry. Using the returned snapshot entry is equivalent to + * using the unmodified original entry in all operations on the same + * JavaSpaces service. Modifications to the original entry will not + * affect the snapshot. You can <code>snapshot</code> a <code>null</code> + * template; <code>snapshot</code> may or may not return null given a + * <code>null</code> template. + * + * The entry returned from <code>snapshot</code> will be guaranteed + * equivalent to the original unmodified object only when used with + * the space. Using the snapshot with any other JavaSpaces service + * will generate an <code>IllegalArgumentException</code> unless the + * other space can use it because of knowledge about the JavaSpaces + * service that generated the snapshot. The snapshot will be a different + * object from the original, may or may not have the same hash code, + * and <code>equals</code> may or may not return <code>true</code> + * when invoked with the original object, even if the original + * object is unmodified. + * + * A snapshot is guaranteed to work only within the virtual machine + * in which it was generated. If a snapshot is passed to another + * virtual machine (for example, in a parameter of an RMI call), + * using it--even with the same JavaSpaces service--may generate + * an <code>IllegalArgumentException</code>. + * + * For more information, please review the appropriate specifications. + * + * @author Sun Microsystems, Inc. + * + */ +// @see SpaceProxy#snapshot +class SnapshotRep implements Entry { + static final long serialVersionUID = 5126328162389368097L; + + private final EntryRep rep; // the rep from the snapshot + + /** + * Create a new <code>SnapshotRep</code> that is a snapshot of + * <code>e</code>. + */ + SnapshotRep(Entry e) throws MarshalException { + rep = new EntryRep(e); + } + + /** + * Construct an SnapshotRep from an existing EntryRep + */ + SnapshotRep(EntryRep e) { + rep = e; + } + + /** + * Return the pre-computed <code>EntryRep</code>. + */ + EntryRep rep() { + return rep; + } +}
Modified: river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/SpaceProxy2.java URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/SpaceProxy2.java?rev=1879521&r1=1879520&r2=1879521&view=diff ============================================================================== --- river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/SpaceProxy2.java (original) +++ river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/SpaceProxy2.java Sun Jul 5 11:41:39 2020 @@ -1,764 +1,764 @@ -/* - * 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.outrigger; - -import java.io.ObjectInputStream; -import java.io.Serializable; -import java.io.IOException; -import java.io.InvalidObjectException; -import java.rmi.MarshalledObject; -import java.rmi.RemoteException; -import java.rmi.MarshalException; -import java.security.PrivilegedAction; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.Iterator; -import java.util.logging.Level; -import java.util.logging.Logger; - -import net.jini.admin.Administrable; -import net.jini.core.entry.Entry; -import net.jini.core.entry.UnusableEntryException; -import net.jini.core.event.EventRegistration; -import net.jini.core.event.RemoteEventListener; -import net.jini.core.lease.Lease; -import net.jini.core.transaction.Transaction; -import net.jini.core.transaction.TransactionException; -import net.jini.entry.UnusableEntriesException; -import net.jini.space.JavaSpace05; -import net.jini.space.MatchSet; - -import net.jini.id.Uuid; -import net.jini.id.UuidFactory; -import net.jini.id.ReferentUuid; -import net.jini.id.ReferentUuids; -import net.jini.security.Security; - -import org.apache.river.landlord.LandlordLease; - -/** - * This class is the client-side proxy for the Outrigger - * implementation of a JavaSpaces<sup><font size=-2>TM</font></sup> - * service. <code>OutriggerServerImpl</code> implements the - * <code>OutriggerSpace</code> interface, and each - * <code>SpaceProxy2</code> object holds a reference to the remote - * OutriggerSpace server it represents to the client. The client makes - * calls from the <code>JavaSpace</code> interface, which the - * <code>SpaceProxy2</code> translates into appropriate - * <code>OutriggerSpace</code> calls to the - * <code>OutriggerServerImpl</code> server. - * - * @author Sun Microsystems, Inc. - * - */ -// @see OutriggerSpace -class SpaceProxy2 implements JavaSpace05, Administrable, ReferentUuid, - Serializable -{ - static final long serialVersionUID = 1L; - - /** - * The remote server this proxy works with. - * Package protected so it can be read by subclasses and proxy verifier - * @serial - */ - final OutriggerServer space; - - /** - * The <code>Uuid</code> that identifies the space this proxy is for. - * Package protected so it can be read by subclasses and proxy verifier - * @serial - */ - final Uuid spaceUuid; - - /** - * The value to use for maxServerQueryTimeout if no - * local value is provided. Package protected so it can be read by - * subclasses. - * @serial - */ - final long serverMaxServerQueryTimeout; - - /** - * Maximum time any sub-query should be allowed to run for. - */ - private transient volatile long maxServerQueryTimeout; - - - /** - * Value (as a long) of the - * <code>org.apache.river.outrigger.maxServerQueryTimeout</code> - * property in this VM, or a non-positive number if it is not set. - */ - private static final long maxServerQueryTimeoutPropertyValue = - getMaxServerQueryTimeoutPropertyValue(); - - /** - * Logger for logging information about operations carried out in - * the client. Note, we hard code "org.apache.river.outrigger" so - * we don't drag in OutriggerServerImpl to outrigger-dl.jar. - */ - private static final Logger logger = - Logger.getLogger("org.apache.river.outrigger.proxy"); - - // -------------------------------------------------- - // Construction - // -------------------------------------------------- - - /** - * Create a new <code>SpaceProxy2</code> for the given space. - * @param space The <code>OutriggerServer</code> for the - * space. - * @param spaceUuid The universally unique ID for the - * space - * @param serverMaxServerQueryTimeout The value this proxy - * should use for the <code>maxServerQueryTimeout</code> - * if no local value is provided. - * @throws NullPointerException if <code>space</code> or - * <code>spaceUuid</code> is <code>null</code>. - * @throws IllegalArgumentException if - * <code>serverMaxServerQueryTimeout</code> is not - * larger than zero. - */ - SpaceProxy2(OutriggerServer space, Uuid spaceUuid, - long serverMaxServerQueryTimeout) - { - if (space == null) - throw new NullPointerException("space must be non-null"); - if (spaceUuid == null) - throw new NullPointerException("spaceUuid must be non-null"); - if (serverMaxServerQueryTimeout <= 0) - throw new - IllegalArgumentException("serverMaxServerQueryTimeout " + - "must be positive"); - this.space = space; - this.spaceUuid = spaceUuid; - this.serverMaxServerQueryTimeout = serverMaxServerQueryTimeout; - setMaxServerQueryTimeout(); - } - - public String toString() { - return getClass().getName() + " for " + spaceUuid + - " (through " + space + ")"; - } - - // inherit doc comment - public boolean equals(Object other) { - return ReferentUuids.compare(this, other); - } - - // inherit doc comment - public int hashCode() { - return spaceUuid.hashCode(); - } - - public Uuid getReferentUuid() { - return spaceUuid; - } - - /** - * Safely read the value of - * <code>org.apache.river.outrigger.maxServerQueryTimeout</code>. - * If it can't be read return -1. - */ - private static long getMaxServerQueryTimeoutPropertyValue() { - try { - final String propValue = - (String)Security.doPrivileged( - new ReadProperityPrivilegedAction( - "org.apache.river.outrigger.maxServerQueryTimeout")); - if (propValue == null) - return -1; - - // Note, if we throw NumberFormatException we return -1. - return Long.parseLong(propValue); - } catch (Throwable t) { - return -1; - } - } - - /** - * PrivilegedAction for reading a property. Returns a string. - */ - private static class ReadProperityPrivilegedAction - implements PrivilegedAction - { - /** Property to read */ - final private String propName; - - /** - * Construct a ReadProperityPrivilegedAction that will read - * the specified property. - */ - ReadProperityPrivilegedAction(String propName) { - this.propName = propName; - } - - public Object run() { - try { - return System.getProperty(propName); - } catch (SecurityException e) { - return null; - } - } - } - - /** - * Set <code>maxServerQueryTimeout</code> based on the values - * of <code>serverMaxServerQueryTimeout</code> and - * <code>maxServerQueryTimeoutPropertyValue</code>. - */ - private void setMaxServerQueryTimeout() { - /* If the org.apache.river.outrigger.maxServerQueryTimeout property - * was set in this VM, override the value set by the server - * when we were created. - */ - if (maxServerQueryTimeoutPropertyValue > 0) - maxServerQueryTimeout = maxServerQueryTimeoutPropertyValue; - else if (serverMaxServerQueryTimeout > 0) - maxServerQueryTimeout = serverMaxServerQueryTimeout; - else - /* should never get here, the constructor and readObject - * check to make sure that serverMaxServerQueryTimeout - * is positive. - */ - throw new - AssertionError("serverMaxServerQueryTimeout invalid:" + - serverMaxServerQueryTimeout); - - if (logger.isLoggable(Level.CONFIG)) { - logger.log(Level.CONFIG, - "Outrigger proxy using {0} ms for maxServerQueryTimeout", - Long.valueOf(maxServerQueryTimeout)); - } - } - - /** - * Read this object back setting the <code>maxServerQueryTimeout</code> - * field and validate state. - */ - private void readObject(ObjectInputStream in) - throws IOException, ClassNotFoundException - { - in.defaultReadObject(); - - if (space == null) - throw new InvalidObjectException("null server reference"); - - if (spaceUuid == null) - throw new InvalidObjectException("null Uuid"); - - if (serverMaxServerQueryTimeout <= 0) - throw new - InvalidObjectException("Bad serverMaxServerQueryTimeout " + - "value:" + serverMaxServerQueryTimeout); - - setMaxServerQueryTimeout(); - } - - /** - * We should always have data in the stream, if this method - * gets called there is something wrong. - */ - private void readObjectNoData() throws InvalidObjectException { - throw new - InvalidObjectException("SpaceProxy2 should always have data"); - } - - // -------------------------------------------------- - // JavaSpace method implementations - // -------------------------------------------------- - - // inherit doc comment - public Lease write(Entry entry, Transaction txn, long lease) - throws TransactionException, RemoteException - { - if (entry == null) - throw new NullPointerException("Cannot write null Entry"); - long[] leaseData = space.write(repFor(entry), txn, lease); - if (leaseData == null || leaseData.length != 3){ - StringBuilder sb = new StringBuilder(180); - sb.append("space.write returned malformed data \n"); - int l = leaseData == null? 0 : leaseData.length; - for (int i =0; i < l; i++){ - sb.append(leaseData[i]).append("\n"); - } - throw new AssertionError(sb); - } - return newLease(UuidFactory.create(leaseData[1], leaseData[2]), - leaseData[0]); - } - - public Entry read(Entry tmpl, Transaction txn, long timeout) - throws UnusableEntryException, TransactionException, - InterruptedException, RemoteException - { - // Figure out the max time this query should last - final long endTime = calcEndTime(timeout); - - long remaining = timeout; - OutriggerServer.QueryCookie queryCookie = null; - - // Loop util timeout or we get an answer (call at least once!) - do { - final long serverTimeout = - Math.min(remaining, maxServerQueryTimeout); - logQuery("read", serverTimeout, queryCookie, remaining); - - final Object rslt = - space.read(repFor(tmpl), txn, serverTimeout, queryCookie); - if (rslt == null) { - // should never get null from a non-ifExists query - throw new AssertionError("space.read() returned null"); - } else if (rslt instanceof EntryRep) { - // Got an answer, return it - return entryFrom((EntryRep)rslt); - } else if (rslt instanceof OutriggerServer.QueryCookie) { - /* Will still want to go on if there is time, but pass - * the new cookie - */ - queryCookie = (OutriggerServer.QueryCookie)rslt; - } else { - throw new AssertionError( - "Unexpected return type from space.read()"); - } - - /* Update remaining and loop, checking to see if the timeout has - * expired. - */ - remaining = endTime - System.currentTimeMillis(); - } while (remaining > 0); - - /* If we get here then there must not have been an entry available - * to us before the endTime. - */ - return null; - } - - // inherit doc comment, use internal routine for common code - public Entry readIfExists(Entry tmpl, Transaction txn, long timeout) - throws UnusableEntryException, TransactionException, - InterruptedException, RemoteException - { - // Figure out the max time this query should last - final long endTime = calcEndTime(timeout); - - long remaining = timeout; - OutriggerServer.QueryCookie queryCookie = null; - - // Loop util timeout or we get an answer (call at least once!) - do { - final long serverTimeout = - Math.min(remaining, maxServerQueryTimeout); - logQuery("readIfExists", serverTimeout, queryCookie, remaining); - - final Object rslt = - space.readIfExists(repFor(tmpl), txn, serverTimeout, - queryCookie); - if (rslt == null) { - // Must be no matches in the space at all - return null; - } else if (rslt instanceof EntryRep) { - // Got an answer, return it - return entryFrom((EntryRep)rslt); - } else if (rslt instanceof OutriggerServer.QueryCookie) { - /* Will still want to go on if there is time, but pass - * the new cookie - */ - queryCookie = (OutriggerServer.QueryCookie)rslt; - } else { - throw new AssertionError( - "Unexpected return type from space.readIfExists()"); - } - - /* Update remaining and loop, checking to see if the timeout has - * expired. - */ - remaining = endTime - System.currentTimeMillis(); - } while (remaining > 0); - - /* If we get here then there must not have been an entry available - * to us before the endTime. - */ - return null; - } - - // inherit doc comment, use internal routine for common code - public Entry take(Entry tmpl, Transaction txn, long timeout) - throws UnusableEntryException, TransactionException, - InterruptedException, RemoteException - { - // Figure out the max time this query should last - final long endTime = calcEndTime(timeout); - - long remaining = timeout; - OutriggerServer.QueryCookie queryCookie = null; - - // Loop util timeout or we get an answer (call at least once!) - do { - final long serverTimeout = - Math.min(remaining, maxServerQueryTimeout); - logQuery("take", serverTimeout, queryCookie, remaining); - - final Object rslt = - space.take(repFor(tmpl), txn, serverTimeout, queryCookie); - if (rslt == null) { - // should never get null from a non-ifExists query - throw new AssertionError("space.take() returned null"); - } else if (rslt instanceof EntryRep) { - // Got an answer, return it - return entryFrom((EntryRep)rslt); - } else if (rslt instanceof OutriggerServer.QueryCookie) { - /* Will still want to go on if there is time, but pass - * the new cookie - */ - queryCookie = (OutriggerServer.QueryCookie)rslt; - } else { - throw new AssertionError( - "Unexpected return type from space.take()"); - } - - /* Update remaining and loop, checking to see if the timeout has - * expired. - */ - remaining = endTime - System.currentTimeMillis(); - } while (remaining > 0); - - /* If we get here then there must not have been an entry available - * to us before the endTime. - */ - return null; - } - - // inherit doc comment, use internal routine for common code - public Entry takeIfExists(Entry tmpl, Transaction txn, long timeout) - throws UnusableEntryException, TransactionException, - InterruptedException, RemoteException - { - // Figure out the max time this query should last - final long endTime = calcEndTime(timeout); - - long remaining = timeout; - OutriggerServer.QueryCookie queryCookie = null; - - // Loop util timeout or we get an answer (call at least once!) - do { - final long serverTimeout = - Math.min(remaining, maxServerQueryTimeout); - logQuery("takeIfExists", serverTimeout, queryCookie, remaining); - - final Object rslt = - space.takeIfExists(repFor(tmpl), txn, serverTimeout, - queryCookie); - if (rslt == null) { - // Must be no matches in the space at all - return null; - } else if (rslt instanceof EntryRep) { - // Got an answer, return it - return entryFrom((EntryRep)rslt); - } else if (rslt instanceof OutriggerServer.QueryCookie) { - /* Will still want to go on if there is time, but pass - * the new cookie - */ - queryCookie = (OutriggerServer.QueryCookie)rslt; - } else { - throw new AssertionError( - "Unexpected return type from space.takeIfExists()"); - } - - /* Update remaining and loop, checking to see if the timeout has - * expired. - */ - remaining = endTime - System.currentTimeMillis(); - } while (remaining > 0); - - /* If we get here then there must not have been an entry available - * to us before the endTime. - */ - return null; - } - - // inherit doc comment - public Entry snapshot(Entry entry) throws MarshalException { - if (entry == null) - return null; - else - return new SnapshotRep(entry); - } - - // inherit doc comment - public EventRegistration - notify(Entry tmpl, Transaction txn, RemoteEventListener listener, - long lease, MarshalledObject handback) - throws TransactionException, RemoteException - { - return space.notify(repFor(tmpl), txn, listener, lease, handback); - } - - public List write(List entries, Transaction txn, List leaseDurations) - throws RemoteException, TransactionException - { - final long[] leases = new long[leaseDurations.size()]; - int j = 0; - for (Iterator i=leaseDurations.iterator(); i.hasNext(); ) { - final Object l = i.next(); - - if (l == null) - throw new NullPointerException( - "leaseDurations contatins a null element"); - - if (!(l instanceof Long)) - throw new IllegalArgumentException( - "leaseDurations contatins an element which is not a Long"); - - leases[j++] = ((Long)l).longValue(); - } - - long[] leaseData = space.write(repFor(entries, "entries"), txn, leases); - if (leaseData == null) - throw new AssertionError("space.write<multiple> returned null"); - - final List rslt = new ArrayList(leaseData.length/3); - try { - int m=0; - while (m<leaseData.length) { - final long duration = leaseData[m++]; - final long high = leaseData[m++]; - final long low = leaseData[m++]; - final Uuid uuid = UuidFactory.create(high, low); - rslt.add(newLease(uuid, duration)); - } - } catch (ArrayIndexOutOfBoundsException e) { - throw new - AssertionError("space.write<multiple> returned malformed data"); - } - - return rslt; - } - - public Collection take(Collection tmpls, Transaction txn, - long timeout, long maxEntries) - throws UnusableEntriesException, TransactionException, RemoteException - { - // Figure out the max time this query should last - final long endTime = calcEndTime(timeout); - - long remaining = timeout; - OutriggerServer.QueryCookie queryCookie = null; - final EntryRep[] treps = repFor(tmpls, "tmpls"); - - final int limit; - if (maxEntries < 1) { - throw new IllegalArgumentException("maxEntries must be positive"); - } else if (maxEntries <= Integer.MAX_VALUE) { - limit = (int)maxEntries; - } else { - limit = Integer.MAX_VALUE; // ok to return fewer than requested - } - - // Loop util timeout or we get an answer (call at least once!) - do { - final long serverTimeout = - Math.min(remaining, maxServerQueryTimeout); - logQuery("take(multiple)", serverTimeout, queryCookie, remaining); - - - final Object rslt = - space.take(treps, txn, serverTimeout, limit, queryCookie); - if (rslt == null) { - // should never get null from a non-ifExists query - throw new AssertionError("space.take<multiple>() returned null"); - } else if (rslt instanceof EntryRep[]) { - EntryRep[] reps = (EntryRep[])rslt; - // Got an answer, return it - final Collection entries = new LinkedList(); - Collection exceptions = null; - - for (int i=0;i<reps.length;i++) { - try { - entries.add(entryFrom(reps[i])); - } catch (UnusableEntryException e) { - if (exceptions == null) - exceptions = new LinkedList(); - - exceptions.add(e); - } - } - - if (exceptions == null) { - return entries; - } else { - throw new UnusableEntriesException( - "some of the removed entries could not be unmarshalled", - entries, exceptions); - } - } else if (rslt instanceof OutriggerServer.QueryCookie) { - /* Will still want to go on if there is time, but pass - * the new cookie - */ - queryCookie = (OutriggerServer.QueryCookie)rslt; - } else { - throw new AssertionError( - "Unexpected return type from space.take<multiple>()"); - } - - /* Update remaining and loop, checking to see if the timeout has - * expired. - */ - remaining = endTime - System.currentTimeMillis(); - } while (remaining > 0); - - /* If we get here then there must not have been any entries available - * to us before the endTime. - */ - return Collections.EMPTY_LIST; - } - - public EventRegistration - registerForAvailabilityEvent(Collection tmpls, - Transaction txn, - boolean visibilityOnly, - RemoteEventListener listener, - long leaseDuration, - MarshalledObject handback) - throws TransactionException, RemoteException - { - return space.registerForAvailabilityEvent( - repFor(tmpls, "tmpls"), txn, visibilityOnly, listener, - leaseDuration, handback); - } - - - // inherit doc comment - public MatchSet contents(Collection tmpls, - Transaction txn, - long leaseDuration, - long maxEntries) - throws RemoteException, TransactionException - { - final MatchSetData msd = - space.contents(repFor(tmpls, "tmpls"), txn, leaseDuration, maxEntries); - return new MatchSetProxy(msd, this, space); - } - - /* We break up lease creation into two methods. newLease takes - * care of converting from duration to expiration and we should - * never need to override (so we make it final), while - * constructLease takes care of invoking the right constructor for - * the given context (e.g. constrainable v. not) - */ - - /** Create a new lease with the specified id and initial duration */ - final protected Lease newLease(Uuid uuid, long duration) { - long expiration = duration + System.currentTimeMillis(); - - // We added two positive numbers, so if the result is negative - // we must have overflowed, so use Long.MAX_VALUE - if (expiration < 0) - expiration = Long.MAX_VALUE; - return constructLease(uuid, expiration); - } - - /** Create a new lease with the specified id and initial expiration */ - protected Lease constructLease(Uuid uuid, long expiration) { - return new LandlordLease(uuid, space, spaceUuid, expiration); - } - - // -------------------------------------------------- - // Administrable methods implementation - // -------------------------------------------------- - // inherit doc comment - public Object getAdmin() throws RemoteException { - return space.getAdmin(); - } - - // -------------------------------------------------- - // Private implementation - // -------------------------------------------------- - - /** - * Utility method to calculate the absolute end time of a query. - * @param timeout relative timeout of query. - * @return timeout plus the current time, or - * <code>Long.MAX_VALUE</code> if timeout plus the current time - * is larger than <code>Long.MAX_VALUE</code>. - */ - private long calcEndTime(long timeout) { - if (timeout < 0) - throw new IllegalArgumentException("timeout must be non-negative"); - final long now = System.currentTimeMillis(); - if (Long.MAX_VALUE - timeout <= now) - return Long.MAX_VALUE; - else - return now + timeout; - } - - static EntryRep[] repFor(Collection entries, String argName) - throws MarshalException - { - final EntryRep[] reps = new EntryRep[entries.size()]; - int j = 0; - for (Iterator i=entries.iterator(); i.hasNext(); ) { - final Object e = i.next(); - if (!(e == null || e instanceof Entry)) - throw new IllegalArgumentException( - argName + " contatins an element which is not an Entry"); - - reps[j++] = repFor((Entry)e); - } - - return reps; - } - - /** - * Return an <code>EntryRep</code> object for the given - * <code>Entry</code>. - */ - static EntryRep repFor(Entry entry) throws MarshalException { - if (entry == null) - return null; - if (entry instanceof SnapshotRep) // snapshots are pre-calculated - return ((SnapshotRep) entry).rep(); - return new EntryRep(entry); - } - - /** - * Return an entry generated from the given rep. - */ - static Entry entryFrom(EntryRep rep) throws UnusableEntryException { - if (rep == null) - return null; - return rep.entry(); - } - - /** Log query call to server */ - private void logQuery(String op, long serverTimeout, - OutriggerServer.QueryCookie cookie, long remaining) - { - if (logger.isLoggable(Level.FINER)) { - logger.log(Level.FINER, "Outrigger calling {0} on server with " + - "timeout of {1} ms for serverTimeout, using QueryCookie " + - "{2}, {3} ms remaining on query", - new Object[] {op, Long.valueOf(serverTimeout), cookie, - Long.valueOf(remaining)}); - } - } -} +/* + * 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.outrigger.proxy; + +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.io.IOException; +import java.io.InvalidObjectException; +import java.rmi.MarshalledObject; +import java.rmi.RemoteException; +import java.rmi.MarshalException; +import java.security.PrivilegedAction; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.Iterator; +import java.util.logging.Level; +import java.util.logging.Logger; + +import net.jini.admin.Administrable; +import net.jini.core.entry.Entry; +import net.jini.core.entry.UnusableEntryException; +import net.jini.core.event.EventRegistration; +import net.jini.core.event.RemoteEventListener; +import net.jini.core.lease.Lease; +import net.jini.core.transaction.Transaction; +import net.jini.core.transaction.TransactionException; +import net.jini.entry.UnusableEntriesException; +import net.jini.space.JavaSpace05; +import net.jini.space.MatchSet; + +import net.jini.id.Uuid; +import net.jini.id.UuidFactory; +import net.jini.id.ReferentUuid; +import net.jini.id.ReferentUuids; +import net.jini.security.Security; + +import org.apache.river.landlord.LandlordLease; + +/** + * This class is the client-side proxy for the Outrigger + * implementation of a JavaSpaces<sup><font size=-2>TM</font></sup> + * service. <code>OutriggerServerImpl</code> implements the + * <code>OutriggerSpace</code> interface, and each + * <code>SpaceProxy2</code> object holds a reference to the remote + * OutriggerSpace server it represents to the client. The client makes + * calls from the <code>JavaSpace</code> interface, which the + * <code>SpaceProxy2</code> translates into appropriate + * <code>OutriggerSpace</code> calls to the + * <code>OutriggerServerImpl</code> server. + * + * @author Sun Microsystems, Inc. + * + */ +public // @see OutriggerSpace +class SpaceProxy2 implements JavaSpace05, Administrable, ReferentUuid, + Serializable +{ + static final long serialVersionUID = 1L; + + /** + * The remote server this proxy works with. + * Package protected so it can be read by subclasses and proxy verifier + * @serial + */ + final OutriggerServer space; + + /** + * The <code>Uuid</code> that identifies the space this proxy is for. + * Package protected so it can be read by subclasses and proxy verifier + * @serial + */ + final Uuid spaceUuid; + + /** + * The value to use for maxServerQueryTimeout if no + * local value is provided. Package protected so it can be read by + * subclasses. + * @serial + */ + final long serverMaxServerQueryTimeout; + + /** + * Maximum time any sub-query should be allowed to run for. + */ + private transient volatile long maxServerQueryTimeout; + + + /** + * Value (as a long) of the + * <code>org.apache.river.outrigger.maxServerQueryTimeout</code> + * property in this VM, or a non-positive number if it is not set. + */ + private static final long maxServerQueryTimeoutPropertyValue = + getMaxServerQueryTimeoutPropertyValue(); + + /** + * Logger for logging information about operations carried out in + * the client. Note, we hard code "org.apache.river.outrigger" so + * we don't drag in OutriggerServerImpl to outrigger-dl.jar. + */ + private static final Logger logger = + Logger.getLogger("org.apache.river.outrigger.proxy"); + + // -------------------------------------------------- + // Construction + // -------------------------------------------------- + + /** + * Create a new <code>SpaceProxy2</code> for the given space. + * @param space The <code>OutriggerServer</code> for the + * space. + * @param spaceUuid The universally unique ID for the + * space + * @param serverMaxServerQueryTimeout The value this proxy + * should use for the <code>maxServerQueryTimeout</code> + * if no local value is provided. + * @throws NullPointerException if <code>space</code> or + * <code>spaceUuid</code> is <code>null</code>. + * @throws IllegalArgumentException if + * <code>serverMaxServerQueryTimeout</code> is not + * larger than zero. + */ + public SpaceProxy2(OutriggerServer space, Uuid spaceUuid, + long serverMaxServerQueryTimeout) + { + if (space == null) + throw new NullPointerException("space must be non-null"); + if (spaceUuid == null) + throw new NullPointerException("spaceUuid must be non-null"); + if (serverMaxServerQueryTimeout <= 0) + throw new + IllegalArgumentException("serverMaxServerQueryTimeout " + + "must be positive"); + this.space = space; + this.spaceUuid = spaceUuid; + this.serverMaxServerQueryTimeout = serverMaxServerQueryTimeout; + setMaxServerQueryTimeout(); + } + + public String toString() { + return getClass().getName() + " for " + spaceUuid + + " (through " + space + ")"; + } + + // inherit doc comment + public boolean equals(Object other) { + return ReferentUuids.compare(this, other); + } + + // inherit doc comment + public int hashCode() { + return spaceUuid.hashCode(); + } + + public Uuid getReferentUuid() { + return spaceUuid; + } + + /** + * Safely read the value of + * <code>org.apache.river.outrigger.maxServerQueryTimeout</code>. + * If it can't be read return -1. + */ + private static long getMaxServerQueryTimeoutPropertyValue() { + try { + final String propValue = + (String)Security.doPrivileged( + new ReadProperityPrivilegedAction( + "org.apache.river.outrigger.maxServerQueryTimeout")); + if (propValue == null) + return -1; + + // Note, if we throw NumberFormatException we return -1. + return Long.parseLong(propValue); + } catch (Throwable t) { + return -1; + } + } + + /** + * PrivilegedAction for reading a property. Returns a string. + */ + private static class ReadProperityPrivilegedAction + implements PrivilegedAction + { + /** Property to read */ + final private String propName; + + /** + * Construct a ReadProperityPrivilegedAction that will read + * the specified property. + */ + ReadProperityPrivilegedAction(String propName) { + this.propName = propName; + } + + public Object run() { + try { + return System.getProperty(propName); + } catch (SecurityException e) { + return null; + } + } + } + + /** + * Set <code>maxServerQueryTimeout</code> based on the values + * of <code>serverMaxServerQueryTimeout</code> and + * <code>maxServerQueryTimeoutPropertyValue</code>. + */ + private void setMaxServerQueryTimeout() { + /* If the org.apache.river.outrigger.maxServerQueryTimeout property + * was set in this VM, override the value set by the server + * when we were created. + */ + if (maxServerQueryTimeoutPropertyValue > 0) + maxServerQueryTimeout = maxServerQueryTimeoutPropertyValue; + else if (serverMaxServerQueryTimeout > 0) + maxServerQueryTimeout = serverMaxServerQueryTimeout; + else + /* should never get here, the constructor and readObject + * check to make sure that serverMaxServerQueryTimeout + * is positive. + */ + throw new + AssertionError("serverMaxServerQueryTimeout invalid:" + + serverMaxServerQueryTimeout); + + if (logger.isLoggable(Level.CONFIG)) { + logger.log(Level.CONFIG, + "Outrigger proxy using {0} ms for maxServerQueryTimeout", + Long.valueOf(maxServerQueryTimeout)); + } + } + + /** + * Read this object back setting the <code>maxServerQueryTimeout</code> + * field and validate state. + */ + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException + { + in.defaultReadObject(); + + if (space == null) + throw new InvalidObjectException("null server reference"); + + if (spaceUuid == null) + throw new InvalidObjectException("null Uuid"); + + if (serverMaxServerQueryTimeout <= 0) + throw new + InvalidObjectException("Bad serverMaxServerQueryTimeout " + + "value:" + serverMaxServerQueryTimeout); + + setMaxServerQueryTimeout(); + } + + /** + * We should always have data in the stream, if this method + * gets called there is something wrong. + */ + private void readObjectNoData() throws InvalidObjectException { + throw new + InvalidObjectException("SpaceProxy2 should always have data"); + } + + // -------------------------------------------------- + // JavaSpace method implementations + // -------------------------------------------------- + + // inherit doc comment + public Lease write(Entry entry, Transaction txn, long lease) + throws TransactionException, RemoteException + { + if (entry == null) + throw new NullPointerException("Cannot write null Entry"); + long[] leaseData = space.write(repFor(entry), txn, lease); + if (leaseData == null || leaseData.length != 3){ + StringBuilder sb = new StringBuilder(180); + sb.append("space.write returned malformed data \n"); + int l = leaseData == null? 0 : leaseData.length; + for (int i =0; i < l; i++){ + sb.append(leaseData[i]).append("\n"); + } + throw new AssertionError(sb); + } + return newLease(UuidFactory.create(leaseData[1], leaseData[2]), + leaseData[0]); + } + + public Entry read(Entry tmpl, Transaction txn, long timeout) + throws UnusableEntryException, TransactionException, + InterruptedException, RemoteException + { + // Figure out the max time this query should last + final long endTime = calcEndTime(timeout); + + long remaining = timeout; + OutriggerServer.QueryCookie queryCookie = null; + + // Loop util timeout or we get an answer (call at least once!) + do { + final long serverTimeout = + Math.min(remaining, maxServerQueryTimeout); + logQuery("read", serverTimeout, queryCookie, remaining); + + final Object rslt = + space.read(repFor(tmpl), txn, serverTimeout, queryCookie); + if (rslt == null) { + // should never get null from a non-ifExists query + throw new AssertionError("space.read() returned null"); + } else if (rslt instanceof EntryRep) { + // Got an answer, return it + return entryFrom((EntryRep)rslt); + } else if (rslt instanceof OutriggerServer.QueryCookie) { + /* Will still want to go on if there is time, but pass + * the new cookie + */ + queryCookie = (OutriggerServer.QueryCookie)rslt; + } else { + throw new AssertionError( + "Unexpected return type from space.read()"); + } + + /* Update remaining and loop, checking to see if the timeout has + * expired. + */ + remaining = endTime - System.currentTimeMillis(); + } while (remaining > 0); + + /* If we get here then there must not have been an entry available + * to us before the endTime. + */ + return null; + } + + // inherit doc comment, use internal routine for common code + public Entry readIfExists(Entry tmpl, Transaction txn, long timeout) + throws UnusableEntryException, TransactionException, + InterruptedException, RemoteException + { + // Figure out the max time this query should last + final long endTime = calcEndTime(timeout); + + long remaining = timeout; + OutriggerServer.QueryCookie queryCookie = null; + + // Loop util timeout or we get an answer (call at least once!) + do { + final long serverTimeout = + Math.min(remaining, maxServerQueryTimeout); + logQuery("readIfExists", serverTimeout, queryCookie, remaining); + + final Object rslt = + space.readIfExists(repFor(tmpl), txn, serverTimeout, + queryCookie); + if (rslt == null) { + // Must be no matches in the space at all + return null; + } else if (rslt instanceof EntryRep) { + // Got an answer, return it + return entryFrom((EntryRep)rslt); + } else if (rslt instanceof OutriggerServer.QueryCookie) { + /* Will still want to go on if there is time, but pass + * the new cookie + */ + queryCookie = (OutriggerServer.QueryCookie)rslt; + } else { + throw new AssertionError( + "Unexpected return type from space.readIfExists()"); + } + + /* Update remaining and loop, checking to see if the timeout has + * expired. + */ + remaining = endTime - System.currentTimeMillis(); + } while (remaining > 0); + + /* If we get here then there must not have been an entry available + * to us before the endTime. + */ + return null; + } + + // inherit doc comment, use internal routine for common code + public Entry take(Entry tmpl, Transaction txn, long timeout) + throws UnusableEntryException, TransactionException, + InterruptedException, RemoteException + { + // Figure out the max time this query should last + final long endTime = calcEndTime(timeout); + + long remaining = timeout; + OutriggerServer.QueryCookie queryCookie = null; + + // Loop util timeout or we get an answer (call at least once!) + do { + final long serverTimeout = + Math.min(remaining, maxServerQueryTimeout); + logQuery("take", serverTimeout, queryCookie, remaining); + + final Object rslt = + space.take(repFor(tmpl), txn, serverTimeout, queryCookie); + if (rslt == null) { + // should never get null from a non-ifExists query + throw new AssertionError("space.take() returned null"); + } else if (rslt instanceof EntryRep) { + // Got an answer, return it + return entryFrom((EntryRep)rslt); + } else if (rslt instanceof OutriggerServer.QueryCookie) { + /* Will still want to go on if there is time, but pass + * the new cookie + */ + queryCookie = (OutriggerServer.QueryCookie)rslt; + } else { + throw new AssertionError( + "Unexpected return type from space.take()"); + } + + /* Update remaining and loop, checking to see if the timeout has + * expired. + */ + remaining = endTime - System.currentTimeMillis(); + } while (remaining > 0); + + /* If we get here then there must not have been an entry available + * to us before the endTime. + */ + return null; + } + + // inherit doc comment, use internal routine for common code + public Entry takeIfExists(Entry tmpl, Transaction txn, long timeout) + throws UnusableEntryException, TransactionException, + InterruptedException, RemoteException + { + // Figure out the max time this query should last + final long endTime = calcEndTime(timeout); + + long remaining = timeout; + OutriggerServer.QueryCookie queryCookie = null; + + // Loop util timeout or we get an answer (call at least once!) + do { + final long serverTimeout = + Math.min(remaining, maxServerQueryTimeout); + logQuery("takeIfExists", serverTimeout, queryCookie, remaining); + + final Object rslt = + space.takeIfExists(repFor(tmpl), txn, serverTimeout, + queryCookie); + if (rslt == null) { + // Must be no matches in the space at all + return null; + } else if (rslt instanceof EntryRep) { + // Got an answer, return it + return entryFrom((EntryRep)rslt); + } else if (rslt instanceof OutriggerServer.QueryCookie) { + /* Will still want to go on if there is time, but pass + * the new cookie + */ + queryCookie = (OutriggerServer.QueryCookie)rslt; + } else { + throw new AssertionError( + "Unexpected return type from space.takeIfExists()"); + } + + /* Update remaining and loop, checking to see if the timeout has + * expired. + */ + remaining = endTime - System.currentTimeMillis(); + } while (remaining > 0); + + /* If we get here then there must not have been an entry available + * to us before the endTime. + */ + return null; + } + + // inherit doc comment + public Entry snapshot(Entry entry) throws MarshalException { + if (entry == null) + return null; + else + return new SnapshotRep(entry); + } + + // inherit doc comment + public EventRegistration + notify(Entry tmpl, Transaction txn, RemoteEventListener listener, + long lease, MarshalledObject handback) + throws TransactionException, RemoteException + { + return space.notify(repFor(tmpl), txn, listener, lease, handback); + } + + public List write(List entries, Transaction txn, List leaseDurations) + throws RemoteException, TransactionException + { + final long[] leases = new long[leaseDurations.size()]; + int j = 0; + for (Iterator i=leaseDurations.iterator(); i.hasNext(); ) { + final Object l = i.next(); + + if (l == null) + throw new NullPointerException( + "leaseDurations contatins a null element"); + + if (!(l instanceof Long)) + throw new IllegalArgumentException( + "leaseDurations contatins an element which is not a Long"); + + leases[j++] = ((Long)l).longValue(); + } + + long[] leaseData = space.write(repFor(entries, "entries"), txn, leases); + if (leaseData == null) + throw new AssertionError("space.write<multiple> returned null"); + + final List rslt = new ArrayList(leaseData.length/3); + try { + int m=0; + while (m<leaseData.length) { + final long duration = leaseData[m++]; + final long high = leaseData[m++]; + final long low = leaseData[m++]; + final Uuid uuid = UuidFactory.create(high, low); + rslt.add(newLease(uuid, duration)); + } + } catch (ArrayIndexOutOfBoundsException e) { + throw new + AssertionError("space.write<multiple> returned malformed data"); + } + + return rslt; + } + + public Collection take(Collection tmpls, Transaction txn, + long timeout, long maxEntries) + throws UnusableEntriesException, TransactionException, RemoteException + { + // Figure out the max time this query should last + final long endTime = calcEndTime(timeout); + + long remaining = timeout; + OutriggerServer.QueryCookie queryCookie = null; + final EntryRep[] treps = repFor(tmpls, "tmpls"); + + final int limit; + if (maxEntries < 1) { + throw new IllegalArgumentException("maxEntries must be positive"); + } else if (maxEntries <= Integer.MAX_VALUE) { + limit = (int)maxEntries; + } else { + limit = Integer.MAX_VALUE; // ok to return fewer than requested + } + + // Loop util timeout or we get an answer (call at least once!) + do { + final long serverTimeout = + Math.min(remaining, maxServerQueryTimeout); + logQuery("take(multiple)", serverTimeout, queryCookie, remaining); + + + final Object rslt = + space.take(treps, txn, serverTimeout, limit, queryCookie); + if (rslt == null) { + // should never get null from a non-ifExists query + throw new AssertionError("space.take<multiple>() returned null"); + } else if (rslt instanceof EntryRep[]) { + EntryRep[] reps = (EntryRep[])rslt; + // Got an answer, return it + final Collection entries = new LinkedList(); + Collection exceptions = null; + + for (int i=0;i<reps.length;i++) { + try { + entries.add(entryFrom(reps[i])); + } catch (UnusableEntryException e) { + if (exceptions == null) + exceptions = new LinkedList(); + + exceptions.add(e); + } + } + + if (exceptions == null) { + return entries; + } else { + throw new UnusableEntriesException( + "some of the removed entries could not be unmarshalled", + entries, exceptions); + } + } else if (rslt instanceof OutriggerServer.QueryCookie) { + /* Will still want to go on if there is time, but pass + * the new cookie + */ + queryCookie = (OutriggerServer.QueryCookie)rslt; + } else { + throw new AssertionError( + "Unexpected return type from space.take<multiple>()"); + } + + /* Update remaining and loop, checking to see if the timeout has + * expired. + */ + remaining = endTime - System.currentTimeMillis(); + } while (remaining > 0); + + /* If we get here then there must not have been any entries available + * to us before the endTime. + */ + return Collections.EMPTY_LIST; + } + + public EventRegistration + registerForAvailabilityEvent(Collection tmpls, + Transaction txn, + boolean visibilityOnly, + RemoteEventListener listener, + long leaseDuration, + MarshalledObject handback) + throws TransactionException, RemoteException + { + return space.registerForAvailabilityEvent( + repFor(tmpls, "tmpls"), txn, visibilityOnly, listener, + leaseDuration, handback); + } + + + // inherit doc comment + public MatchSet contents(Collection tmpls, + Transaction txn, + long leaseDuration, + long maxEntries) + throws RemoteException, TransactionException + { + final MatchSetData msd = + space.contents(repFor(tmpls, "tmpls"), txn, leaseDuration, maxEntries); + return new MatchSetProxy(msd, this, space); + } + + /* We break up lease creation into two methods. newLease takes + * care of converting from duration to expiration and we should + * never need to override (so we make it final), while + * constructLease takes care of invoking the right constructor for + * the given context (e.g. constrainable v. not) + */ + + /** Create a new lease with the specified id and initial duration */ + final protected Lease newLease(Uuid uuid, long duration) { + long expiration = duration + System.currentTimeMillis(); + + // We added two positive numbers, so if the result is negative + // we must have overflowed, so use Long.MAX_VALUE + if (expiration < 0) + expiration = Long.MAX_VALUE; + return constructLease(uuid, expiration); + } + + /** Create a new lease with the specified id and initial expiration */ + protected Lease constructLease(Uuid uuid, long expiration) { + return new LandlordLease(uuid, space, spaceUuid, expiration); + } + + // -------------------------------------------------- + // Administrable methods implementation + // -------------------------------------------------- + // inherit doc comment + public Object getAdmin() throws RemoteException { + return space.getAdmin(); + } + + // -------------------------------------------------- + // Private implementation + // -------------------------------------------------- + + /** + * Utility method to calculate the absolute end time of a query. + * @param timeout relative timeout of query. + * @return timeout plus the current time, or + * <code>Long.MAX_VALUE</code> if timeout plus the current time + * is larger than <code>Long.MAX_VALUE</code>. + */ + private long calcEndTime(long timeout) { + if (timeout < 0) + throw new IllegalArgumentException("timeout must be non-negative"); + final long now = System.currentTimeMillis(); + if (Long.MAX_VALUE - timeout <= now) + return Long.MAX_VALUE; + else + return now + timeout; + } + + static EntryRep[] repFor(Collection entries, String argName) + throws MarshalException + { + final EntryRep[] reps = new EntryRep[entries.size()]; + int j = 0; + for (Iterator i=entries.iterator(); i.hasNext(); ) { + final Object e = i.next(); + if (!(e == null || e instanceof Entry)) + throw new IllegalArgumentException( + argName + " contatins an element which is not an Entry"); + + reps[j++] = repFor((Entry)e); + } + + return reps; + } + + /** + * Return an <code>EntryRep</code> object for the given + * <code>Entry</code>. + */ + static EntryRep repFor(Entry entry) throws MarshalException { + if (entry == null) + return null; + if (entry instanceof SnapshotRep) // snapshots are pre-calculated + return ((SnapshotRep) entry).rep(); + return new EntryRep(entry); + } + + /** + * Return an entry generated from the given rep. + */ + static Entry entryFrom(EntryRep rep) throws UnusableEntryException { + if (rep == null) + return null; + return rep.entry(); + } + + /** Log query call to server */ + private void logQuery(String op, long serverTimeout, + OutriggerServer.QueryCookie cookie, long remaining) + { + if (logger.isLoggable(Level.FINER)) { + logger.log(Level.FINER, "Outrigger calling {0} on server with " + + "timeout of {1} ms for serverTimeout, using QueryCookie " + + "{2}, {3} ms remaining on query", + new Object[] {op, Long.valueOf(serverTimeout), cookie, + Long.valueOf(remaining)}); + } + } +} Modified: river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/StorableObject.java URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/StorableObject.java?rev=1879521&r1=1879520&r2=1879521&view=diff ============================================================================== --- river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/StorableObject.java (original) +++ river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/StorableObject.java Sun Jul 5 11:41:39 2020 @@ -1,53 +1,53 @@ -/* - * 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.outrigger; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; - -/** - * Interface that must be implemented by objects that must persist their - * state. - * - * @param <T> The type of the object to be restored - * @see LogOps - * - * @author Sun Microsystems, Inc. - * - * @since 2.0 - */ -public interface StorableObject<T> { - - /** - * Store the persistent fields - * @param out - * @throws IOException - */ - public void store(ObjectOutputStream out) throws IOException; - - /** - * Restore the persistent fields and return new instance. - * @param in - * @return new object instance. - * @throws IOException - * @throws ClassNotFoundException - */ - public T restore(ObjectInputStream in) - throws IOException, ClassNotFoundException; -} +/* + * 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.outrigger.proxy; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +/** + * Interface that must be implemented by objects that must persist their + * state. + * + * @param <T> The type of the object to be restored + * @see LogOps + * + * @author Sun Microsystems, Inc. + * + * @since 2.0 + */ +public interface StorableObject<T> { + + /** + * Store the persistent fields + * @param out + * @throws IOException + */ + public void store(ObjectOutputStream out) throws IOException; + + /** + * Restore the persistent fields and return new instance. + * @param in + * @return new object instance. + * @throws IOException + * @throws ClassNotFoundException + */ + public T restore(ObjectInputStream in) + throws IOException, ClassNotFoundException; +} Modified: river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/StorableResource.java URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/StorableResource.java?rev=1879521&r1=1879520&r2=1879521&view=diff ============================================================================== --- river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/StorableResource.java (original) +++ river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-dl/src/main/java/org/apache/river/outrigger/proxy/StorableResource.java Sun Jul 5 11:41:39 2020 @@ -1,34 +1,34 @@ -/* - * 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.outrigger; - -import org.apache.river.landlord.LeasedResource; - -/** - * Sub-interface of <code>StorableObject</code> that must be implemented by - * objects that represent leased resources and must persist their state. - * - * @param <T> - * @see LogOps - * - * @author Sun Microsystems, Inc. - * - * @since 2.0 - */ -public interface StorableResource<T extends LeasedResource> extends StorableObject<T>, LeasedResource { -} +/* + * 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.outrigger.proxy; + +import org.apache.river.landlord.LeasedResource; + +/** + * Sub-interface of <code>StorableObject</code> that must be implemented by + * objects that represent leased resources and must persist their state. + * + * @param <T> + * @see LogOps + * + * @author Sun Microsystems, Inc. + * + * @since 2.0 + */ +public interface StorableResource<T extends LeasedResource> extends StorableObject<T>, LeasedResource { +} Modified: river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-service/pom.xml URL: http://svn.apache.org/viewvc/river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-service/pom.xml?rev=1879521&r1=1879520&r2=1879521&view=diff ============================================================================== --- river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-service/pom.xml (original) +++ river/jtsk/modules/modularize/apache-river/river-services/outrigger/outrigger-service/pom.xml Sun Jul 5 11:41:39 2020 @@ -1,44 +1,54 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- -~ Copyright (C) 2014 the original author or authors. -~ -~ Licensed 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. ---> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - <modelVersion>4.0.0</modelVersion> - <parent> - <groupId>org.apache.river</groupId> - <artifactId>outrigger</artifactId> - <version>3.0-SNAPSHOT</version> - </parent> - - <groupId>org.apache.river.outrigger</groupId> - <artifactId>outrigger-service</artifactId> - <url>http://river.apache.org</url> - <name>Module :: Outrigger Service Implementation</name> - - <dependencies> - <dependency> - <groupId>org.apache.river.outrigger</groupId> - <artifactId>outrigger-dl</artifactId> - <version>${project.version}</version> - </dependency> - - <dependency> - <groupId>org.apache.river</groupId> - <artifactId>river-lib</artifactId> - <version>${project.version}</version> - </dependency> - </dependencies> -</project> +<?xml version="1.0" encoding="UTF-8"?> +<!-- ~ Copyright (C) 2014 the original author or authors. ~ ~ Licensed 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. --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.river</groupId> + <artifactId>outrigger</artifactId> + <version>3.0-SNAPSHOT</version> + </parent> + + <groupId>org.apache.river.outrigger</groupId> + <artifactId>outrigger-service</artifactId> + <url>http://river.apache.org</url> + <name>Module :: Outrigger Service Implementation</name> + + <dependencies> + + <dependency> + <groupId>org.apache.river.outrigger</groupId> + <artifactId>outrigger-dl</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.river</groupId> + <artifactId>river-logging</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.river</groupId> + <artifactId>river-lib</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.apache.river</groupId> + <artifactId>river-activation</artifactId> + <version>${project.version}</version> + </dependency> + + + + </dependencies> +</project>
