-
Notifications
You must be signed in to change notification settings - Fork 26
Custom registry metadata validator
The Registry simulator can be configured with a custom metadata validator that is run on each Register transaction received by the simulator. The validator is written in Groovy, installed in the External Cache, and is registered in the configuration of the simulator.
A simple example of a validator is:
import gov.nist.toolkit.testengine.engine.validations.registry.AbstractServerValidater import org.apache.axiom.om.* import gov.nist.toolkit.registrymetadata.Metadata import gov.nist.toolkit.errorrecording.ErrorRecorder class FooFoo extends AbstractServerValidater { FooFoo(ErrorRecorder er) { super(er) } /* * metadata is the container holding all the metadata objects in the submission * er is the error log you should report to if an error is detected. * */ @Override void run(Metadata metadata, ErrorRecorder er) { // every Register is declared to have an invalid code er.err('No Code', 'Invalid code', null, null, null) } }
The validator is a class that extends AbstractServerValidater. The class shown is FooFoo and it must be put in a file named FooFoo.groovy. The first method is the constructor which must be coded as shown with only the class named changed. The run method is where you put your validation logic. Errors are reported through the er.err() method.
The er.err() error reporting call has some built in flexibility. There are two variations on the call:
void err(XdsErrorCode.Code code, String msg, String location, String severity, String resource)
or
void err(String code, String msg, String location, String severity, String resource)
Where:
XdsErrorCode.Code code is one of a collection of predefined codes listed below.
String msg is an informative message.
String location indicates where in the message the problem occurred.
String severity is either "WARNING" or "ERROR" for basic error reporting. This parameter can take on other values which produce other kinds of output. More on that below.
String resource should be null.
The predefined codes are
XdsErrorCode.Code.NoCode XdsErrorCode.Code.XDSMissingDocument XdsErrorCode.Code.XDSMissingDocumentMetadata XdsErrorCode.Code.XDSRegistryNotAvailable XdsErrorCode.Code.XDSRegistryError XdsErrorCode.Code.XDSRepositoryError XdsErrorCode.Code.XDSRegistryDuplicateUniqueIdInMessage XdsErrorCode.Code.XDSRepositoryDuplicateUniqueIdInMessage XdsErrorCode.Code.XDSDuplicateUniqueIdInRegistry XdsErrorCode.Code.XDSNonIdenticalHash XdsErrorCode.Code.XDSRegistryBusy XdsErrorCode.Code.XDSRepositoryBusy XdsErrorCode.Code.XDSRegistryOutOfResources XdsErrorCode.Code.XDSRepositoryOutOfResources XdsErrorCode.Code.XDSRegistryMetadataError XdsErrorCode.Code.XDSRepositoryMetadataError XdsErrorCode.Code.XDSTooManyResults XdsErrorCode.Code.XDSExtraMetadataNotSaved XdsErrorCode.Code.XDSUnknownPatientId XdsErrorCode.Code.XDSPatientIdDoesNotMatch XdsErrorCode.Code.XDSUnknownStoredQuery XdsErrorCode.Code.XDSStoredQueryMissingParam XdsErrorCode.Code.XDSStoredQueryParamNumber XdsErrorCode.Code.XDSRegistryDeprecatedDocumentError XdsErrorCode.Code.XDSUnknownRepositoryId XdsErrorCode.Code.XDSDocumentUniqueIdError XdsErrorCode.Code.XDSPartialSuccess XdsErrorCode.Code.XDSMetadataVersionError XdsErrorCode.Code.XDSMetadataUpdateOperationError XdsErrorCode.Code.XDSMetadataUpdateError XdsErrorCode.Code.XDSMissingHomeCommunityId XdsErrorCode.Code.XDSUnknownCommunity XdsErrorCode.Code.XDSResultNotSinglePatient XdsErrorCode.Code.XDSIRequestError XdsErrorCode.Code.XDSIUnknownIdsUid XdsErrorCode.Code.ReferencesExistException XdsErrorCode.Code.XDSUnreferencedObjectException XdsErrorCode.Code.UnresolvedReferenceException
Here are some calls that can be used to report other types of information back to the user.
Challenge and ExternalChallenge produce top level headings in the log.
Errors and warnings are reported in the RegistryResponse message returned from the Register transaction and in the simulator log.
All logging information described above goes into the log associated with the simulator and can be viewed through the New Simulator Logs tab - look in the [Log] inner tab.
The Metadata class is the internal container for a metadata-based message like Register. It is built around the Axiom XML parser and the Axiom internal datatypes are used in calls and responses.
Here are some example calls:
@Override void run(Metadata metadata, ErrorRecorder er) { OMElement docEntry = metadata.extrinsicObjects[0] Iterator<OMElement> it = docEntry.getChildrenWithLocalName('Classification') boolean foundIt = false while (it.hasNext() && foundIt == false) { OMElement clas = (OMElement) it.next() if (clas.getAttributeValue(new QName('classificationScheme')) == 'urn:uuid:f4f85eac-e6cb-4883-b524-f2705394840f' && clas.getAttributeValue(new QName('nodeRepresentation')) == 'V') foundIt = true } if (!foundIt) er.err('No Code', 'Unacceptable Confidentiality code', null, null, null) }
Validators are stored in the environment area of the External Cache. They are defined within an Environment and a TestSession. The directory holding validators on my system for the default Environment and the default TestKit is
/home/bill/ExternalCache/environment/default/testkits/default/plugins/RegistryValidator
where
/home/bill/ExternalCache is the ExternalCache
environment holds all information for environments
default is the default environment
testkits is the collection of testkits defined for this environment
default is the TestKit for the default TestSession of the default environment
plugins is the plugins container
RegistryValidator holds the groovy code for all Registry validators
The above validator would be in this directory in a file FooFoo.groovy.
Most of this directory structure can be created automatically using the Create Testkit Structure function located in Toolkit Configuration.
These directories and files must be readable by the account in which Tomcat runs (the Tomcat that hosts Toolkit).
Open the Simulators tool and edit the configuration (select simulator and click on the pencil icon below).
Fill in the Register Metadata Validator Class Name parameter with the class name of your validator. For the above example the name is FooFoo.
Save the configuration.
It will run when the next Register transaction is received.
If a validator fails because of invalid code (bad variable name for example) here are some possible messages that will be returned and what they mean. These messages will appear in the RegistryResponse message.
Validation Fails - message did not meet the criteria
Error Code: message
Validator does not extend AbstractServerValidater
SOAP Fault: startup failed: /Users/bill/tmp/toolkit2a/environment/default/testkits/default/plugins/RegistryValidator/ConfCode.groovy: 18: Method 'run' from class 'ConfCode' does not override method from its superclass or interfaces but is annotated with @Override. @ line 18, column 5.
In this message the validator in question is ConfCode.groovy.
Code does not compile
SOAP Fault: startup failed: /Users/bill/tmp/toolkit2a/environment/default/testkits/default/plugins/RegistryValidator/ConfCode.groovy: 21: unexpected token: Iterator @ line 21, column 9. Iterator it = docEntry.getChildrenWithLocalName('Classification')
Unknown validator
SOAP Fault: Unknown validater ConfCode1 in default/default [/Users/bill/tmp/toolkit2a/environment/default/testkits/default/plugins/RegistryValidator, /Users/bill/Library/Caches/IntelliJIdea2018.1/gwt/develop.47685b4e/xdstools2.cf8becc6/run/www/toolkitx/testkit/plugins/RegistryValidator]
default/default shows the Environment/TestSession
The list is the search path through the available TestKits.
Toolkit
Downloads
Installing Toolkit
Configuring Toolkit for Imaging Tests
Reporting Toolkit Installation Problems
Environment
Test Session
Conformance Test Tool
Writing Conformance Tests
Overview of Imaging Tests
Test Context Definition
Launching Conformance Tool from Gazelle
Inspector
External Cache
Support Tools
Test Organization
Configuring Test Kits
Managing Multiple Test Kits
SAML Validation against Gazelle
Renaming Toolkit
Toolkit API
Managing system configurations
Configuring Toolkit for Connectathon
Developer's blog