public abstract class RelatedResource extends java.lang.Object implements BitFlagsConstants
All access to instances of these resources MUST only be through static factory methods. This
means that each subclass should have a private constructor and should use the create
and open
methods in this class to manage the access. create
is used to
instantiate a new resource of a given name. Only one resource of that name is possible at
any given time. When a create
has occurred for a given name (once and only once),
any other thread needing access must use open
to obtain the instance. It is very
important that these APIs are used for access. DO NOT pass references to these resources to
other threads. Doing so will damage the reference counted resource management. Calling
create
for a named resource that already exists will cause an error.
The end of a thread's use of a resource is managed using the close
or destroy
methods. close
is used to decrement the reference count and allow the resource to
do some cleanup. When the last reference uses close
, an implicit destroy
occurs. At that point, no further usage of the resource is possible and any access will
generate an error. One may also use destroy
directly, but doing so while other
threads are accessing the resource will typically release all waiting threads and cause
errors for all subsequent access. It is OK to call create
on a name that has been
destroyed.
Each subclass must have a unique resource type name. This is used to namespace all resource instances of a given type. The names are in a format "/resource_type/instance_name" where the instance name must be unique for all instances of the same resource type. Generally, the following rules are enforced:
RUN AS-THREAD
. This
mode allows all related threads full access to all operations, without any security manager
checks. In contrast, non-local mode is a resource that can be used by any thread in the same
JVM. These threads can be related threads but they do not need to be related. In non-local
(i.e. cross-session) mode, all access is checked by the security manager to enforce security
permissions as defined in the directory. The ConcurrentResource
security plugin
implements these security checks and even related threads will have these access checks
enforced. This non-local mode allows for an arbitrarily complex inter-thread communication
pattern to be implemented (across users, batch processes, appserver agents, REST agents...)
but at the cost of additional configuration and the runtime security checks. If one can
implement in local mode it is much simpler so this is often preferred where possible.
For non-local resources, the rights are represented by a small set of flags:
create
)
destroy
)
Modifier and Type | Field and Description |
---|---|
protected boolean |
active
Flag to identify a destroyed resource.
|
private static java.lang.Object |
key
Hidden key used for storing/retrieving values between related threads.
|
private boolean |
local
Local or non-local resource.
|
protected java.lang.Object |
lock
Used to lock access to this instance.
|
protected java.lang.String |
name
The name of this resource.
|
private long |
references
Track how many threads are referencing this resource.
|
private static java.util.HashMap |
shared
Cross-session (JVM-wide) registry of resources.
|
private static SecurityManager |
sm
SecurityManager singleton instance.
|
BIT_CREATE_ACCESS, BIT_DELETE_ACCESS, BIT_DENIED_ACCESS, BIT_READ_ACCESS, BIT_WRITE_ACCESS, BITSET_SIZE
Modifier | Constructor and Description |
---|---|
protected |
RelatedResource(java.lang.String name)
Constructor.
|
Modifier and Type | Method and Description |
---|---|
protected static boolean |
checkAccess(java.lang.String name,
int perms)
Check with the security manager to see if the current context has the listed access to the
named resource.
|
void |
checkDelete()
Raise an error if the resource is non-local AND the current context does not have DELETE
access to this resource name.
|
protected static void |
checkName(java.lang.String prefix,
java.lang.String name)
Check the name raise an error if it is not valid.
|
void |
checkRead()
Raise an error if the resource is non-local AND the current context does not have READ
access to this resource name.
|
private void |
checkWorker(int perms,
java.lang.String descr)
Raise an error if the resource is non-local AND the current context does not have the
requested access to this resource name.
|
void |
checkWrite()
Raise an error if the resource is non-local AND the current context does not have WRITE
access to this resource name.
|
private void |
cleanup()
Cleanup all resources associated with this instance and set the status to destroyed.
|
void |
close()
Close the current thread's access to this resource.
|
protected static RelatedResource |
create(java.lang.String prefix,
java.lang.String iname,
java.util.function.Function<java.lang.String,? extends RelatedResource> creator,
boolean local)
Factory method which creates a new instance with the given name.
|
private boolean |
decrement()
Decrement the reference count.
|
void |
destroy()
Release all waiting threads and delete the resource.
|
protected void |
errorIfDead()
Raise an error if the resource has already been destroyed (and thus it cannot be used).
|
protected static java.lang.String |
formatName(java.lang.String prefix,
java.lang.String instance)
Confirm that the inputs are non-null and non-empty, then format as a properly namespaced
resource name (in /resource_name/instance_name format).
|
private void |
increment()
Increment the reference count.
|
private static java.util.HashMap<java.lang.String,RelatedResource> |
obtain(boolean local)
Access the internal storage used to map names to resources based on whether this is a local
or non-local request.
|
protected static RelatedResource |
open(java.lang.String prefix,
java.lang.String iname,
boolean local)
Opens an existing instance with the given name.
|
protected void |
release()
Release all waiting threads.
|
abstract java.lang.String |
resourceName()
Obtain the resource name (which makes up the prefix for valid names of this resource type).
|
WaitStatus |
status()
Reports on the status of the resource.
|
private static final java.util.HashMap shared
private static final java.lang.Object key
private static final SecurityManager sm
private long references
private boolean local
protected boolean active
protected final java.lang.String name
protected final java.lang.Object lock
protected RelatedResource(java.lang.String name)
name
- Resource name, must not be null
.protected static RelatedResource create(java.lang.String prefix, java.lang.String iname, java.util.function.Function<java.lang.String,? extends RelatedResource> creator, boolean local) throws ErrorConditionException
In non-local mode, this requires CREATE access.
prefix
- The non-null, non-empty resource type name which is a constant for all resources
of the same type. It MUST NOT contain any "/" character.iname
- The instance name, excluding the leading "/resource_type/" prefix. It MUST NOT
contain any "/" character or whitespace.creator
- Code for delegated creation of the resource.local
- true
to create a local instance (one that is only accessible between
threads in the same security context. false
creates an instance that
is accessible from any session in the JVM.ErrorConditionException
- If there was any problem in creation.protected static RelatedResource open(java.lang.String prefix, java.lang.String iname, boolean local) throws ErrorConditionException
In non-local mode, this requires READ access.
prefix
- The non-null, non-empty resource type name which is a constant for all resources
of the same type. It MUST NOT contain any "/" character.iname
- The instance name, excluding the leading "/resource_type/" prefix. It MUST NOT
contain any "/" character or whitespace.local
- true
to open a local instance (one that is only accessible between
threads in the same security context. false
opens an instance that
is accessible from any session in the JVM.ErrorConditionException
- If there was any problem in opening.public void checkRead() throws ErrorConditionException
ErrorConditionException
- If non-local and access is denied.public void checkWrite() throws ErrorConditionException
ErrorConditionException
- If non-local and access is denied.public void checkDelete() throws ErrorConditionException
ErrorConditionException
- If non-local and access is denied.public void destroy() throws ErrorConditionException
WaitStatus.DESTROYED
.
In non-local mode, this requires DELETE access.
ErrorConditionException
- If there was any problem in destroying the resource.public void close() throws ErrorConditionException
In non-local mode, this requires READ access.
ErrorConditionException
- If there was any problem in closing the resource.public WaitStatus status()
In non-local mode, this requires READ access.
WaitStatus.OK
or WaitStatus.DESTROYED
.public abstract java.lang.String resourceName()
protected static boolean checkAccess(java.lang.String name, int perms)
name
- Resource name to check.perms
- The access type requested (see BitFlagsConstants
.true
if the access is allowed.protected static java.lang.String formatName(java.lang.String prefix, java.lang.String instance) throws ErrorConditionException
prefix
- The non-null, non-empty resource type name which is a constant for all resources
of the same type. It MUST NOT contain any "/" character.instance
- The instance name, excluding the leading "/resource_type/" prefix. It MUST NOT
contain any "/" character or whitespace.ErrorConditionException
- If the inputs are invalid.protected static void checkName(java.lang.String prefix, java.lang.String name) throws ErrorConditionException
prefix
- The non-null, non-empty resource type name which is a constant for all resources
of the same type. It MUST NOT contain any "/" character.name
- The fully formatted name to check.ErrorConditionException
- If the inputs are invalid.protected void errorIfDead() throws ErrorConditionException
ErrorConditionException
- If the active flag is false
.protected void release()
lock.notifyAll()
.
Override this if the blocking mechanism is NOT using the lock
object
monitor.private static java.util.HashMap<java.lang.String,RelatedResource> obtain(boolean local)
local
- true
if this is a resource that is private to a set of related threads.
false
for resources that can be shared JVM-wide.private void cleanup() throws ErrorConditionException
ErrorConditionException
- If there was any problem in cleanup of the resources.private void increment()
private boolean decrement()
true
if there are still active references.private void checkWorker(int perms, java.lang.String descr) throws ErrorConditionException
perms
- The permissions needed (see BitFlagsConstants
).descr
- The permission name for the error message.ErrorConditionException
- If non-local and access is denied.