TIF ENOVIA/3DExperience Connector - Directory / File Listener
Some legacy systems communicate with each other by creating files in certain directories in the file system. TIF provides built-in support for setting up one or several listeners that will listen to changes in a directory (or directories) in the file-system and then perform some action.
You can listen to events in the file system like CREATE or MODIFY. By default, a directory listener will react upon the CREATE event.
When a directory listener receives an event, the processing of the file will take place a few moments later according to the configured pickup-delay (default is 3000 ms.). This pickup delay will ensure that we do not react upon multiple events for the same file, which may be the case on some Operating Systems (Windows using file-shares for example).
Configuration Details
You can set-up several directory listeners, each will then listen to different directories within the file-system.
Do not configure multiple listeners that will listen to the same or a sub-directory as another directory listeners is configured for. |
The preferred way of configuring such listener is to use the XML configuration format.
E.g. adding a file within the directory ${TIF_ROOT}/modules/enovia/cfg/directorylistener
.
By default, this directory is scanned upon startup and all configured listeners therein will be registered automatically.
You can configure this behaviour within ${TIF_ROOT}/modules/enovia/etc/module.custom.properties
via the following properties:
Property | Type | Default | Description |
---|---|---|---|
resources.directoryListener.autoRegister |
boolean |
True |
Use this property to disable the auto registration |
resources.directoryListener.excluded |
Comma separated list |
Comma separated list of resources to be excluded. |
|
resources.directoryListener.included |
Comma separated list |
Comma separated list of resources to be included. |
By default, auto registration is enabled and no resources are excluded.
XML Configuration Format
The root element is <DirectoryListener>
. The table below lists the allowed child elements:
Element | Required | Description | Example |
---|---|---|---|
|
Yes |
Defines a user friendly name of this configuration |
|
|
No |
Defines the pickup delay in milliseconds. Default is 3000. |
|
|
No |
Can be used to define a File Destination that defines the directory where to listen from. Either this is defined OR the |
|
|
Yes, unless a |
Defines input/output/error paths. |
See below. |
|
No |
Define file system events to react upon. Default is CREATE event only. |
|
No |
Defines if to establish an ENOVIA/3DEXPERIENCE context |
|
|
Yes |
Defines the handler containing your businesslogic that is processing the message |
|
|
The <Paths>
element supports the following attributes.
- recurse
-
A boolean specifying if to register to sub-directories also. Default is true
- processExistingOnStartup
-
A boolean specifying if to process files in the input directory upon startup. Default is true.
- registerNewDirectories
-
A boolean specifying if to register new directories created within the monitored file-area. Default is true.
- delete
-
Whether or not to delete the file after it has been processed.
If donePath and/or errorPath has been set then the file is moved instead of being deleted, even if delete flag is set to true.
|
The <Paths>
element supports the following child elements.
Element | Required | Description | Example |
---|---|---|---|
|
Yes |
Defines input directory. Use multiple |
|
|
No |
Defines a directory, which files are moved to upon successful processing |
|
|
No |
Defines a directory, which files are moved to upon an error |
|
The <Events>
element supports the following child elements.
Element | Required | Description |
---|---|---|
|
No |
React upon create events |
|
No |
React upon modify events |
|
No |
React upon delete events |
Leaving the Events out implies reacting upon Create events. |
The <WithContext>
element supports the following attributes.
Attribute | Required | Description |
---|---|---|
user |
No |
If omitted, the super user will be used |
securityContext |
No |
Defines the security context to be used |
useDefaultSecurityContext |
No |
If set to true, the default security context for the user will be used. The used user must have a default security context otherwise an error will be raised. |
The <Handler>
element supports one of these three attributes
- className
-
The name of a class implementing
com.technia.tif.enovia.file.WatcherHandler
. See chapter below. - script
-
Name of a script resource. Example:
script="tvc:script/MyHandler.js"
. See chapter below. - type
-
Name of a pre-defined type. Example:
type="SomePredefinedType"
Example configuration:
<tif:DirectoryListener
xmlns:tif="http://technia.com/TIF/DirectoryListener"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://technia.com/TIF/DirectoryListener file:///C:/apps/tif-server/modules/enovia/schema/DirectoryListener.xsd">
<tif:Name>Test Listener</tif:Name>
<tif:Paths>
<tif:Input>/test/a/input</tif:Input>
<tif:Output>/test/a/done</tif:Output>
<tif:Error>/test/a/error</tif:Error>
</tif:Paths>
<tif:WithContext />
<tif:Handler className="com.acme.integrations.part.DefaultMessageReceiver" />
</tif:AMQPListener>
When TIF is running in development mode, you can edit, create or delete configurations at runtime and those will be hot deployed automatically without the need to restart the TIF instance or take any further action. However, in production mode, you can only edit a definition at runtime, but in order to take the changes into use you need to restart the corresponding service activator from within the Administration UI. Add or delete configurations is not supported. See also this chapter for more info |
Registration via Module Properties
The recommended way of registering a directory listener is to use the XML configuration format as described in the previous chapter.
However, you may still register a listener from with the module properties file. E.g. using the file
${TIF_ROOT}/modules/enovia/etc/module.custom.properties
.
Below is an example configuration:
directoryListener.0.enabled = true
directoryListener.0.name = A User Friendly Name
directoryListener.0.directories = /var/integration/erp
directoryListener.0.recurse = true
directoryListener.0.className = com.acme.integrations.ERPDirectoryListener
directoryListener.0.context = true
directoryListener.0.context.user = ...
directoryListener.0.context.securityContext = ..
directoryListener.0.context.useDefaultSecurityContext = true|false
The prefix of a directory listener is directoryListener.<ID>.
where <ID>
is a unique identifier containing letters and/or digits.
The available property suffices are shown in the table below.
Property Suffix | Description | Required | Default |
---|---|---|---|
name |
Defines a user friendly name of the service, used for example in the Admin UI |
No |
Default the name is equal to the ID |
enabled |
Defines if the directory listener should be enabled or not. |
No |
True |
directories |
The directories to listen for changes in. Use ";" (semi-colon) on Windows to separate multiple directories and ":" (colon) on UNIX. |
Yes |
|
recurse |
Whether or not if to recursively listen to changes in directories below the specified. |
No |
True |
deleteFile |
Whether or not to delete the file after it has been processed. Note that if the |
No |
False |
donePath |
Specifies a directory, to which successfully processed files will be moved into |
No |
|
errorPath |
Specifies a directory, to which processed files that failed will be moved into |
No |
|
events |
Specifies a comma separated list of events that we should react upon. Possible values are
|
No |
create |
pickupDelay |
Specifies the delay in milliseconds to delay the processing of the file |
No |
3000 |
processExistingOnStartup |
Specifies if to process existing files in the directories we watch upon startup. Note that this flag should not be set to true in case you choose to NOT delete the files nor move it after processing. Otherwise the same files will be processed every time you start TIF, or restart the particular service. |
No |
True |
registerNewDirectories |
Specifies if to register new directories being added as being watched. Note that this will only have effect if also the recurse flag is set to true. |
No |
True |
context |
A boolean value indicating if an ENOVIA/3DEXPERIENCE context object should be allocated when the handler is invoked. |
No. |
False. |
context.user |
An optional name of a ENOVIA/3DEXPERIENCE user (used if context = true). May be omitted to indicate that the default ENOVIA/3DEXPERIENCE system-user should be used. |
No |
Defaults to the system user. |
context.securityContext |
Specify ENOVIA/3DEXPERIENCE security context. |
No |
|
context.useDefaultSecurityContext |
Specify to use the default security context on the user. |
No |
False |
className |
Defines a fully qualified class name of a Java class implementing "com.technia.tif.enovia.file.WatcherHandler". See below. |
One of the attributes |
|
script |
A script that implements the same functionality as a corresponding Java class. See below. |
Example registration:
directoryListener.0.enabled = true
directoryListener.0.directories = /var/integration/erp
directoryListener.0.recurse = false
directoryListener.0.context = true
directoryListener.0.donePath = /var/integration/erp/succeeded
directoryListener.0.errorPath = /var/integration/erp/failed
directoryListener.0.className = com.acme.tif.FileProcessor
Java Class
The Java class pointed out via the className attribute must implement the interface com.technia.tif.enovia.file.WatcherHandler
in TIF. This Watcher-Handler API looks like:
package com.technia.tif.enovia.file;
import java.nio.file.Path;
/**
* @author Technia
*/
public interface WatcherHandler {
/**
* @param event The event causing this call
* @param p The path
*/
void handleEvent(WatchEvent event, Path p);
}
The first argument to the "handleEvent" is an enum instance, which may have the following values:
WatchEvent.CREATE WatchEvent.MODIFY WatchEvent.DELETE
Script
Instead of implementing the WatcherHandler as a traditional Java class you may implement this in a script file.
Scripts are stored and handled as a XML resource file, described in chapter [XXX].
Example:
directoryListener.TEST.script = DirectoryListener.js
or
directoryListener.TEST.script = tvc:script/DirectoryListener.js
or
directoryListener.TEST.script = tvc:script:domain/DirectoryListener.js
A directory listener implemented as a script has the same method signature as the corresponding Java-class implementation.
function handleEvent(type, path) {
if (type == "CREATE") {
} else if (type == "DELETE") {
} else if (type == "MODIFY") {
}
}
The last argument is an object of type java.nio.file.Path