Class NamedResourceHandler<R>
- Type Parameters:
R
- The type of the configuration object that is stored in the resources.
- All Implemented Interfaces:
Lifecycle
- Direct Known Subclasses:
FontManagerImpl
,IconManagerImpl
,ThemeManagerImpl
This class acts as an abstraction layer for handling named configuration resources. These resources are stored
using the gateway's ConfigurationManager
, and could be accessed directly using that API, but most subsystems
find it more convenient to use this class to interact with their resources.
This class takes care of details like the following:
- Loading resources from the correct resource collection, so that subsystems don't need to worry about details like loading from core, local, or what the active deployment mode is.
- Using a
ResourceCollectionLifecycleFactory
to correctly listen for resource changes. These changes are packaged up and delivered to subclasses using the various on* methods (likeonInitialResources(List)
andonResourcesUpdated(List)
) - Using the
ResourceTypeMeta
and it'sResourceCodec
to encode and decode the configuration stored within the resource's config.json data file. By the time resources are delivered to subclasses of this method, they are already decoded into the appropriate configuration object and wrapped in aDecodedResource
object. If resources cannot be decoded because of aDecodingException
, they are simply treated as if they don't exist. This means that if a resource is updated and becomes un-decodable, it will be as if the resource was deleted (onResourceRemoved(DecodedResource)
will be invoked. If the resource is later modified and becomes decode-able, it will be presented as if it is an added resource. (onResourceAdded(DecodedResource)
will be invoked). - Gracefully handles renaming resources, including detection and updating any references to the renamed resource.
- Understands and listens for changes to the gateway's redundancy role, and will automatically switch to using backup configuration objects (backupConfig.json) when the gateway is in a backup role.
To use this class, you can either:
- Extend it and override the various on* methods to handle resource changes
- Use the
NamedResourceHandler.Builder
by callingnewBuilder(ResourceTypeMeta)
to create an instance of this class, and provide callbacks for the various resource change events.
- See Also:
-
Nested Class Summary
Nested Classes -
Field Summary
FieldsModifier and TypeFieldDescriptionprotected final ConfigurationManager
protected final org.slf4j.Logger
protected final ResourceTypeMeta<R>
-
Constructor Summary
ConstructorsModifierConstructorDescriptionprotected
NamedResourceHandler
(ConfigurationManager configManager, RedundancyManager redundancyManager, ResourceTypeMeta<R> meta) protected
NamedResourceHandler
(GatewayContext context, ResourceTypeMeta<R> meta) -
Method Summary
Modifier and TypeMethodDescriptionPass through forcreate(String, Object, String)
with a null actor, indicating the source of the new resource is now known or unspecified.Pass through forcreate(String, Object, String, Consumer)
with a null customizer, indicating that no additional customization is needed.Creates a new resource, with a UUID attribute derived bynewUuid(Object)
.protected Optional<DecodedResource<R>>
delete
(String name, ReferenceHandling referencePolicy) protected boolean
filter
(DecodedResource<R> resource) This method is called to filter out resources that should not be included in the handler's list of resources.findResource
(String name) Find a resource by name.protected boolean
protected boolean
Override this and return true (the default is false) to enable rename handling.Modifies an existing resource.static <R> NamedResourceHandler.Builder<R>
newBuilder
(ResourceTypeMeta<R> meta) protected @NotNull UUID
Override if your config object contains/provides its own UUID.protected void
onInitialResources
(List<DecodedResource<R>> resources) Called once at startup with the resource that are already present in the configuration collection.protected void
onResourceAdded
(DecodedResource<R> newResource) Called once per each resource that is added.protected void
onResourceRemoved
(DecodedResource<R> removedResource) Called for resources that are removed (or updated and then fail to parse).protected void
onResourcesUpdated
(List<DecodedResource<R>> resources) Called each time the overall set of resources changes in any way.protected void
onResourceUpdated
(ModifiedResource<R> modifiedResource) Called once per each resource that is updated.protected void
protected void
renameAndModify
(String oldName, String newName, R config) Renames and modifies an existing resource.renameAndModify
(String oldName, String newName, R config, String actor) renameAndModify
(String oldName, String newName, R config, String actor, Consumer<ResourceBuilder> customizer) renameAndModify
(String oldName, String newName, R config, String actor, Consumer<ResourceBuilder> customizer, ReferenceHandling referencePolicy) Methods inherited from class com.inductiveautomation.ignition.common.lifecycle.AbstractLifecycle
isRunning, shutdown, startup
-
Field Details
-
logger
protected final org.slf4j.Logger logger -
meta
-
configManager
-
-
Constructor Details
-
NamedResourceHandler
-
NamedResourceHandler
protected NamedResourceHandler(ConfigurationManager configManager, @Nullable RedundancyManager redundancyManager, ResourceTypeMeta<R> meta)
-
-
Method Details
-
getResources
- Returns:
- an unmodifiable list of the resources currently in the configuration collection for the active mode.
-
findResource
Find a resource by name.- Parameters:
name
- The name of the resource. Case-sensitivity is determined byisCaseSensitive()
- Returns:
- An optional containing the decoded resource if it exists, or empty if it does not. The object inside
the decoded resource is provided by
ResourceTypeMeta.getCodec()
that was passed to the constructor of this handler.
-
create
Pass through forcreate(String, Object, String)
with a null actor, indicating the source of the new resource is now known or unspecified.- Throws:
PushException
- See Also:
-
create
public CompletableFuture<Void> create(String name, R config, @Nullable String actor) throws PushException Pass through forcreate(String, Object, String, Consumer)
with a null customizer, indicating that no additional customization is needed.- Throws:
PushException
- See Also:
-
create
public CompletableFuture<Void> create(String name, R config, @Nullable String actor, Consumer<ResourceBuilder> customizer) throws PushException Creates a new resource, with a UUID attribute derived bynewUuid(Object)
. The resource will be created in the collection specified byResourceTypeMeta.getPreferredCollection()
- Parameters:
name
- The name of the resource to be created.config
- The configuration object to be stored in the resource.actor
- A string representing the actor responsible for the change. If null,"unknown"
will be used.customizer
- A consumer that can be used to customize the resource before it is created.- Throws:
PushException
- If a resource with the same name already exists.- See Also:
-
newUuid
Override if your config object contains/provides its own UUID.- Parameters:
config
- the object that is about to be created increate(String, Object, String, Consumer)
- Returns:
- A random UUID by default.
- See Also:
-
modify
Modifies an existing resource. If the resource does not exist, this will throw a PushException. Will first fetch the existing resource, so that the resource is modified in its defining collection.- Throws:
PushException
-
modify
- Throws:
PushException
-
modify
public CompletableFuture<Void> modify(String name, R config, @Nullable String actor, Consumer<ResourceBuilder> customizer) throws PushException - Throws:
PushException
-
renameAndModify
public CompletableFuture<Void> renameAndModify(String oldName, String newName, R config) throws PushException Renames and modifies an existing resource. This is actually a create followed by a delete. By using this method, the delete and create will be performed in a single, atomic push, which consolidates the updates to listeners.- Throws:
PushException
-
renameAndModify
public CompletableFuture<Void> renameAndModify(String oldName, String newName, R config, @Nullable String actor) throws PushException - Throws:
PushException
-
renameAndModify
public CompletableFuture<Void> renameAndModify(String oldName, String newName, R config, @Nullable String actor, Consumer<ResourceBuilder> customizer) throws PushException - Throws:
PushException
-
renameAndModify
public CompletableFuture<Void> renameAndModify(String oldName, String newName, R config, @Nullable String actor, Consumer<ResourceBuilder> customizer, ReferenceHandling referencePolicy) throws PushException - Throws:
PushException
-
delete
- Throws:
PushException
-
delete
public CompletableFuture<Void> delete(String name, ReferenceHandling referencePolicy) throws PushException - Throws:
PushException
-
onInitialResources
Called once at startup with the resource that are already present in the configuration collection. -
onResourceAdded
Called once per each resource that is added. -
onResourceUpdated
Called once per each resource that is updated.Note that whether "rename" events are considered "updates" or "removes" and "adds" is determined by
isRenameAware()
. -
onResourceRemoved
Called for resources that are removed (or updated and then fail to parse). -
onResourcesUpdated
Called each time the overall set of resources changes in any way. Called after added, updated, and removed are called. -
onStartup
protected void onStartup()- Specified by:
onStartup
in classAbstractLifecycle
-
onShutdown
protected void onShutdown()- Specified by:
onShutdown
in classAbstractLifecycle
-
decode
-
filter
This method is called to filter out resources that should not be included in the handler's list of resources. By default, this method filters out resources that are not enabled.
Note that resources which do not pass this filter (i.e. return false) will be "invisible" to the handler. For example, if a resource first passes the filter, and is loaded, but is then modified later and no longer passes, the handler will see this as a removal of that resource.
- Parameters:
resource
- the resource to process- Returns:
true
if the resource should be included in the handler's list of resources,false
otherwise.
-
isCaseSensitive
protected boolean isCaseSensitive()- Returns:
- if the name handling in
findResource(String)
is considered case-sensitive (true) or not (false)
-
isRenameAware
protected boolean isRenameAware()Override this and return true (the default is false) to enable rename handling. When enabled, the handler will use Resource "uuid"s to identify resources that have been renamed. So, rather than a rename looking like a "delete" event followed by an "add" event, it will instead be aonResourceUpdated(ModifiedResource)
invocation whereModifiedResource.isRename()
is true.Note that if this is enabled, all resources must have a valid uuid attribute. Any resources missing this attribute will be treated as if they don't exist.
-
newBuilder
-