Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Cleaning, deleting and reorganising

git-svn-id: https://svn.apache.org/repos/asf/river/jtsk/trunk@1302083 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information...
commit 1fa705cdeda179540b038bb28d7a6bce51c08001 1 parent 5b2f084
Peter Firmstone authored
View
6 build.xml
@@ -362,6 +362,9 @@
<package name="net.jini.url.file"/>
<package name="net.jini.url.httpmd"/>
<package name="net.jini.url.https"/>
+ <package name="org.apache.river.api.lookup"/>
+ <package name="org.apache.river.api.security"/>
+ <package name="org.apache.river.api.util"/>
</javadoc>
<mkdir dir="${doc.api.dir}/doc-files"/>
<copy file="NOTICE" tofile="${doc.api.dir}/doc-files/NOTICE.txt"/>
@@ -523,6 +526,7 @@
<copy todir="lib">
<fileset refid="asm.jars"/>
<fileset refid="high-scale-lib.jars"/>
+ <fileset refid="reference-collections.jar"/>
</copy>
</target>
@@ -2176,7 +2180,7 @@
<target name="prep-tests" depends="">
<mkdir dir="${test.classes.dir}"/>
<mkdir dir="${test.results.dir}"/>
- <copy file="high-scale-lib/high-scale-lib.jar" todir="test/lib"/>
+ <copy file="dep-libs/high-scale-lib/high-scale-lib.jar" todir="test/lib"/>
</target>
<target name="clean-tests" depends="">
View
9 qa/build.xml
@@ -207,6 +207,8 @@
<file name="phoenix-init.jar"/>
<file name="tools.jar"/>
<file name="classserver.jar"/>
+ <file name="reference-collections-1.0.0.jar"/>
+ <file name="high-scale-lib.jar"/>
</filelist>
</move>
<move file="${river.lib-ext.dir}/jsk-policy.jar" todir="${jtreg.dir}/JTlib-tmp"/>
@@ -214,7 +216,7 @@
errorproperty="jtreg.fail" failureproperty="jtreg.fail"
reportdir="${jtreg.dir}/JTreport" workdir="${jtreg.dir}/JTwork"
jdk="${jdk1.5.home}">
- <arg value="-cpa:${jtlib.tmp}/jsk-policy.jar${path.separator}${jtlib.tmp}/jsk-lib.jar${path.separator}${jtlib.tmp}/jsk-platform.jar${path.separator}${jtlib.tmp}/jsk-resources.jar${path.separator}${jtlib.tmp}/phoenix-init.jar${path.separator}${jtlib.tmp}/tools.jar${path.separator}${jtlib.tmp}/classserver.jar"/>
+ <arg value="-cpa:${jtlib.tmp}/jsk-policy.jar${path.separator}${jtlib.tmp}/jsk-lib.jar${path.separator}${jtlib.tmp}/jsk-platform.jar${path.separator}${jtlib.tmp}/jsk-resources.jar${path.separator}${jtlib.tmp}/phoenix-init.jar${path.separator}${jtlib.tmp}/tools.jar${path.separator}${jtlib.tmp}/classserver.jar${path.separator}${jtlib.tmp}/reference-collections-1.0.0.jar${path.separator}${jtlib.tmp}/high-scale-lib.jar"/>
<arg value="-timeout:8"/>
<!--<arg value="-Djsk.home=${river.home}"/>-->
<arg value="-Djtlib.tmp=${jtlib.tmp}"/>
@@ -251,6 +253,8 @@
<file name="phoenix-init.jar"/>
<file name="tools.jar"/>
<file name="classserver.jar"/>
+ <file name="reference-collections-1.0.0.jar"/>
+ <file name="high-scale-lib.jar"/>
</filelist>
</move>
<move file="${jtreg.dir}/JTlib-tmp/jsk-policy.jar" todir="${river.lib-ext.dir}"/>
@@ -269,6 +273,8 @@
<file name="phoenix-init.jar"/>
<file name="tools.jar"/>
<file name="classserver.jar"/>
+ <file name="reference-collections-1.0.0.jar"/>
+ <file name="high-scale-lib.jar"/>
</filelist>
</move>
<move file="${jtreg.dir}/JTlib-tmp/jsk-policy.jar" todir="${river.lib-ext.dir}"/>
@@ -331,6 +337,7 @@
<include name="jsk-platform.jar"/>
<include name="jsk-lib.jar"/>
<include name="high-scale-lib.jar"/>
+ <include name="reference-collections-1.0.0.jar"/>
</fileset>
</classpath>
<env key="SOUL" value="${soul}"/>
View
2  qa/src/com/sun/jini/qa/harness/TestDescription.java
@@ -605,7 +605,7 @@ String getWrapperClassName() {
// Uncomment the following line if you want to debug permission requests
// cmdList.add("-Djava.security.manager=com.sun.jini.tool.ProfilingSecurityManager");
// cmdList.add("-Djava.security.manager=java.lang.SecurityManager");
- cmdList.add("-Djava.security.manager=org.apache.river.api.security.DelegateCombinerSecurityManager");
+ cmdList.add("-Djava.security.manager=org.apache.river.api.security.CombinerSecurityManager");
cmdList.add("-Djava.security.policy=" + getPolicyFile());
if (getCodebase() != null) {
cmdList.add("-Djava.rmi.server.codebase=" + getCodebase());
View
6 qa/src/com/sun/jini/qa/resources/qaDefaults.properties
@@ -214,7 +214,7 @@ com.sun.jini.qa.harness.actdeathdelay=5
# You might find the following debugging options useful
# -Djava.security.debug=access:failure,\
# -Djava.security.manager=com.sun.jini.tool.ProfilingSecurityManager,\
-# -Djava.security.manager=org.apache.river.api.security.DelegateCombinerSecurityManager,\
+# -Djava.security.manager=org.apache.river.api.security.CombinerSecurityManager,\
# -Dpolicy.provider=net.jini.security.policy.DynamicPolicyProvider,\
# -Djava.security.manager=java.rmi.RMISecurityManager,\
@@ -252,11 +252,11 @@ testPolicyfile=<url:harness/policy/defaulttest.policy>
# The default classpath. This property must be defined, and must include
# all Jini dependencies as components
-testClasspath=<harnessJar>$:<testJar>$:${com.sun.jini.jsk.home}$/lib$/jsk-platform.jar$:${com.sun.jini.jsk.home}$/lib$/jsk-lib.jar$:${com.sun.jini.jsk.home}$/lib$/high-scale-lib.jar
+testClasspath=<harnessJar>$:<testJar>$:${com.sun.jini.jsk.home}$/lib$/jsk-platform.jar$:${com.sun.jini.jsk.home}$/lib$/jsk-lib.jar$:${com.sun.jini.jsk.home}$/lib$/high-scale-lib.jar$:${com.sun.jini.jsk.home}$/lib$/reference-collections-1.0.0.jar
# Alternate test classpath, for tests that don't use <testJar>
#
-altClasspath=<harnessJar>$:${com.sun.jini.jsk.home}$/lib$/jsk-platform.jar$:${com.sun.jini.jsk.home}$/lib$/jsk-lib.jar$:${com.sun.jini.jsk.home}$/lib$/high-scale-lib.jar
+altClasspath=<harnessJar>$:${com.sun.jini.jsk.home}$/lib$/jsk-platform.jar$:${com.sun.jini.jsk.home}$/lib$/jsk-lib.jar$:${com.sun.jini.jsk.home}$/lib$/high-scale-lib.jar$:${com.sun.jini.jsk.home}$/lib$/reference-collections-1.0.0.jar
#
# Services run with server vm; test runs with client vm
View
32 src/net/jini/security/policy/DynamicPolicyProvider.java
@@ -19,6 +19,7 @@
package net.jini.security.policy;
import org.apache.river.api.security.ConcurrentPolicy;
+import org.apache.river.api.security.ConcurrentPolicyFile;
import java.io.IOException;
import java.rmi.RemoteException;
import org.apache.river.api.security.CachingSecurityManager;
@@ -79,10 +80,7 @@
* by granting additional permissions, this implementation adds an experimental
* feature for revoking permissions, however there are some caveats:</p>
*
- * <p>Background: if ProtectionDomain.toString(), is called a ProtectionDomain will
- * merge Permissions, from the policy with those in the ProtectionDomain,
- * in a new private instance of Permissions, thus a ProtectionDomain cannot have
- * Permission's removed, only additional merged. A ProtectionDomain must
+ * <p>A ProtectionDomain must
* be created with the dynamic constructor otherwise it will never consult
* the policy. The AccessController.checkPermission(Permission) method
* consults the current AccessControlContext, which contains all
@@ -115,28 +113,19 @@
*
* <p>So in order to prevent dynamic grants from finding
* their way into a ProtectionDomain's private PermissionCollection,
- * one would have to ensure that no dynamically grantable permissions are
+ * this policy ensures that no dynamically grantable permissions are
* returned via the method:</p>
* <p>
- * getPermissions(ProtectionDomain domain) and
* getPermissions(Codesource source) as a precaution.
* </p>
- * <p>This is different to the behaviour of the existing Jini 2.0
+ * <p>This is different to the behaviour of the previous Jini 2.0
* DynamicPolicyProvider implementation where dynamically granted Permissions
- * are added and can escape into the ProtectionDomain's private PermissionCollection.
- *
- * However when a Policy is checked via implies(ProtectionDomain d, Permission p)
- * this implementation checks the dynamic grants
- *
- * This means that if a DynamicPolicy is utilised as the base Policy class
- * and if it returns dynamically granted permissions, then those permissions
- * cannot be revoked.</p>
+ * could escape into the ProtectionDomain's private PermissionCollection.
+ * /p>
* <p>
* It is thus recommended that Static policy files only be used for setting
* up your privileged code and use UmbrellaGrantPermission's and grant
- * all other Permission's using dynamic grants. This minimises the double
- * checking of Permission, that occurs when a ProtectionDomain is constructed
- * so it contains a default PermissionCollection that is not null.
+ * all other Permission's using dynamic grants.
*
* </p><p>
* To make the best utilisation of this Policy provider, set the System property:
@@ -144,14 +133,11 @@
* net.jini.security.policy.PolicyFileProvider.basePolicyClass =
* org.apache.river.security.concurrent.ConcurrentPolicyFile
* </p>
- * @author Peter Firmstone
- * @version 1
- * @since 2.2
+ * @since 2.0
* @see ProtectionDomain
* @see Policy
* @see ConcurrentPolicyFile
* @see net.jini.security.policy.PolicyFileProvider
- * @see ConcurrentPermissionCollection
* @see CachingSecurityManager
* @see RemotePolicy
*/
@@ -330,7 +316,7 @@ public DynamicPolicyProvider(Policy basePolicy){
policyPermissions.setReadOnly();
}
- /**
+ /*
* OLD COMMENT:
*
* Ensures that any classes depended on by this policy provider are
View
3  src/org/apache/river/api/lookup/DefaultEntries.java
@@ -37,7 +37,8 @@
* Note: This class is not threadsafe, use external synchronization if required.
*
* Suggested by Dan Creswell.
- * @author peter
+ * @author Peter Firmstone.
+ * @since 2.2.1
*/
public class DefaultEntries {
private final Set<Class> entrys;
View
1  src/org/apache/river/api/lookup/ServiceItemClasspathSub.java
@@ -54,6 +54,7 @@
* by calling #getServiceItem().
* </p>
* @author Peter Firmstone.
+ * @since 2.2.1
*/
public abstract class ServiceItemClasspathSub extends ServiceItem{
private static final long SerialVersionUID = 1L;
View
1  src/org/apache/river/api/lookup/ServiceResultStreamFilter.java
@@ -39,6 +39,7 @@
* New instances can be created as required.
* <p>
* @author Peter Firmstone.
+ * @since 2.2.1
*/
public class ServiceResultStreamFilter implements ResultStream<ServiceItem> {
private final List<ServiceItemFilter> filters;
View
1  src/org/apache/river/api/lookup/ServiceResultStreamUnmarshaller.java
@@ -31,6 +31,7 @@
* proxy verification, or applying constraints.
*
* @author Peter Firmstone.
+ * @since 2.1.1
* @see ServiceItemClasspathSub.
* @see StreamServiceRegistrar
*/
View
8 src/org/apache/river/api/lookup/StreamServiceRegistrar.java
@@ -37,16 +37,12 @@
* (on both StreamServiceRegistrar and ServiceRegistration) is atomic with
* respect to other invocations.
* <p></p>
- * The StreamServiceRegistrar is intended to perform the same function
- * as the ServiceRegistrar, but with the ability to return results as a
+ * StreamServiceRegistrar is intended to perform the same function
+ * as ServiceRegistrar, but with the ability to return results as a
* stream, so memory consumption is minimised at the client and network
* communication is minimised between the client and lookup service server.
- * <p></p>
- * All clients utilising ServiceRegistrar, should switch to the
- * StreamServiceRegistrar.
* <p>
* @see ServiceRegistrar
- * @see PortableServiceRegistrar
* @see ServiceRegistration
* @author Peter Firmstone
* @since 2.2.1
View
1  src/org/apache/river/api/security/CachingSecurityManager.java
@@ -32,6 +32,7 @@
* See "Inside Java 2 Platform Security" 2nd Edition, ISBN:0-201-78791-1, page 176.
*
* @author Peter Firmstone.
+ * @since 2.2.1
*/
public interface CachingSecurityManager {
View
7 src/org/apache/river/api/security/CombinerSecurityManager.java
@@ -54,9 +54,12 @@
/**
* CombinerSecurityManager, is intended to be a highly scalable
- * SecurityManager implementation that softly caches the results of security checks
+ * SecurityManager implementation that caches the results of security checks
* for each context, which may be an instance of SecurityContext or
- * AccessControlContext.
+ * AccessControlContext. Stale records are pruned from the cache.
+ *
+ * The cache utilises Cliff Click's NonBlockingHashMap and Doug Lee's
+ * ConcurrentSkipListSet.
*
* This SecurityManager should be tuned for garbage collection for a large
* young generation heap, since many young objects are created and discarded.
View
10 src/org/apache/river/api/security/ConcurrentPermissions.java
@@ -19,7 +19,6 @@
package org.apache.river.api.security;
import java.io.Serializable;
-import java.lang.reflect.Constructor;
import java.security.AllPermission;
import java.security.Permission;
import java.security.PermissionCollection;
@@ -41,11 +40,11 @@
/**
- * ConcurrentPermission's is a replacement for java.security.Permissions.
+ * ConcurrentPermissions is a replacement for java.security.Permissions.
*
* This was originally intended to be used as a policy cache, it turns out
- * that a policy cache is not needed, due to the efficiency of
- * URLGrant.implies(ProtectionDomain pd). Scalability is better without
+ * that a policy cache is not needed, due to the efficiency of package private
+ * URIGrant.implies(ProtectionDomain pd). Scalability is better without
* a policy cache because PermissionGrant's are immutable, have no mutable shared
* state and are therefore not likely to causing cache misses.
*
@@ -73,9 +72,10 @@
* added during an Enumeration.
*
* TODO: Serialization properly
- * @version 0.4 2009/11/10
+ * @version 0.5 2012/04/18
*
* @author Peter Firmstone
+ * @since 2.2.1
* @serial permsMap
*/
public final class ConcurrentPermissions extends PermissionCollection
View
23 src/org/apache/river/api/security/ConcurrentPolicyFile.java
@@ -57,19 +57,22 @@
/**
+ * <p>
* Concurrent Policy implementation based on policy configuration files,
* it is intended to provide concurrent implies() for greatly improved
- * throughput at the expense of memory usage.
- *
+ * throughput. Caching limits scalability and consumes shared memory,
+ * so no cache exists.
+ * </p><p>
* Set the following system properties to use this Policy instead of the
* built in Java sun.security.provider.PolicyFile:
- *
+ * </p>
+ * <pre>
* net.jini.security.policy.PolicyFileProvider.basePolicyClass =
* org.apache.river.security.concurrent.ConcurrentPolicyFile
- *
+ * </pre>
*
* This
- * implementation recognizes text files, consisting of clauses with the
+ * implementation recognises text files, consisting of clauses with the
* following syntax:
*
* <pre>
@@ -154,13 +157,9 @@
* </dl>
* <br>
* <br>
- * This implementation is thread-safe. The policy caches sets of calculated
- * permissions for the requested objects (ProtectionDomains and CodeSources) via
- * WeakHashMap; the cache is cleaned either explicitly during refresh()
- * invocation, or naturally by garbage-collecting the corresponding objects.
- *
- * @see org.apache.harmony.security.PolicyUtils#getPolicyURLs(Properties, String,
- * String)
+ * This implementation is thread-safe and scalable.
+ * @author Peter Firmstone.
+ * @since 2.2.1
*/
public class ConcurrentPolicyFile extends Policy implements ConcurrentPolicy {
View
1  src/org/apache/river/api/security/PermissionComparator.java
@@ -49,6 +49,7 @@
* FilePermissionCollection.
*
* @author Peter Firmstone.
+ * @since 2.2.1
*/
public class PermissionComparator implements Comparator<Permission>, Serializable {
private static final long serialVersionUID = 1L;
View
22 src/org/apache/river/api/security/PermissionGrant.java
@@ -25,12 +25,12 @@
import java.util.Collection;
/**
- * PermissionGrant's are expected to be effectively immutable,
+ * PermissionGrant implementations are expected to be immutable,
* thread safe and have a good hashCode implementation to perform well in
* Collections.
*
- * You shouldn't pass around PermissionGrant's to just anyone as they can
- * provide an attacker with information about which Permissions may be granted.
+ * You shouldn't pass around PermissionGrant's to just anyone; they can
+ * provide an attacker with information about granted Permissions.
*
* Caveat Implementor: PermissionGrant's cannot perform privileged actions,
* whilst being used by the policy to make policy decisions, any privileged
@@ -38,9 +38,10 @@
* Only PermissionGrant's belonging to the same ProtectionDomain as the
* active Policy can perform PrivilegedAction's, since the Policy caches it's
* own domain Permissions during initialisation, it doesn't consult
- * PermissionGrant's after.
+ * PermissionGrant's thereafter.
*
* @author Peter Firmstone
+ * @since 2.2.1
*/
public interface PermissionGrant {
@@ -57,11 +58,6 @@
* if it applies to a Particular ProtectionDomain, if it does, the Policy
* calls getPermissions.
*
- * Dynamic grants can be denied to some ProtectionDomains based on
- * CodeSource or URL's for codebases, this is to remove the possiblity of
- * executing Permissions for vulnerable codebases, once a vulnerability
- * is identified after the fact.
- *
* @param pd ProtectionDomain
* @return
* @see RevokeableDynamicPolicy
@@ -103,15 +99,13 @@
/**
* Returns true if this PermissionGrant defines no Permissions, or if
- * a PermissionGrant was made to a ProtectionDomain that no longer exists,
- * or if the Exclusion excludes the PermissionGrant.
- *
+ * a PermissionGrant was made to a ProtectionDomain that no longer exists.
*/
public boolean isVoid();
/**
- * Provide a suitable PermissionGrantBuilder, the user can use to
- * produce a new PermissionGrant.
+ * Provide a PermissionGrantBuilder, suitable for
+ * producing a new PermissionGrant.
*
* @return
*/
View
33 src/org/apache/river/api/security/RemotePolicy.java
@@ -24,60 +24,67 @@
import org.apache.river.api.security.PermissionGrant;
/**
- * RemotePolicy is a service implemented by a Policy Provider, that allows
- * the Policy provider to be updated remotely by a djinn group administrator.
- *
+ * <p>
+ * RemotePolicy is a service api that can be implemented by a distributed Policy service,
+ * allowing local Policy providers to be updated remotely by a djinn group administrator.
+ * </p><p>
+ * No service implementation has been provided, DynamicPolicyProvider does
+ * implement this interface to simplify creation of such a service.
+ * </p>
+ * <h2>Notes for implementors:</h2>
+ * <p>
* For security purposes, only secure jeri Endpoint's should be used and must
* require client and server authentication, in addition the proxy must be a
* reflective proxy only, as DownloadPermission should not be granted, which is
* also beneficial to reduced network load at the administrator client.
* RemotePolicy may be submitted to a lookup service, where an administrator
* client will look it up and replace PermissionGrant's periodically.
- *
+ * </p><p>
* To reduce network load, the administrator client may delay updates by
* lazily processing updates in a serial manner. New RemotePolicy services
* obtained by the administrator client's via RemoteEvent notification should
* be processed as a priority over policy updates. Eventually a djinn group
* policy should reach equilibrium where all nodes have had their policy's
* updated.
- *
+ * </p><p>
* This policy, in addition to any local policy provider, allows a network djinn
* administrator to provide a list of PermissionGrant's, from a single or
* replicated remote location, distributed to all nodes in a djinn that
* administrator is responsible for. Every time the administrator updates
* his network policy, he can use a RemoteEvent notification system to be
* notified for any new RemotePolicy registrations.
- *
+ * </p><p>
* In addition, replicating administrator clients may register a pseudo RemotePolicy
* in order to track the primary administrator client and take over in the
* event it fails. Failure may be failure to authenticate or failure to renew
* a Lease.
- *
+ * </p><p>
* RemotePolicy, if it encapsulates an underlying RemotePolicy, does not
* delegate updates to the base RemotePolicy, this is in case an
* implementer wants a number of different layers of RemotePolicy, where
* each layer represents a different administrator role or responsibility.
* The administrator's subject must hold the necessary permissions in order
* to grant them, including RuntimePermission("getProtectionDomain").
- *
+ * </p><p>
* A node may join more than one djinn group, in this case RemotePolicy's may
* be used as nested basePolicy's.
- *
+ * </p><p>
* The intent of RemotePolicy is to make granting of DowloadPermission to
* new signer Certificates and adding new Principals and Permission's to
* distributed policy providers.
- *
+ * </p><p>
* Local policy files should be used to restrict the Permissions grantable
* via a RemotePolicy.
- *
+ * </p><p>
* PermissionGrant's that are replaced and no longer exist in the RemotePolicy
* will no longer be implied by the policy.
- *
+ * </p><p>
* DefaultPolicyParser has been provided for an administrator client to
* parse standard java format policy file's, to create PermissionGrant's
* custom policy file formats may be used by extending DefaultPolicyScanner.
- *
+ * </p>
* @author Peter Firmstone
+ * @since 2.2.1
* @see GrantPermission
* @see UmbrellaGrantPermission
* @see PolicyParser
View
60 src/org/apache/river/api/security/package.html
@@ -22,55 +22,17 @@
</head>
-<body bgcolor="white">
-
-Provides an interface for security policy providers capable of dynamic
-permission grants, an interface for security manager or policy providers
-that use custom security context state, and a security policy provider
-supporting dynamic permission grants.
-<p>
-The {@link net.jini.security.policy.DynamicPolicy} interface is
-implemented by security policy providers that may support dynamic granting of
-permissions at run-time. One such provider is {@link
-net.jini.security.policy.DynamicPolicyProvider}, which layers
-dynamic grant functionality on top of a "static" security policy provider (that
-is, one incapable of dynamic permission grants itself).
-<p>
-The default static security policy used by <code>DynamicPolicyProvider</code>
-is {@link net.jini.security.policy.PolicyFileProvider}: a policy implementation
-that wraps the J2SE(TM) default
-<a href="http://java.sun.com/j2se/1.4/docs/guide/security/PolicyFiles.html">
-"PolicyFile" security policy provider</a> distributed as part of the Java(TM) 2
-Platform, Standard Edition. <code>PolicyFileProvider</code> augments the
-J2SE default policy provider with convenience constructors as well as support
-for a special-cased permission,
-{@link net.jini.security.policy.UmbrellaGrantPermission}, which signifies a
-{@link net.jini.security.GrantPermission} for all permissions authorized to a
-given protection domain.
+<body bgcolor="white"
<p>
-The {@link net.jini.security.policy.SecurityContextSource} interface is
-intended to be implemented by security managers and policy providers whose
-security contexts include state in addition to that provided by
-{@link java.security.AccessControlContext}.
-
-@since 2.0
-@version 2.0
-
-<!--
-<h2>Package Specification</h2>
-
-##### FILL IN ANY SPECS NEEDED BY JAVA COMPATIBILITY KIT #####
-<ul>
- <li><a href="">##### REFER TO ANY FRAMEMAKER SPECIFICATION HERE #####</a>
-</ul>
-
-<h2>Related Documentation</h2>
-
-For overviews, tutorials, examples, guides, and tool documentation, please see:
-<ul>
- <li><a href="">##### REFER TO NON-SPEC DOCUMENTATION HERE #####</a>
-</ul>
--->
-
+This package contains a scalable cache based security manager that parallelises
+domain security checks. Also included is a concurrent
+policy file provider to replace Java's standard offering, this policy provider
+is in theory much faster after policy file parsing is complete, it uses an immutable data
+structure that supports highly scalable concurrent access and does not require
+further disk access and minimises network and DNS requirements.
+</p><p>
+Delegates and DelegatePermission were intended inclusions in this release,
+however they have been removed and will be included in a future release of River.
+</p>
</body>
</html>
Please sign in to comment.
Something went wrong with that request. Please try again.