
The topics below will give you an introduction to MOTECH, an open source mHealth platform developed by the Grameen Foundation. Some of these topics are quite technical in nature (i.e. aimed at software developers), while others are more accessible to people who aren’t familiar with software code.
Contents¶
About MOTECH¶
Mobile Technology for Community Health (MOTECH) is a modular, extensible open source software project originally designed for mobile health (mHealth), which can also be used outside of the health domain. It allows organizations to use mobile technology to communicate information to patients, collect data about patients, alert caregivers to patients’ status, and schedule caregivers’ work. The modular system allows organizations to choose among multiple mHealth technologies and to enable data sharing for users of the system.
MOTECH Architecture Overview¶
MOTECH consists of the core platform and several modules, each providing use of a technology such as SMS or email, or access to an external system such as CommCare. Organizations can choose to install one or more modules, and developers can extend MOTECH by writing new modules. MOTECH is written in Java. It depends on open source systems including Apache Tomcat, Apache ActiveMQ, and Quartz. For more information about MOTECH architecture, see Core Architecture and Modules Architecture.
What can MOTECH do?¶
The MOTECH Platform can be used for setting appointments, tracking any scheduled activity, and managing workers deployed in the field. Its initial implementations have been for mHealth projects that improve health by sending messages to patients and caregivers based on an evaluation of the recommended schedule of care compared to the patient’s health-related actions. Some features of typical MOTECH-based applications are:
Communicate information to patients via voice or SMS according to a schedule of care defined for the patient’s condition, e.g.:
- Reminders for ANC appointments, lab visits, etc.
- Reminders to take medication on schedule, e.g., DOTS, ART, etc.
- Reminder notices to take children for scheduled immunization services
Collect data from patients or caregivers, e.g.:
- Patients report their symptoms prior to treatment or during treatment (adverse events)
- Patients give feedback on service delivery
- Caregivers report what service was delivered to a patient and on what date
Alert caregivers of the status of their patients, e.g.:
- Notify Community Health Worker when patient has not taken ART, DOTS or other drugs
- Notify nurse when patient has not kept a scheduled appointment (e.g., ANC visit)
Facilitate communication between patients, caregivers, and/or health administrators, e.g.:
- Establish secure peer networks for patients who share similar health concerns
- Initiate conversations between patients and caregivers in a way that allows the caregiver to manage the workload effectively
MOTECH’s Current Capabilities¶
The latest version of MOTECH is 0.27.x. We recognize that open source projects rapidly develop with many contributors adding a piece at a time. This document focuses on the capabilities of MOTECH right now and will remain updated regardless of the current release. We’re keeping a list of future features on our roadmap with a focus on MOTECH 1.0.
Below is a list of features currently available in MOTECH:
- Administration
- Manage modules through the user interface. MOTECH is a modular system that allows you to add specific features and connections through modules. Administrators are able to install, configure and manage modules through the user interface.
- Role based access controls, audit logs, password requirements and many other security and auditing capabilities
- Create user defined entities (MySQL database tables, lookups and relationships) through the user interface
- Tasks
- Wire up events in MOTECH through the UI with the tasks module
- The tasks module is the primary method to act on events in MOTECH. Each interaction raises an event in MOTECH which can trigger a task and perform a corresponding action.
- Interfaces
- Web Browser
- End users can directly interact with the MOTECH interface through a web browser
- Commcare two-way integration
- Configure multiple connections to Commcare projects
- Receive and act on forwarded forms and cases from CommCare
- Import historical forms
- Connect to Commcare’s data, fixture and location APIs to supplement tasks
- IVR Integration
- Initiate outgoing calls from MOTECH by integrating with a mobile network operator
- Modules
- Perform Message Campaigns
- MOTECH is able to perform SMS, voice and email message campaigns directly to communities and front line workers
- Pill Reminder System
- Enroll users in a custom pill regimen and send per-user reminders for their specific medication
- Consume Facility, Provider and Organization information based on the IHE Care Services Discovery profile
- Connect to a CSD provider such as OpenInfoMan via REST or SOAP and store the data in the MOTECH Data Services system.
- Reporting
- DHIS2 one-way push integration
- Configure a single connection to a DHIS2 server
- Create tracked entity instances
- Enroll tracked entities in DHIS2 programs
- Push program stage events
- Send aggregate data values and value sets
- ETL Connections to Pentaho and Jasper Reports
- MOTECH can connect to popular third party reporting systems through an Extraction, Transformation and Loading (ETL) system such as Pentaho’s Data Integration - Kettle and Jaspersoft-ETL
Getting Started Implementers¶
We recognize that the MOTECH Platform Server requires deep programmatic understanding to implement. The MOTECH Platform Server was built to be generic, allowing for complex customization through the user interface. This section is intended for you, as an implementer of MOTECH, to help get started with installation and begin creating custom solutions to meet your needs. After the installation, you will have to configure the implementation and begin building applications within the platform. The topics below cover some of the common features that need to be configured for a MOTECH app.
As the platform matures, most of the features below will be usable by implementers without developing any software code. As of now, a number of these features do require some coding in order to use (the topics below provide sample code where appropriate). Feel free to reach out to our MOTECH-dev group if you get stuck or can’t decide the best path forward.
Installing MOTECH¶
This installation guide is used for demo systems based on 64-bit Ubuntu 14.04 LTS. It assumes you are running on the same and is not suitable for a full production install which requires additional steps to ensure security of the system. For example, it’s not advisable to use the root username in MySQL to setup the databases. MOTECH will run on other operating systems but the commands required and external packages will change. The changes shouldn’t be drastic but they aren’t documented here.
Install and Configure Dependencies¶
MOTECH version 0.27 and prior depends on the following software:
Tomcat7Java7 (OpenJDK or OracleJDK) OpenJDK installs as a dependency of Tomcat7ActiveMQMySQLMOTECH version 0.28 has upgraded to Java 8:
Tomcat7Java8 (OpenJDK or Oracle JDK) Installed through a PPA because these versions were not supported in Ubuntu 14.04ActiveMQMySQL
Install Java, Tomcat7, ActiveMQ and MySQL
Skip this next code-block (java installation) if installing MOTECH v.0.27 and prior
sudo add-apt-repository ppa:openjdk-r/ppa sudo apt-get update sudo apt-get install -y openjdk-8-jdksudo apt-get install -y tomcat7 sudo apt-get install -y activemq mysql-serverNote
MySQL is going to ask you for a root password. You have to input it twice. Remember it because we’ll use this later.
Change memory allocation for catalina when it starts and the ownership of the tomcat7 directories
#Note, you can change the memory allocation to anything, but we recommend at least 512m.
sudo service tomcat7 stop echo 'CATALINA_OPTS="-Xms512m -Xmx512m"' | sudo tee --append /usr/share/tomcat7/bin/setenv.sh sudo chown -R tomcat7:tomcat7 /var/lib/tomcat7/ /usr/share/tomcat7/ /var/log/tomcat7/Set JAVA_HOME in the default tomcat startup
Skip this step if installing MOTECH v.0.27 and prior
echo 'JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64"' | sudo tee --append /etc/default/tomcat7Configure ActiveMQ
ActiveMQ needs an enabled instance to run. Use the following command to create a symbolic link from instances-available to instances-enabled.
sudo ln -s /etc/activemq/instances-available/main /etc/activemq/instances-enabled/main sudo sed -e 's/<broker /<broker schedulerSupport="true" /' -i /etc/activemq/instances-enabled/main/activemq.xml #Then start ActiveMQ sudo service activemq restart
Deploy MOTECH .war file¶
We have to deploy the MOTECH .war file from our Nexus repository. The following code uses curl to download the latest released version of the motech-platform-server to your home directory. If you would like to choose another version, please visit our release notes page, which has all of the artefacts for download.
After downloading the appropriate .war file, you must then copy the file to the tomcat webapps folder so it will automatically deploy. Once downloaded, we start tomcat7.
sudo curl -L "http://nexus.motechproject.org/service/local/artifact/maven/redirect?r=releases&g=org.motechproject&a=motech-platform-server&v=RELEASE&e=war" -o ~/motech-platform-server.war
sudo cp ~/motech-platform-server.war /var/lib/tomcat7/webapps/motech-platform-server.war
sudo chown -R tomcat7:tomcat7 /var/lib/tomcat7/webapps/motech-platform-server.war
sudo service tomcat7 start
Navigate to http://localhost:8080/motech-platform-server
Complete the Bootstrap Form¶
You will be redirected to the bootstrap form the first time. Complete the form by clicking the ‘use’ button under each field. The MySQL username is ‘root’ and password is what you entered during the MySQL installation.

Once complete, test the MySQL connection by clicking the ‘Verify SQL Connection’ button. Then, click ‘Continue’
Complete Startup Settings¶
The MOTECH startup settings screen asks you to choose a language and select a login mode. Choose ‘Repository’ to create a new admin username and password.

You will be redirected to the MOTECH login screen where you enter the admin username and password you just created and your installation is complete.
MOTECH first-run experience¶
Table of Contents
Bootstrap screen¶
Once you’ve installed MOTECH and started it for the first time, you’ll be welcomed by the following bootstrap screen. Here you’ll have to provide some basic configuration information for the MOTECH to load properly.
- ActiveMQ Broker URL
- The URL pointing to the ActiveMQ server. If you’ve installed ActiveMQ using the default settings, or by using the provided
install.sh
script, you can simply clickUse
button next to the first suggestion right under the text box. Otherwise, you must provide the correct URL.- SQL URL
- The URL pointing to the SQL server. If you’ve installed MySQL, or by using the provided
install.sh
script, you can simply clickUse
button next to the first suggestion. If you’ve installed Postgres using the default settings, you can simply clickUse
button next to the second suggestion. Otherwise, you must provide the correct URL.- SQL Database Driver
- JDBC driver for the chosen database.
com.mysql.jdbc.Driver
for MySQL database.org.postgresql.Driver
for Postgresql.- SQL Username
- The username that MOTECH will be using for managing the database.
- SQL Password
- The password for the account with the username provided in the SQL Username.
- Felix path
- The location where OSGi cache should be stored.
- Configuration Mode
- The mode that will be used for further MOTECH configuration. Both modes will be explained in the following sections. Keep in mind that if you select the
FILE
mode, you must provide a configuration file BEFORE progressing further. See Configuring MOTECH through FILE section for more information about how to prepare the configuration file.
After you’ve filled up the bootstrap form and clicked Continue
button, you will have to wait for the MOTECH to
start. The following screen will inform you about to the progress during MOTECH startup process.
MOTECH configuration¶
Once the MOTECH have started, it might require some more configuration depending on the selected configuration mode. If
you’ve selected UI
as configuration mode jump to the `Configuring MOTECH through UI`_ section or to the
Configuring MOTECH through FILE section if you’ve selected FILE
.
Configuring MOTECH through the UI¶
If you’ve selected the UI as the configuration mode, the following screen will be displayed.
Here you are able to select the language MOTECH will be using, as well as one of the following login mode:
- Repository Using this mode will result in creating accounts locally.
- OpenID Using this mode will result in using the OpenID standard. For more information about the OpenID, please visit the www.openid.net website.
Repository login mode¶
If you’ve selected Repository
as the login mode, the following screen will be displayed. Here you have to
provide the credentials for the administrator account.
Once you’re done just hit Submit
button and then continue to the First login through repository section.
OpenID login mode¶
If you’ve selected OpenID as the login mode, the following screen will be displayed. Here you have to provide the information about OpenID provider. For more information about the OpenID please visit www.openid.net website.
Once you’re done just hit Submit
button and then continue to the First login through OpenID section.
Configuring MOTECH through FILE¶
If you’ve selected this method of configuring MOTECH you’ll have to provide the configuration file. The file must have
the .properties
extension and must be placed in the config
subfolder of the MOTECH folder(most likely
/home/{username}/.motech/config
) and must store the following properties.
- system.language
- The language the MOTECH will be using. The accepted values are
en
,pl
etc.- login.mode
- The login mode that will be used. The accepted values are
repository
andopenid
.
Repository login mode¶
If you’ve selected repository as the login mode, the following screen will pop up. Here you’ll be able to create admin account by providing the credentials. Keep in mind that this is admin account and those credentials should be strong.
Once you’re done just hit Submit
button and then continue to the First login through repository section.
OpenID login mode¶
If you’ve selected OpenID login mode, you’ll have to include two more properties into the file.
- provider.name
- The name of the OpenID provider.
- provider.url
- The URL that the OpenID provider uses for authentication.
Here’s an example file that uses OpenID mode.
system.language=en
login.mode=openid
provider.name=UbuntuOne
provider.url=https://login.launchpad.net/
Once you’re done just hit Submit
button and then continue to the First login through OpenID section.
First login¶
Once you’re done with installing and configuring MOTECH, the first login screen(depending on the selected login mode) will pop up.
First login through repository¶
If you’ve chosen repository as the login mode, the following window will be displayed. Here you’ll have to enter the credentials you provided in the MOTECH configuration step.
First login through OpenID¶
If you’ve chosen OpenID as the login mode, the following window will be displayed. Here, you’ll have to click on the
Sign in with Provide name
button, which will result in redirecting you to the OpenID provider login page, where
you’ll have to enter valid credentials for that provider.
Configuration System¶
This document describes the MOTECH configuration system.
Step 1: Specify Config Locations¶
Default Behavior¶
By default, all configuration files are loaded from one of the following locations:
....${user.home}/.motech/config/
For example, if Motech runs under the user motech in Linux, configuration files will be searched in “/home/motech/.motech/config” folder.
Or:
..../etc/motech/
If the configuration files are not found in the above mentioned location, files will be searched in “/etc/motech” folder.
Overriding Default Behavior¶
If you want to override the location where configuration files are loaded from, you have to add config-locations.properties to ${user.home}/.motech or to ${user.home}/ directory. Otherwise the property file in classpath will be picked up. Default config-locations.properties file:
....config.location= ${sys:user.home}/.motech/config/,/etc/motech/.
where “${sys:user.home}” is used to specify the home directory.
Note that, multiple locations can be specified for config.location property, and motech-settings.properties (which contains platform core config) config file will be searched starting from the first location and then falling back to next specified location, if it is not found. The directory in which it is found, is considered as the current config location and all other config files will be looked only in that particular location. For e.g., in the above sample config, if you have motech-settings.properties in /etc/motech/, then all config files will be searched in /etc/motech/ location only. You cannot have files in different locations.
Step 2: Bootstrap Configuration¶
There are certain properties which are essential for the system to start up. These properties can be defined either in bootstrap.properties file or by environment variables. The properties are:
- db.url – The database connection url, e.g.: localhost:5984
- db.username – The user who has access to the database.
- db.password – Password to connect to the database.
- tenant.id – Optional. Default value is default.
- config.source – Optional. The source from which MOTECH core configuration and all module configurations should be read. Valid config values can be either one of FILE or UI. Default value is UI.
During startup, the system will look for these configurations in the following locations, falling back in order (that is when the properties are found in any of the following locations, search look up will stop):
Config Directory Environment Variable: If MOTECH_CONFIG_DIR environment variable is defined, then the system will load properties from ${MOTECH_CONFIG_DIR}/bootstrap.properties.
- Config Environment Variables: Config is loaded from one or more environment variables:
- MOTECH_DB_URL – specifies value for db.url
- MOTECH_DB_USERNAME - specifies value for db.username
- MOTECH_DB_PASSWORD – specifies value for db.password
- MOTECH_TENANT_ID – specifies value for tenant.id
- MOTECH_CONFIG_SOURCE – specifies value for config.source
Location from Property file: bootstrap.properties file is loaded from any one of the locations specified in config-locations.properties file described above.
We are working on a feature in which, if bootstrap.properties is not found in any of the above mentioned locations, a UI will be presented to user after startup, prompting for bootstrap properties.
Step 3: MOTECH Core Config¶
There are some system configurations and activemq configurations which are needed to get MOTECH up and running.
- System configurations:
- system.language - Can take en(English), pl(Polski), es(Spanish), fr(French), it(Italian), sw(Swahili) as values(although only English and Polski are implemented as of now). Optional, default value is en.
- statusmsg.timeout - Represents the expiration time(in seconds) of messages and notifications in admin UI. Optional, default value is 60.
- login.mode - Can be repository or openId (case insensitive).
- provider.name - OpenId? provider name, mandatory in case login mode is openId.
- provider.url - OpenId? provider url, mandatory in case login mode is openId.
- Security configurations(For more details you should read the security configuration section):
- security.required.email - Indicates whether you must provide an email address when creating the user.
- security.failure.login.limit - The permissible number of incorrect login attempts, default value is 0. After this limit is reached the user is blocked. After a successful login counter is reset. If the value is 0 then blocking is inactive.
- security.session.timeout - The session timeout in seconds, default 30 minutes. After this time session will be closed.
- security.password.minlength - The minimum length of the password, default 0. if the value is 0 then length checking is disabled.
- security.password.validator - The password validator, it specify password rules e.g. 1 number, 1 special character. Can take none, lower_upper(at least 1 uppercase and lowercase), lower_upper_digit(at least 1 uppercase, lowercase and digit), lower_upper_digit_special(at least 1 uppercase, lowercase, digit and special character) as values, default none validator is used.
- Activemq configurations:
- jms.queue.for.events - Queue name to hold motech event messages. Optional, default value is QueueForEvents.
- jms.topic.for.events - Topic name to hold motech event messages. Optional, default value is TopicForEvents.
- jms.broker.url - JMS broker URL. Can take failover URLs also. Sample values: tcp://localhost:61616, failover:(tcp://192.168.32.1:61616,tcp://192.168.32.2:61616)?randomize=false
- jms.maximumRedeliveries - Maximum number of redeliveries in case of any exceptions and a message consumption fails. Optional, default value is 0.
- jms.redeliveryDelayInMillis - Delay(in seconds) between successive re-deliveries of messages. If delay=d and first exception was raised at time=t, then successive redelivery times are calculated using exponential backoff . i.e. t+d, t+(d*2), t+(d*4), t+(d*8), t+(d*16) and so on, till maximum redelivery count is reached. Optional, default value is 2000.
- jms.concurrentConsumers - Optional, default value is 1.
- jms.maxConcurrentConsumers - Optional, default value is 10.
- jms.session.cache.size - Optional, default value is 10.
- jms.cache.producers - Optional, default value is false.
Case 1: When ConfigSource is FILE¶
Define motech-settings.properties file in any one of the locations defined in config-locations.properties with the above mentioned properties.
Case 2: When ConfigSource is UI¶
After server startup, if core settings are not configured already, you will be presented with a startup page which asks for System Language, Queue URL for events, Login Mode and user setup based on login mode. Other activemq settings can be changed in Settings tab after logging in.
Step 4: Module Configurations¶
Case 1: When ConfigSource is FILE¶
Module specific property files can be added to:
....<config-location-dir>/<module-symbolic-name>/ directory
and any JSON templates/configurations to:
....<config-location-dir>/<module-symbolic-name>/raw/ directory.
A typical example of a motech’s module symbolic name:
....<module-name>
prefixed with “org.motechproject.motech-”.
All these files are monitored for changes. So, any change to these config files at runtime would be detected and saved in DB. Restart the module if required using Manage Modules tab in UI. We are enhancing the config monitor to raise an event in case of config change. This event can be listened by interested modules and take appropriate actions.
Case 2: When ConfigSource is UI¶
After server startup, you can find each module having settings UI associated with it in the Manage Modules tab, where you can edit the properties for the module. Also, restart the module if required. We are enhancing the config monitor to raise an event in case of config change.
Modeling Data with MOTECH Data Services¶
Table of Contents
- Modeling Data with MOTECH Data Services
- Introduction
- MDS Entities
- MDS Lookups
- Data Services
- EUDE - End User Defined Entities
- DDE - Developer Defined Entities
- Defining entities - the @Entity annotation
- DDE entity fields - @Field and @Ignore annotations
- DDE relationships
- Common problems with relationships and their solutions
- Using DataNucleus annotations
- DDE service interfaces
- Defining editable lookups for DDE entities
- Programmatic usage of DDE entities
- Record versioning and optimistic locking
- MEDE - MDS Enhanced Developer Defined Entities
- Supported field types
- History tracking for entities
- MDS Trash Bin
- The MDS Data Browser
- Data browsing settings
- The REST API
- Entity validations
- MDS Lookup Service
- Executing custom queries
- Using Spring Transactions with MDS
- Security
- CRUD Events
- Instance Lifecycle Listeners
- Entities Migrations
- Schema Import/Export
- Javadoc
Introduction¶
MOTECH Data Services (MDS) is the data layer for the MOTECH Platform. MDS allows defining the data model both through code (using annotations or the exposed API) and the Schema Editor UI. It is capable of exposing generic services which allow executing CRUD operations on the defined model. It also is capable of exposing a fully functional REST API for the defined entities on the fly. Entities defined through means of code can always be extended or get their settings modified through the MDS Schema Editor or its underlying API.
- The benefits of MDS include:
- Generated user interface for data entry
- UI-based schema editor, and the ability to enhance developer-defined entities
- Generated OSGi services and Java APIs for accessing data objects
- Generated REST APIs for external data access
- Generated CRUD events for MDS entities (and exposure of these events via the Tasks module)
- Ability to register actions that execute on instances based on CRUD triggers
- Bulk import/export of data
- Change tracking (auditing) of data
- Object-level security
MDS uses DataNucleus underneath for persistence in a relational data store. Currently MDS officially supports two RDBMS engines MySQL and PostgreSQL. Javassist is used for code generation and OSGi mechanics such as bytecode weaving are used for replacing the code at runtime.
MDS generated entities bundle¶
All classes generated by MDS live in the mds-entities OSGi bundle, which gets generated at runtime and installed in the directory ~/.motech/bundles. The bundle is always regenerated when changes are made to the MDS schema. This generated bundle can also be downloaded using the following url: http://<motech_url>/modulemds/jar.
MDS Entities¶
MDS defines an Entity concept. An MDS entity maps directly to a POJO class and a table in the relational database. Entities consist of fields which are directly mapped to the object fields and columns in the database table. MDS supports multiple field types.
MDS integrates itself with the Tasks module, so a user can create a working application with a minimal amount of code. Entities generate task data providers which allow access to the data within MDS. Entities can also be configured to publish MOTECH events which are fired after CRUD operations are completed in MDS. These CRUD events, are exposed as task triggers in a dynamically generated task channel. CRUD actions are also exposed as actions within the task module, allowing users to create database manipulating logic through the tasks module.
We can group entities into three categories:
EUDE - End User Defined Entities. The entities created using the UI by the end user. These classes do not exist at compile time, but only after they are generated by MDS. Adding the bundle generated by MDS to the classpath will allow compile time access however. EUDE entities can also be defined using the MDS API through the EntityService. Users can view and create instances of the entities through the MDS Data Browser.
DDE - Developer Defined Entities. Developers can use annotations to mark their POJO classes as MDS Entities. These will be treated in the same way as EUDE entities, instances of the DDEs will also be accessible through the data browser. Users can still view the schema for these entities through the Schema Editor, add fields and modify settings(although they can’t remove fields declared by the developer in the java class).
MEDE - MDS Enhanced Developer Defined Entity. These are DDEs that were enhanced with additional fields added either through the UI or the Entity API. This are the same as DDE, but with additional fields added at runtime. Those fields can be accessed at compile time using Java Reflection API.
Automatically added fields¶
All entities in MDS will be enhanced with the following fields automatically:
Name | Type | Description |
---|---|---|
id | Long | The id field of the entity, used to uniquely identify the instance. |
owner | String | The username of the owner of the instance. This field can be used with security settings for the entity in order to filter access to only instance owners. |
creator | String | The username of the creator of the instance. Automatically set to username of the MOTECH user that created the instance. Note that security can be set up to limit instance access to only creators of those instances. |
modifiedBy | String | The username of the user that last modifier of the instance. Automatically set to the username of the user that last edited the entity. |
creationDate | DateTime | The datetime on which this entity was created. Filled automatically. |
modificationDate | DateTime | The datetime on which this entity was last modified. Updated automatically. |
Access to these fields can be done through reflections, through re-declaring them in the DDE class or by inheriting the MDSEntity class.
MDS Lookups¶
Lookups allow easily defining and executing queries on MDS entities. A lookup allows querying for a single or multiple fields. A lookup field is always corresponding to a single field in the entity. It can be also configured to either return a single or multiple results.
Note
If more then one instance matches the criteria of a single return lookup, the lookup will fail.
Lookups at this moment can only use AND logic for doing a query for multiple fields. For OR(or move complex) logic JDO queries have to be used. Lookups also allow comparing fields against provided parameters using a custom operator or using a range or set of values, defining such lookups is not supported through the UI at the moment though.
For each lookup two additional versions of the method will be generated. The first one is the same as the lookup, but with an additional parameter at the end - org.motechproject.mds.query.QueryParams. This class contains pagination directives - page number and page size, it also contains information about ordering the results - an org.motechproject.mds.util.Order object containing the sort direction and sort column. This version of the lookup is useful for operating on large data sets and providing ordered views to the user. The third version is the same as the basic lookup, but it returns a number (long) - the total count of the entity in the database. The name of the count method consists of count and the capitalized original lookup method name. For example for a lookup with a method name byName the count method will be called countByName.
Note
When defining a DDE, it doesn’t matter which version of the lookup you define, all three methods will be generated. For compile access to them however, they have to be explicitly defined in your service. More info on defining lookups in DDEs can be found in the section about defining DDE Data Services
Data Services¶
All access to entities in MDS is done through Data Services. These are services implementing the org.motechproject.mds.service.MotechDataService interface. They are exposed as OSGi service that can be retrieved from the OSGi BundleContext. All data access exposed by MDS, either the REST API, the UI data browser, Csv Import/Export etc. is done through these services. The class of the service is generated at runtime and it extends the base DefaultMotechDataService class. Developers can extend the **MotechDataService** interface in order to add their own lookups to the interface simply by declaring the method signatures and annotating them properly.
EUDE - End User Defined Entities¶
These entities are created by end users, either through the UI or using the exposed API. No programming knowledge is required in order to define an EUDE using the first method. Although these entities are not known at compile time(unless the jar generated by MDS is added to the classpath) programmatic access to these entities is still possible using Java Reflection API and some handy helper classes exposed by MDS - mainly the MdsLookupService.
Note
All EUDE classes share the same java package: org.motechproject.mds.entity
Creating EUDE through UI¶
The easiest way to create EUDE entities is to use the MOTECH UI. First select Data Services from the left navigation menu(Modules menu), then navigate to the Schema Editor tab. You will see a dropdown allowing to select an existing entity for modification or deletion. Next to the dropdown menu you will see a New Entity button.
After that the user is asked for the name of the entity. This can be anything that is a legal name of a class in Java.
The view for managing entity fields is then displayed to the user. Users can add a field by selecting its type, choosing a name and a display name. ‘display name’ represents what will be visualised to the users in the MDS Data Browser, task editor etc. ‘name’ represents the actual name of the field that will be used for class and table creation. After this data is entered, hitting the green plus sign will add the field.
The field is then expanded and the user is presented with options to modify the field settings:
The Basic sections allows to change the previously entered name and display name, it also allows marking the field as required, meaning that users will be prevented from creating an instance without any value in this field. A default value for the field can also be entered, as well as a tooltip that will be shown to users creating instances of the entity.
The Metadata section allows adding metadata to the field. This used internally by MDS for features such as relationships. End users should not worry about this section, but advanced users can add any values they wish for their own processing needs. Metadata is retrieved with the field schema using the Entity API. An example of using metadata could be a scenario when we are writing a third party export tool, that takes the MDS Schema and imports it into a 3rd party system. The field metadata can be used by that tool in order to recognize some fields as requiring special processing logic.
The Validation section allows setting specific validation rules for the field. Users will then be constrained by these validations when creating instances of the entity. Validations are type specific.
The Settings tab allows users to set type specific settings of the field. An example setting is the ‘Max text length’ of a String field, which indicates the maximum length of the string at the database level.
Existing fields can be deleted using the trash bin icon next to their type.
When the user is done modifying the entity, clicking Save changes will save the changes to schema and regenerate MDS entities. Clicking Abandon Changes will abandon all changes made by the user since the last save.
Defining a Lookup through the UI¶
Users can use the UI for adding lookups to an entity. These lookups can then be executed either directly through the data services or using the Data Browser UI. In order to add a new lookup, first open the advanced settings of an entity by clicking the ‘Advanced Settings’ button.
After that users can create lookups by clicking on the ‘New Lookup’ button.
The name fo the lookup can then be modified as well as whether it returns a single or multiple objects. In order to make a lookup useful, it has be executed on a given set of fields, which can be added on the right side of the window by clicking the ‘New Lookup Field’ button and selecting the right field from the dropdown. They can be deleted using the trash bin button.
In order to remove a lookup, the delete button in the lower right of dialog can be used.
When the user is done adding lookups to an entity, clicking Save changes will save the changes and trigger regeneration. Clicking Abandon Changes will abandon all changes made by the user since the last save.
Creating EUDE through the Entity API¶
Creation of entities can be also done using the org.motechproject.mds.service.EntityService. This an OSGi service exposed by MDS which allows creation and modification of MDS entities, exposing everything that the UI does. In order to use the service it has to be retrieved from the OSGi context, either directly using the OSGi API or a Blueprint reference can be used to inject a proxy for that service directly as a Spring bean.
Example of retrieving the service manually:
import org.motechproject.mds.service.EntityService;
import org.osgi.framework.*;
...
public EntityService getEntityService() {
// note that if using Spring, the BundleContext can be injected as any other bean
// which allows skipping this step
BundleContext bundleContext = FrameworkUtil.getBundle(EntityService.class).getBundleContext();
// get the service reference from the bundle context
ServiceReference<EntityService> ref = bundleContext.getServiceReference(EntityService.class);
// return the service for the reference, or null if there are no references
// the service should always be available, so a null reference definitely indicates some sort error
return ref == null ? null : bundleContext.getService(ref);
}
and the preferred way using blueprint. Note that thanks to this declaration an EntityService bean becomes available in your Spring context.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.eclipse.org/gemini/blueprint/schema/blueprint"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.eclipse.org/gemini/blueprint/schema/blueprint
http://www.eclipse.org/gemini/blueprint/schema/blueprint/gemini-blueprint.xsd">
<osgi:reference id="entityService" interface="org.motechproject.mds.service.EntityService"/>
</beans>
After getting hold of the service the entity can be created using the createEntity method:
EntityService entityService = getEntityService();
EntityDto entity = new EntityDto("Patient");
// the EntityDto instance returned will have the id value set
entity = entityService.createEntity(entity);
If we want to edit an existing entity, we can retrieve it using the EntityService:
// We can use the org.motechproject.mds.util.ClassName utility in order
// to get the EUDE class name given just the name
String className = ClassName.getEntityName("Patient");
// className is org.motechproject.mds.entity.Patient
EntityDto entity = entityService.getEntityByClassName(className);
When we have the EntityDto instance, fields can get added to the entity using the service and EntityDto returned:
// a simple integer field
FieldDto simpleField = new FieldDto("simpleInt", "Simple integer", TypeDto.INTEGER);
// a required name field
FieldDto nameField = new FieldDto("name", "Patient Name", TypeDto.STRING, true);
// an optional date of birth field, with a tooltip
FieldDto dobField = new FieldDto("dob", "Date of Birth", TypeDto.DATETIME, false, null,
"Patients date of birth, leave blank if unknown");
// a required Social ID field, defaulting to 0
FieldDto socialIdField = new FieldDto("socialId", "Social ID", TypeDto.LONG, true, 0L);
// add the fields to the entity created earlier
entityService.addFields(entity, simpleField, nameField, dobField, socialIdField);
In order to make these changes take effect, data bundle regeneration must be triggered.
Creating Lookups through the API¶
Just as any other edits on the entity schema, lookups can also be created using the EntityService. In a similar fashion to fields, the addLookups method can be used for adding lookups to an entity. Given that we have the EntityDto object and the EntityService(), we can create lookups in the following manner:
// this lookup will check the name field, during an exact comparison
LookupDto lookupByName = new LookupDto("By name",
true, // single object return
true, // expose this lookup through REST
Arrays.asList(new LookupFieldDto("name", LookupFieldDto.Type.VALUE)
));
// this a complex lookup using multiple fields
LookupDto complexLookup = new LookupDto("Complex lookup",
false, // return multiple objects
false, // do not expose by REST
Arrays.asList(
// the custom operator matches() will be used for querying on the name field
new LookupFieldDto("name", LookupFieldDto.Type.VALUE, Constants.Operators.MATCHES),
// the dob parameter will take a range, with a min and max value
new LookupFieldDto("dob", LookupFieldDto.Type.RANGE),
// for the state field, a set of possible values can be supplied
new LookupFieldDto("state", LookupFieldDto.Type.SET),
// the search through relationship fields is possible using the dot operator
new LookupFieldDto("relationshipField.number", LookupFieldDto.Type.VALUE))
);
// add the lookup
entityService.addLookups(entity, lookupByName, complexLookup);
In order to make these changes take effect, data bundle regeneration must be triggered.
Regenerating the entities bundle¶
After we are done with modifications to the entity schema, we must trigger regeneration in order for the classes to get updated and made available in OSGi. For this we need to use org.motechproject.mds.service.JarGeneratorService, which we can retrieve the same way that we can retrieve the EntityService. Once we have an instance of the service, all we need to do is call the regenerateMdsDataBundle method:
JarGeneratorService jarGeneratorService = getJarGeneratorService();
jarGeneratorService.regenerateMdsDataBundle();
After the schema gets regenerated and all bundles using MDS get refreshed, the EUDE class should be available for use.
Programmatic access to EUDE entities¶
EUDE classes can be accessed using java reflections. This is an example of creating an instance using reflections:
// first get the interface class name of the name entity
// this helper method will always return org.motechproject.mds.entity.Patient
String interfaceName = ClassName.getInterfaceName("Patient")
// Retrieve the Data Service
MotechDataService service = ServiceUtil.getServiceForInterfaceName(bundleContext, interfaceName);
// Get the Class object for the entity
Class entityClass = service.getClassType();
// create a patient instance and set the name to "John"
Object instance = entityClass.newInstance();
PropertyUtil.setProperty(instance, "name", "John");
// save it using the service
service.create(instance);
As you can see the access is done through the Data Service. We can obtain the Class object for the generated class and use it for doing all required operations using reflections.
DDE - Developer Defined Entities¶
Developers can use annotated POJO classes in order to define the model for their application. Entities defined in this way will be treated in a similar fashion to EUDE entities, they can also be accessed using the MDS Data Browser. New fields can also be added to DDEs - so that they become MEDE.
DDEs are represented by actual Java classes used for defining them. OSGi bytecode weaving is used in order to enhance these classes at runtime and add additional fields for them. Because of this, these classes can be used with ease in code, since they are available during compile time to developers.
Defining entities - the @Entity annotation¶
In order to define a DDE by using the org.motechproject.mds.annotations.Entity annotation. This are the contents of Patient.java, an example fo a DDE entity:
package org.motechproject.example;
import org.motechproject.mds.annotations.*;
@Entity
public class Patient {
}
When the module containing this entity gets installed MDS will scan it for classes annotated with @Entity, and the class above would get picked up for processing. Schema for the entity is then generated and persisted in the database of MDS, the class is also enhanced by DataNucleus. The MDS weaving hook then replaces the bytecode for this class in module ClassLoaders with the DataNucleus/MDS enhanced version, making it available to the modules using it.
Note
The module must export the package of the entity in OSGi, using the Export-Package directive in its manifest.
The @Entity annotation has the following parameters:
name
- The name of the entity displayed to the user. Defaults to the simple name of the annotated class.module
- The name of the module for this entity. Defaults to the module name of the bundle from which this entity comes from.namespace
- The namespace in which the entity is defined. Optional, defaults to empty.tableName
- The actual name of the table in the database for this entity. Allows users to directly control the name in the data store. The default table name will take the form of:MDS_<MODULE>_<NAMESPACE>_<ENTITY_NAME>
. If an entity has no namespace or module, those parts will be omitted.recordHistory
- Set to true if MDS should record history for this entity.
DDE entity fields - @Field and @Ignore annotations¶
An entity does not have much use without any fields. MDS will treat any public field or field with public getter/setter in the class as an MDS field. In the class below, the field name will be picked up automatically as a field to be persisted in the database:
@Entity
public class Patient {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The @Field annotation can be used for more explicit marking and control over the fields basic properties. In the example below, the required parameter of the annotations is used to mark the name field as required, moreover the physical column name in the database is set to “P_NAME”:
@Entity
public class Patient {
@Field(name = "P_NAME", required = true)
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The @Field annotation could also be placed on the setter or getter methods for the same effect.
Not every public field, or not every field that has a public getter or setter has to be persisted in the database. The @Ignore annotation can be used for marking such field as not persistent:
@Entity
public class Patient {
@Ignore
public String name;
}
The name field in the example above will not become a database field and no MDS schema will be generated for it. This field will also not be accessible through the data browser.
DDE relationships¶
Creating relationships between entities is currently only possible for DDE. The definition of a relationship depends on the type of the relation. MDS supports one-to-one, one-to-many, many-to-many and master-detail relationships, both uni-directional and bi-directional. The way to define relationships for DDEs is presented in the examples below.
- One-to-one To create a one to one relationship, one of the related entities, should define a field of class, that represents the second entity. Both classes must of course be valid MDS Entities. The code below, provided that Book is an entity, will create a simple, uni-directional, one-to-one relationship between Author and Book.
@Entity
public class Author {
@Field
private String name;
@Field
private Book book;
...
}
- One-to-many To create a one to many relationship, one of the entities should define a collection of related entity. Just like in one-to-one relationships, both classes must be valid MDS entities to work. The code below shows an example of a simple, uni-directional, one-to-many relationship between Author and Book (one author is related with many books).
@Entity
public class Author {
@Field
private String name;
@Field
private Set<Book> book;
...
}
Bi-directional relationships The bi-directional relationship is a model, in which both sides of a relation are aware of the existence of a relationship and can both refer to the other side of a relation.
- To make the relationship bi-directional, two additional steps must be taken:
- The second entity must also define a relationship to the other entity
- Exactly one MDS field of a bi-directional relationship must be annotated with the @javax.jdo.annotations.Persistent(mappedBy = “fieldName”) annotation. The fieldName should correspond to the field name that is in a relationship, in the another entity.
Please see the code below, for an example of a one-to-many, bi-directional relationship.
@Entity
public class Author {
@Field
private String name;
@Field
@Persistent(mappedBy = "author")
private Set<Book> book;
...
}
@Entity
public class Book {
@Field
private String title;
@Field
private Author author;
...
}
- Many-to-many Mds supports two types of many to many relationship. First type is M-N Set relation which is bi-directional, if you need more information you should read datanucleus M-N Set relation documentation. The code below shows an example of a many-to-many set relationship.
@Entity
public class Author {
@Field
private String name;
@Field
@Persistent(mappedBy = "author")
private Set<Book> book;
...
}
@Entity
public class Book {
@Field
private String title;
@Field
private Set<Author> author;
...
}
Second type is M-N Indexed Lists relation which is modelled as 2 1-N unidirectional relations using join tables. Very important is to use the @IndexedManyToMany annotation at both ends of the relation instead of the @Persistent(mappedBy = “fieldName”). If you need more information you should read datanucleus M-N Indexed List relation documentation. The code below shows an example of a many-to-many indexed list relationship.
@Entity
public class Actor {
@Field
private String name;
@Field
@IndexedManyToMany(relatedField = "actors")
private List<Movie> movies;
...
}
@Entity
public class Movie {
@Field
private String name;
@Field
@IndexedManyToMany(relatedField = "movies")
private List<Actor> actors;
...
}
The code below shows an example how to properly use many-to-many indexed list relationship.
Actor actor1 = actorDataService.findByName("actor_1");
Actor actor2 = actorDataService.findByName("actor_2");
Movie movie = movieDataService.findByName("movie");
movie.getActors().add(actor1);
movie.getActors().add(actor2);
actor1.getMovies().add(movie);
actor2.getMovies().add(movie);
movieDataService.update(movie);
Note
To add an object to an M-N relationship you need to set it at both ends of the relation. You should also remember to define the methods equals and hashCode so that updates are detected correctly.
- Master-detail MDS also supports master-detail model, where entity can inherit some fields from another entity. This is achieved by simple class inheritance, using Java keyword extends. Naturally, both classes must be valid MDS entities for this to work. The code below shows an example of such master-detail model.
@Entity
public abstract class Config {
@Field
private String name;
@Field
private Map<String, String> properties;
...
}
@Entity
public class ModuleConfig extends Config {
@Field
private String moduleName;
@Field
private String moduleVersion;
...
}
Eager/lazy loading By default loading an entity with relationship will load its related entities, but that behaviour can be configured through @Persistent(defaultFetchGroup = “true/false”) annotation. Please see the code below for an example.
@Entity public class Author { @Field private String name; @Field @Persistent(defaultFetchGroup = "false") private Set<Book> books; ... }
By defining class this way the set of books won’t be fetched from the database unless it is explicitly said (e.g. by calling
getBooks()
method on object of theAuthor
class) to. This approach simplifies the queries sent to the database and lower its overall usage.Lets take a look at the following example using
Subscriber
andSubscription
classes.@Entity() public class Subscriber extends MdsEntity { @Field private Long callingNumber; @Field @Persistent(mappedBy = "subscriber") private Set<Subscription> subscriptions; ... }
@Entity public class Subscription extends MdsEntity { @Field private String subscriptionId; @Field private Subscriber subscriber; ... }
With the default approach query responsible for fetching subscriptions will look like this
SELECT 'entity.class.name.Subscription' AS NUCLEUS_TYPE, A0.creationDate, A0.creator, A0.id, A0.modificationDate, A0.modifiedBy, A0.owner, A0.subscriber_id_OID, A0.subscriptionId FROM MOTECH_PLATFORM_DATA_SERVICES_TEST_BUNDLE_SUBSCRIPTION A0 WHERE EXISTS ( SELECT 'entity.class.name.Subscriber' AS NUCLEUS_TYPE, A0_SUB.id AS DN_APPID FROM MOTECH_PLATFORM_DATA_SERVICES_TEST_BUNDLE_SUBSCRIBER A0_SUB WHERE A0.subscriber_id_OID = A0_SUB.id)
which gets simplified to
SELECT 'entity.class.name.Subscription' AS NUCLEUS_TYPE, A0.creationDate, A0.creator, A0.id, A0.modificationDate, A0.modifiedBy, A0.owner, A0.subscriber_id_OID, A0.subscriptionId FROM MOTECH_PLATFORM_DATA_SERVICES_TEST_BUNDLE_SUBSCRIPTION A0 WHERE A0.subscriber_id_OID = 1
if we remove
Subscriptions
field from the default fetch group (by adding@Persistent(defaultFetchGroup = "false") annotation to the :code:`Subscriptions
field. This query requires one table scan less and won’t be sent to the database unless explicitly ordered to.
Common problems with relationships and their solutions¶
Problem: Accessing related fields throws javax.jdo.JDODetachedFieldAccessException or returns null
Explanation: By default, the metadata generated for the entities by MDS specifies that all fields are loaded eagerly. This means that the object retrieved from MDS data service will have all its fields and relationship set. This behaviour can be adjusted, by switching the strategy to lazy loading for certain fields. This is commonly done to improve the performance, since the objects will not be fetched from the database until they are accessed. You can read more about the eager and lazy loading strategies in MDS. Datanucleus will only be able to fetch lazy loaded fields if they are accessed within the same transaction. Accessing fields marked as lazy loaded, outside of the transaction will result in either javax.jdo.JDODetachedFieldAccessException, if the instance is in detached state or will return null, if the instance is in transient state.
Another possible reason of getting the aforementioned exception is accessing objects deep in the relationship chain. Depending on the properties that have been set, Datanucleus will fetch the whole relationship tree together with an object, or only relationships up to some certain level. This can be controlled using the maxFetchDepth property of the @Entity annotation and datanucleus properties. A value of -1 means that the whole relationship tree should be fetched.
Problem: Many-to-many relationship with lists does not work properly
Explanation: Since many-to-many relationship with lists is treated differently - as two one-to-many relationships, and due to several internal MDS issues, many-to-many relationship with lists must be modeled using our own @IndexedManyToMany. Please see usage instructions in the M:N relationships documentation.
Problem: While starting the server or module an InvalidRelationshipException is thrown
Explanation: The Motech Data Services module takes care, that all relationships are defined properly. In case it finds any problems with the relationship definitions, it will throw this exception, with an instruction on how to model the relationship properly. A general rule for bi-directional relationships is to place the @javax.jdo.annotations.Persistent annotation at exactly one side of a relationship. In case of many-to-many relationships, use our own @IndexedManyToMany annotation.
Problem: Creating/updating instance throws StackOverflowError
Explanation: A common mistake while modeling bi-directional relationships is including the relationship field in the hashCode and equals methods. Assume a bi-directional relationship between entities A and B and instances of those entities that point to each other. When Datanucleus attempts to calculate the hashCode or invoke equals method to compare the objects, it will fall into infinite loop, reading instance of entity A and B consecutively, until it runs out of space and throws StackOverflowError. Therefore, it is highly recommended that relationship fields are not used in the hashCode and equals methods. It is recommended that the hashCode and equals methods respect the Java guidelines for overriding these methods. Required and unique fields are the best candidates to use in these methods. Moreover, Datanucleus recommends that the ID field is not used in the hashCode method, as it may cause issue while detaching/attaching persistable object.
In rare conditions the StackOverflowError may originate from the Datanucleus L2 Cache and it is most likely a bug in Datanucleus. If such problem arises, please first make sure that all of the above conditions have been resolved. If it doesn’t help, the Motech Data Service exposes the evictAll method, that clears the entire Datanucleus cache. Moreover, it is possible to adjust the Datanucleus L2 cache settings or even turn it off completely. Please keep in mind that these steps may affect MDS performance.
Problem: CRUD operations on instances throw javax.jdo.JDOUserException: Cannot read fields from a deleted object
Explanation: The exception with the above message is thrown when Datanucleus attempts to perform operations on objects, that have been elsewhere deleted. This might include a scenario with several threads working on the same instance or caching a retrieved instance in a local variable and then accessing its related fields that have been deleted. Simple solutions to this problem include synchronizing the code or retrieving fresh instance of an object, before introducing any changes.
Problem: CRUD operations on instances with many-to-many relationship do not work properly
Explanation: There are several rules that must be followed while working with many-to-many relationships. As per Datanucleus contract, it is expected that the user takes care of the following things:
- the hashCode and equals methods must be set in all entities as mentioned in the hashCode / equals guidelines
- while adding an object to many-to-many relationship, it must be set on the both ends of the relation; otherwise, Datanucleus won’t know which side of the relationship is correct
- while deleting an object with many-to-many relationship, it must first be removed from the other side of the relationship, to avoid errors about an object being linked to other objects
- moreover, please see the Datanucleus documentation about many-to-many relationships
In case of other problems or explanations not being helpful enough, please contact us via mailing list, so we can investigate your case. You will get a faster response if you provide a piece of code that reproduces the issue.
Using DataNucleus annotations¶
DataNucleus JDO annotations can be used for enhancing DDEs. These annotations will be taken into consideration by DataNucleus and override the metadata that MDS generates. For example the @javax.jdo.Unique annotation can be used in order to mark fields in an entity as unique. Refer to the DataNucleus documentation for more information on using those annotations.
DDE service interfaces¶
DDEs can define their own interfaces that extend the default service interface that will be used for generating MDS services. The service will be published under that interface, and thanks to inheritance, it will also expose type safe methods from the base service. Here is an example of defining an interface for a ‘Patient’ DDE:
public interface PatientDataService extends MotechDataService<Patient> {
}
Thanks to this declaration type safe access to methods of the interface will be gained, the generic parameter Patient will be inserted for the returned/parameter values.
This way of defining services for DDEs also allows to define additional lookups on the service. These lookups are defined as plain method declarations with annotations and their implementation will be generated at runtime by MDS. The lookup method must be annotated with a @Lookup annotation. Method parameters should be marked with @LookupField annotation in order to connect the parameter with the actual entity field.
Note
If the @LookupField annotation is not present, MDS will fall back to an attempt to recognize the method parameter name, take note that this requires debug information at runtime, so you have to compile your classes appropriately.
public interface PatientDataService extends MotechDataService<Patient> {
/*
* This lookup finds a single patient based on the field 'name'.
* So invoking this method like this: byName("John") will
* return the patient with the name "John".
*/
@Lookup
Patient byName(@LookupField(name = "name") String name);
/*
* The count method. Note that if this method is not defined,
it will be generated automatically from the lookup above.
*/
long countByName(String name);
/*
* Same as above, but returns multiple results.
*/
@Lookup
List<Patient> byName2(@LookupField(name = "name") String name);
/*
* Same as above, but with QueryParams. Note that if this method is not defined,
it will be generated automatically from the lookup above.
*/
@Lookup
List<Patient> byName2(@LookupField(name = "name") String name, QueryParams queryParams);
}
The type of the parameter must match the type of the field, unless its one of the two special types:
Range - ranges can be used for looking up values that fall within the given range. An example is a range of dates. Range consist of min and max values, it is possible to provide only one of these values so there will be no boundary on the second end.
public interface PatientDataService extends MotechDataService<Patient> {
/*
* Looks up patients for which the date of birth falls in the supplied range of
* values. Example of usage:
byDateOfBirth(new Range<>(DateTime.now().minusYears(30), DateTime.now().minusYears(10)));
* this returns patients born between 30 and 10 years ago.
*/
@Lookup
List<Patient> byDateOfBirth(@LookupField(name = "dob") Range<DateTime> dobRange);
}
Set - Doing lookups by sets is also possible. Instead of providing a single value, you provide a set of values. If an instance field matches one of the values, that is considered a hit(basically this is logical OR matching).
public interface PatientDataService extends MotechDataService<Patient> {
/*
* Looks up patients which name matches one of the values from the set.
* Usage example:
*
* byName(new HashSet<>(Arrays.asList("Tom", "John", "Bob")));
*
* This will return patients named Tom, John or Bob.
*/
@Lookup
List<Patient> byName(@LookupField(name = "name") Set<String> names);
}
Lookups can also use custom operators. The operator is inserted between the field name and the lookup parameter in the JDO query generated for the lookup. The default symbol is ‘=’ - the equality sign, however different operators can also be used. Both JDO QL operators and methods can be used for lookups. If an operator like “<” is provided as the custom operator, it will be put between field name and parameter value. If the operator has the form a function like “matches()” it will generate a method call of the form “parameter.matches(value)” - the value is inserted between the brackets. In order to provide a custom operator for a lookup field, the customOperator field of the @LookupField annotation has to be set:
public interface PatientDataService extends MotechDataService<Patient> {
/*
* Does a matches() lookup on the name field.
* Because matches() is used, a regex pattern can be passed as the parameter.
*/
@Lookup
List<Patient> byName(@LookupField(name = "name", customOperator = "matches()") String name);
}
Note
The list of standard JDO operators that can be used in lookups is defined as constants in the class org.motechproject.mds.util.Constants.Operators.
Defining editable lookups for DDE entities¶
One way to define lookups for DDE entities is to include a mds-lookups.json
file in module resource directory.
The file should be a valid array of EntityLookups
class objects. Every lookup defined in the file will be added
only once, so even after user had deleted lookup it won’t be recreated during module or MOTECH restart. This gives the
user complete control over those lookups without any restrictions. The unique identifier of every lookup is its
entity class name and lookup name combination. This is the intended way for modules to define lookups that should be
made editable by the end user. Backend code should not depend on these lookups.
Example mds-lookups.json
file.
[
{
"entityClassName" : "org.motechproject.tasks.domain.mds.task.Task",
"lookups" : [
{
"lookupName" : "Find Task by Owner",
"singleObjectReturn" : false,
"exposedViaRest" : false,
"lookupFields" : [
{
"name" : "owner",
"type" : "VALUE",
"customOperator" : "\u003d\u003d",
"useGenericParam" : false
}
],
"readOnly" : false,
"methodName" : "findTaskByOwner",
"fieldsOrder" : [
"owner"
]
}
]
}
]
Including the example json in Tasks module will result in adding lookup for Task entity that will return all tasks that are owned by the specified user.
Programmatic usage of DDE entities¶
All that has to be done in order to use a DDE is to retrieve the service for its interface. Because of the nature of DDEs, their classes are available during compile time. The service reference can be then retrieved using the standard OSGi facilities:
public PatientService getPatientService() {
BundleContext bundleContext = FrameworkUtil.getBundle(Patient.class).getBundleContext();
ServiceReference<PatientService> ref = bundleContext.getServiceReference(PatientService.class);
return ref == null ? null : bundleContext.getService(ref);
}
The preferred way however is to use Blueprint OSGi references. The service will be injected as a Spring bean into the Spring application context of the module and can be then used as any other bean(for example it can be @Autowired into other beans).
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.eclipse.org/gemini/blueprint/schema/blueprint"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.eclipse.org/gemini/blueprint/schema/blueprint
http://www.eclipse.org/gemini/blueprint/schema/blueprint/gemini-blueprint.xsd">
<osgi:reference id="patientDataService" interface="org.motechproject.example.PatientService"/>
</beans>
Once the service instance is obtained, the only thing left to do is to just call the right method exposed.
Note
Usually a module should provide a service layer between the end user and the data layer implemented by MDS. It is not required however and left to the implementer.
Record versioning and optimistic locking¶
DDE entities support versioning of records. A version will be automatically increased after each update. This feature is useful when other user or other thread is working with the same record. When user performs update but record has been changed before this update an optimistic exception will be thrown. To enable versioning for the entity developer can extend MdsVersionedEntity or can use the @Version annotation. The following example shows how to use the annotation.
@Entity
@Version(strategy = VersionStrategy.VERSION_NUMBER, column = "version",
extensions={@Extension(vendorName = "datanucleus", key="field-name", value="version")})
public class VersionedEntity {
@Field
private Long version;
}
Note
Very important with REST API is to expose version field.
MEDE - MDS Enhanced Developer Defined Entities¶
MEDE, MDS Enhanced Developer Defined Entities, are the DDE that were enhanced by users with additional fields at runtime. In practice they are not much different from DDEs. The only difference lies in the additional fields added at runtime. These fields are not part of the class at compile time, so access to these fields has to be done using reflections. They can also be set through the MDS Data Browser, so this is a way for nontechnical users to attach their own schema to the model.
Extending DDEs through the UI¶
Extending DDEs through the UI is not different from manipulating the schema of EUDE entities. Refer to the documentation section on creating EUDE entities for more info. In order to extend a DDE first go the MDS Schema Editor and select the DDE entity you wish to edit:
Next add the field you wish to add to the entity:
You can also add lookup to the DDE:
Finally, save your changes to trigger MDS schema regeneration and make your changes take effect(you can also abandon your changes if you wish):
Extending DDEs through code¶
Extending DDEs through code is no different from extending EUDE entities. The only difference is that the EntityDto for the DDE has to be retrieved by providing its class name. Refer to the documentation on extending EUDE through code.
Supported field types¶
MDS supports multiple types
MDS Type | Java type | MySQL DB type | PostgreSQL DB type | Description |
---|---|---|---|---|
Blob | java.lang.Byte[] | mediumblob | bytea | A huge binary object, used to represent binary objects such as files or images. |
Boolean | java.lang.Boolean | bit(1) | boolean | A boolean field, that can take either true or false as value. |
Combobox | Based on settings: enum enum collection java.lang.String String collection | separate table separate table varchar separate table | separate table separate table varchar separate table | A combobox showing users a selection of predefined values. It can take single or multiple selections and can be configured to take user defined values. |
java.util.Date | datetime | timestamp with time zone | A type representing the java.util.Date. Only available for DDE. | |
org.joda.time.LocalDate | date | date | A type representing the LocalDate class from the Joda library. Does not represent time, only date. Only available for DDE. | |
org.joda.time.DateTime | datetime | timestamp with time zone | A type representing the DateTime class from the Joda library. Only available for DDE. | |
Date | java.time.LocalDate | date | date | A type representing the LocalDate class from Java8 time API. Does not represent time, only date. |
DateTime | java.time.LocalDateTime | datetime | timestamp with time zone | A type representing the LocalDateTime class from Java8 time API. |
Decimal | java.lang.Double | double | double precision | A decimal field number. |
Integer | java.lang.Integer | int(11) | integer | An integer number. |
Locale | java.util.Locale | varchar | varchar | A type representing locale. Users will be shown a locale selection dropdown for type. |
Map | java.util.Map | Separate table | Separate table | A map of key-value pairs. |
Period | org.joda.time.Period | varchar | varchar | A type representing the Period class from the Joda library. Represents a period in time, i.e. 3 months. |
String | java.lang.String | varchar | varchar | A string of characters. The max length can be configured. For long text fields, consider using TextArea. |
TextArea | java.lang.String | mediumtext | text | A string of characters without max length. Suited for long text fields. |
Time | org.motechproject. commons.date.model Time | varchar | varchar | A time representation without any date or timezone information. |
Map type¶
You can declare map with keys and values having generic type. MDS supports the following types of generics :
- key types (String, Integer, Long)
- value types (String, Integer, Long)
If you use the supported types, the field will be stored as a separate table in a database. Otherwise the field will be serialized.
Note
In a separate table map keys will be treated as primary keys. By default max key length in InnoDB is 767 bytes. When the innodb_large_prefix configuration option is enabled, this length limit is raised to 3072 bytes, for InnoDB tables that use the DYNAMIC and COMPRESSED row formats. Here you can find more details : http://dev.mysql.com/doc/refman/5.6/en/innodb-parameters.html#sysvar_innodb_large_prefix
History tracking for entities¶
MDS allows to keep track of any changes made on the instances, as well as reverting the state of an instance to a concrete revision. Both viewing the history of an instance and reverting can be done via the code and UI. This feature will only be available if you explicitly set, that the history tracking for your entity should be enabled. If you want to view the history for your instance via UI, simply go to the detailed view of that instance, and click on the History button.
Note
If you introduce any changes to the entity definition (e.g. add or delete a field), you will still be able to view the state of an instance, but you will lose the ability to revert an instance (because of a schema mismatch).
Controlling whether to record history¶
By default MDS doesn’t keep track of the instance revisions. Most of the DDEs that come with MOTECH modules have the tracking of the history disabled as well. To enable history tracking for the...
- Developer Defined Entity (DDE) - You have to set the recordHistory parameter of the @Entity annotation to true.
@Entity(recordHistory = true)
End User Defined Entity (EUDE) - The Enable history audit option is available under the Advanced window of an entity, in the Auditing & Revision Tracking tab
Retrieving history using code¶
MDS exposes an implementation of the org.motechproject.mds.service.HistoryService. To make use of it, you should simply create a reference to that service in your blueprint:
<osgi:reference id="historyServiceOSGi" interface="org.motechproject.mds.service.HistoryService" />
From now on, you will be able to use the history service, just like any other Spring bean, for example, by placing the @Autowired annotation on a field of type org.motechproject.mds.service.HistoryService. The service allows recording history, deleting the whole history for an instance and retrieving the historical revisions of an instance.
MDS Trash Bin¶
When an instance is deleted, it can either be removed completely or moved to the trash. In case an instance is moved to the trash, there will be an ability to view all instances that have been deleted, as well as to restore any instance from the trash. Users may also choose to empty the trash from time to time. All the data retention settings are available in the MDS settings tab. If you choose to empty the trash, MDS will use the scheduler to set up a job, that runs every specified period and empties the trash.
To view instances that have been moved to the trash, click the View trash button, after selecting an entity in the data browser. To restore any instance from the trash, select that instance and click Restore button on the detailed view of the deleted instance.
Note
If you introduce any changes to the entity definition (e.g. add or delete a field), you will lose access to all the deleted instances of the previous schema. That means you will no longer be able to view or restore them anymore.
Using Trash using code¶
Similar to the HistoryService mentioned above, MDS also exposes the TrashService that allows operations on the Trash bin from the code. To use the exposed service, create a reference in your blueprint file:
<osgi:reference id="trashServiceOSGi" interface="org.motechproject.mds.service.TrashService" />
Accessing the service also works the same way as with the HistoryService - treat it as any other Spring bean, for example by placing the @Autowired annotation on the field of type org.motechproject.mds.service.TrashService. The trash service allows to place instances in trash, retrieve instances from trash, schedule the trash purging, empty the trash and check current data retention settings.
The MDS Data Browser¶
The data browser is a place, where you can perform CRUD operations on the instances of an entity. The main window of the data browser shows a list of all entities, grouped by modules to which they belong. From this point, you can choose to view instances of a certain entity by clicking on the name of that entity, or add an instance of an entity by pressing the Add button, next to the entity name.
If you pick one of the entities, you will be brought to the view, showing the instances of that entity. From this view, you can perform several operations on the instances.
Button | Role |
---|---|
Back to entity list | Brings you back to the main data browser view, listing entities |
Add | Brings you to the Add instance dialog, where you can add an instance of an entity |
Lookup | Allows you to view only instances that match certain criteria. The definition of these criteria are set in the Advanced dialog on the Schema Editor |
Fields | Allows you to display only certain fields in the browser. Useful when your entity has got a lot of fields, and you are only interested in few of them |
Import CSV | This option allows the import of instances from a CSV file. If there is an instance with the same id present both in the database and the file, it will get updated with the values from the file |
Export CSV | This option allows the export of all instances of the selected entity to the CSV file |
View trash | Allows to view all instances that have been moved to the trash, on the current entity schema |
If you click on any instance, a detailed view for that instance will be shown. Depending on the entity definition, necessary input fields will be presented, where you can set the values for these fields. You may also choose to delete that instance or view the revision history (if history tracking is enabled for that entity). When you are done editing an instance, click the Save button. To abandon changes, click Cancel.
Data browsing settings¶
The data browsing settings allow to control several data browser UI options for an entity. Available options are:
- The ordering of the entity fields
- The fields to display on the UI by default
- Allow filtering by chosen field values (only available for some types)
- Change UI representation for relationship type fields.
The automatically generated fields are not displayable by default, but all other fields are. The display order is determined based on the order in which they were added. No fields will be marked filterable by default.
Note
The data browser filters can currently only be generated for the Date, DateTime, LocalDate, Boolean and List types.
Changing the settings through the UI¶
To change the data browsing settings via UI, go to the Schema Editor and select an entity for which you wish to set the settings. Go to the Advanced view and pick the Data Browsing tab. The first section, called Display fields, contains two tables. The table to the right shows fields that have been selected to display by default. The table to the left shows all other fields. The order of the fields in the Fields to display table corresponds to the order of the fields in the data browser UI. You can move fields from one table to another and change their order, using provided buttons, or by dragging the fields to their destination. The second section, named Filters allows to pick fields, for which the data browser UI will generate filters. Please note that only fields of a certain types will be displayed. The filters are generated automatically and are adjusted to the field type. For example, for the date types, there will be an option to set a filter for today, this week, this month and this year, while for boolean, this will be only true and false. When you finish making the changes, close the Advanced window and click Save changes.
Changing the settings through annotations¶
The data browsing settings can also be set using MDS annotations. The two annotations that allow this are @UIDisplayable and @UIFilterable. Similar to the @Field annotation, they can be placed on fields, as well as on getters and setters. The @UIFilterable annotation will work only, when placed on the field of a supported type.
Note
If you use the @UIDisplayable annotation on any field of your entity, all other fields, that lack the annotation, will be marked as not displayable.
By default, all fields defined in the entity will be marked as displayable. The @UIDisplayable annotation allows changing this behaviour. If at least one field is marked with the @UIDisplayable annotation, the default behaviour will not be applied, and only annotated fields will be marked displayable. The annotation contains optional position parameter, that allows to pick the position of the field on the data browser UI. The ordering should start with the number zero. Fields are not UIFilterable by default. To allow filtering by field values on the data browser, simply annotate that field with @UIFilterable.
The following code presents the usage of the two annotations:
@Field
private String externalId;
@Field
@UIDisplayable(position = 0)
private String name;
@Field
@UIDisplayable(position = 2)
@UIFilterable
private DateTime dateTime;
@Field
@UIDisplayable(position = 3)
private Long priority;
@Field
@UIDisplayable(position = 1)
private String description;
Changing the UI representation of relationship type fields through annotation¶
The way relationship type fields are displayed can be changed through the @UIRepresentation annotation. This annotation can be placed on a method which takes no arguments and returns String. The @UIRepresentation annotation works only when placed on supported method.
Note
Use the @UIRepresentation annotation only on method for an entity.
By default, the toString method of an entity would be used to get the display value. You can customize this with the @UIRepresentation annotation.
The following code presents the usage of the annotation
@Field
private String externalId;
@Field
private String name;
@UIRepresentation
public String displayValue() {
return "Sample Display Value";
}
The REST API¶
MDS REST API allows to perform CRUD operations on the instances of an entity. By default, no operations are allowed via REST, which means that an administrator, must explicitly allow an access via REST to an entity. Even when an access via REST is enabled for an entity, valid MOTECH credentials must be provided in order for a request to be processed. MDS REST API uses a BASIC access authentication method by default, but that can be changed using dynamic security rules (can be done on a per entity basis). Moreover the standard MDS entity level security will also apply.
REST endpoints¶
The general endpoint to the MDS REST operations is:
http://<motech-server-address>/module/mds/rest/<<path>>
The table below explains what HTTP request method are supported for each of the CRUD operation, as well as how the “path” should look like.
Operation | HTTP requests | Paths | Notes |
---|---|---|---|
Create | POST | /{moduleName}/{namespace}/{entityName}
/{moduleName}/{entityName}
/{entityName} |
The data sent with the request should contain JSON representation of the object |
Read | GET | /{moduleName}/{namespace}/{entityName}
/{moduleName}/{entityName}
/{entityName} |
Can take multiple params, like ?page=1&pageSize=20&sort=name |
Read - Lookup | GET | /lookup/{moduleName}/{namespace}/{entityName}/{lookupName}
/lookup/{moduleName}/{entityName}/{lookupName}
/lookup/{entityName}/{lookupName} |
Can take multiple params, like ?page=1&pageSize=20&sort=name Lookup parameters should be provided as request parameters. |
Update | PUT | /{moduleName}/{namespace}/{entityName}
/{moduleName}/{entityName}
/{entityName} |
The instance to update will be determined on the id, taken from included JSON representation |
Delete | DELETE | /{moduleName}/{namespace}/{entityName}/{instanceId}
/{moduleName}/{entityName}/{instanceId}
/{entityName}/{instanceId} |
Note
EUDE are never assigned to any module. For DDE, the module name should not contain the “motech” or “motech-platform” prefix, if the module has one.
Response codes¶
These are the response codes returned by the MDS REST API:
- 200 OK - The operation was successful. Note that delete is idempotent, meaning 200 will be also returned for already deleted items.
- 400 Bad Request - The body or parameters provided in the request are invalid.
- 401 Unauthorized - The caller is not authorized and thus not permitted to execute the operation.
- 403 Forbidden - The user does not have necessary rights to execute the operation.
- 404 Not Found - Either the given entity or the requested object does not exist.
- 500 Internal Server Error - The request cannot be processed due to a server error.
Read response¶
In case of read operations Motech also adds metadata to the response. Response is divided into two sections: metadata and data. The metadata contains following fields:
Name | Description | Type |
---|---|---|
entity | The entity name of the instances. | String |
className | The name of the entity class. | String |
module | The module name of the entity. Null in case of EUDE entity. | String |
namespace | The namespace in which the entity is defined. | String |
totalCount | The total number of instances that match the search conditions. 1 i
case of retrieving with id parameter or with a single object
lookup. |
Long |
page | The page number. | Integer |
pageSize | The page size. | Integer |
Below you can find sample response:
{
"metadata": {
"entity": "EmailRecord",
"className": "org.motechproject.email.domain.EmailRecord",
"module": "MOTECH Platform Email",
"namespace": "",
"totalCount": 2,
"page": 1,
"pageSize": 20
},
"data": [
{
"id": 1,
"creator": "admin",
"owner": "admin",
"modifiedBy": "admin",
"deliveryStatus": "SENT",
"toAddress": "adress1@organisation.com",
"subject": "Subject 1",
"message": "Sample message",
"fromAddress": "adress2@organisation.com",
},
{
"id": 2,
"creator": "admin",
"owner": "admin",
"modifiedBy": "admin",
"deliveryStatus": "SENT",
"toAddress": "adress1@organisation.com",
"subject": "Subject 2",
"message": "Other message",
"fromAddress": "adress2@organisation.com",
}
]
}
Parameters and lookups¶
When retrieving the instances using MDS REST API (GET request), there’s an ability to apply some parameters, to have a better control on the result of the request. The parameters are applied as any other GET request parameters.
- id Return a single instance, with the provided id
- pageSize Defines an amount of instances that should be returned per request (defaults to 20)
- page Defines a result page that should be returned (defaults to 1)
- sort Defines a column that should be used to sort the instances in the result
- order Either “asc” or “desc”
- lookup A name of lookup that should be used to retrieve the instances. A lookup must be marked as exposed via REST in order for this to work. The values used in the lookup should be provided as GET request parameters. This an alternative way of calling a lookup, rather than calling it through the lookup url described above.
Below, you will find some examples of valid REST URLs. Assume our entity is called MyEntity.
http://<<address>>:<<port>>/motech-platform-server/module/mds/rest/MyEntity
Return 20 records from the first page (default settings applied)http://<<address>>:<<port>>/motech-platform-server/module/mds/rest/MyEntity?id=15
Return an instance with id 15http://<<address>>:<<port>>/motech-platform-server/module/mds/rest/MyEntity?page=2&pageSize=50&sort=name&order=asc
Return 50 records from the second page, having sorted the instances by name field ascendinghttp://<<address>>:<<port>>/motech-platform-server/module/mds/rest/MyEntity?lookup=byName&name=Laura
Executes a lookup named “byName” with the lookup field “name” being “Laura” on the entity “MyEntity” and returns results.
REST fields exposed¶
By default all fields are marked as exposed via REST, both for DDE and EUDE. If you choose to hide some of them, they will simply be ignored, when performing CRUD operations via REST on them. When retrieving instances, the result will not contain the fields that are not exposed and when updating or creating instances, the hidden fields will be ignored, even if they are present in the provided JSON representation.
Changing REST settings through the UI¶
You can access the REST API settings by selecting an entity in the Schema Editor and then opening the advanced settings, by clicking on the Advanced button. On the new window, navigate to the REST API tab.
The settings may contain up to three sections:
- The first one, named Fields allows to pick fields that should be exposed via REST. Fields in the table to the right are exposed and fields in the table to the left are not. You can drag and drop fields from one table to another or select them and use provided buttons.
- The next section is named Actions and defines the operations on the instances that are allowed via REST for this entity. By default, no action is allowed. You can choose to change it, by selecting some or all of the actions.
- The last section, called Lookups will appear only if there is at least one lookup defined for an entity. This section allows to pick the lookups that can be executed via REST. Note, that to execute lookups at all, a “Read” action must be enabled.
Changing REST settings through annotations¶
The REST settings can also be applied using MDS annotations. The three annotations that allow this, are:
- @org.motechproject.mds.annotations.RestIgnore As stated in the previous sections, be default all fields are exposed via REST. You can adjust this behaviour using this annotation. Annotated fields will not be exposed via REST.
- @org.motechproject.mds.annotations.RestOperations Placed on the entity class definition, specifies the REST operations that should be allowed for this entity. The annotation takes an array of org.motechproject.mds.annotations.RestOperation, which is an enum of possible values.
- @org.motechproject.mds.annotations.RestExposed Placed on the lookup method definition, in the service interface. Annotated lookup methods will be marked as exposed via REST. By default, lookups are not exposed via REST.
The code below shows an example usage of the annotations:
@Entity
@RestOperations({RestOperation.CREATE, RestOperation.READ})
public class MyEntity {
@Field
@RestIgnore
private Integer number;
@Field
private String emailAddress;
@Field
private String message;
}
public interface MyEntityService extends MotechDataService<MyEntity> {
@Lookup(name = "By number")
List<MyEntity> findByNumber(@LookupField(name = "number") Integer number);
@Lookup(name = "By Email Address")
@RestExposed
List<MyEntity> findByEmailNumber(@LookupField(name = "emailAddress") String emailAddress);
}
REST documentation¶
MOTECH provides a user interface that documents and allows the testing of the REST API exposed by MDS. This interface is generated using Swagger. In order to access this UI, first select REST API in the top menu, then Data Services in the sub-menu.
The raw Swagger specification file (JSON format) is accessible at <your_motech_url>/module/mds/rest-doc.
Entity validations¶
MDS allows to set up validations on the fields of an entity. A validation ensures that values of created instances will match some criteria. The validations are applied on two levels:
- UI - MDS UI will check the values when adding or editing instances and display hints or errors, when the value does not match some of the defined validations.
- Code - Attempting to save an instance that has got invalid values, using the retrieved MotechDataService, will result in a ConstraintViolationException.
Configuring validations through the UI¶
To set up validations for a field of an entity, open the Schema Editor and select an entity, for which you wish to set validations. Expand the field that should be validated and navigate to the Validation tab.
Only some of the MDS types support setting up validations via UI, so if a selected field is of a type that is not supported, the Validation tab will not appear. Please see the list of supported types and validations below.
Type | Validation | Annotation | Description |
---|---|---|---|
String | Regex | @javax.validation.constraints.Pattern | Allows to set up a regular expression. Only strings that match the regex will be accepted. |
String | Minimum length | @javax.validation.constraints.Size | Defines a minimal number of characters the strings must have. |
String | Maximum length | @javax.validation.constraints.Size | Defines a number of characters the strings cannot exceed. |
Integer / Decimal | Minimum value | @javax.validation.constraints.Min @javax.validation.constraints.DecimalMin | Defines a minimal number that will be accepted. |
Integer / Decimal | Maximum value | @javax.validation.constraints.Max @javax.validation.constraints.DecimalMax | Defines a maximal number that will be accepted. |
Integer / Decimal | Must be in set | @org.motechproject.mds.annotations.InSet | Only numbers that have been explicitly specified will be accepted. |
Integer / Decimal | Cannot be in set | @org.motechproject.mds.annotations.NotIn Set | All numbers that have not been explicitly specified will be accepted. |
Note
Setting up validations via UI is only possible for the EUDE.
The Regex validation contains some predefined patterns, for the most common use cases. To view them, click Select, next to the Regex input field and pick one of the available, predefined expression. This will automatically, place the regular expression in the input field. Please note, that this operation will erase the current value in the field, if there’s any provided.
Setting up validations will display hints while adding an instance of an entity, that has got validated fields. An attempt to add an instance with invalid values, will display an error and block the ability to save the instance.
Configuring validations using annotations¶
For DDEs, it is possible to set up validations using the annotations. MDS will recognize the @javax.validation.constraints annotations, as well as two MDS-defined annotations: @org.motechproject.mds.annotations.InSet and @org.motechproject.mds.annotations.NotInSet. See the code below, for an example of validation definition through annotations.
@Entity
public class MyEntity {
@Field
@Min(10)
@Max(100)
private Integer number;
@Field
@Pattern(regexp = "^\\w+([\\.-]?\\w+)*@\\w+([\\.-]?\\w+)*(\\.\\w{2,3})+$")
private String emailAddress;
@Field
@AssertTrue
private Boolean alwaysTrue;
@Field
@Size(min = 64, max = 2048)
private String message;
}
Note
When using annotations, take into consideration what field types they can be applied to. Most of the annotations support only one or a few types.
Even though you can use any @javax.validation.constraints annotation on an entity field, the UI support (hints, error messages), will only be displayed for the validations listed in the previous section, about setting validation through UI. Other validations will not show up on the UI, but it still will not be possible to add an invalid value - a ConstraintViolationException will be thrown.
MDS Lookup Service¶
The org.motechproject.mds.service.MdsLookupService is an OSGi service which allows easy access to executing queries on entities without compile time access to their classes. It can also be useful for executing on entities without knowing the entity name at compile time. An example is the IVR module which exposes this service to velocity templates, allowing users data access.
Note
As with all MDS API, the MdsLookupService uses the underlying MotechDataService for the entity underneath. It is really just a facade for service access.
The service exposes these methods:
public interface MDSLookupService {
<T> T findOne(Class<T> entityClass, String lookupName, Map<String, ?> lookupParams);
<T> T findOne(String entityClassName, String lookupName, Map<String, ?> lookupParams);
<T> List<T> findMany(Class<T> entityClass, String lookupName, Map<String, ?> lookupParams);
<T> List<T> findMany(String entityClassName, String lookupName, Map<String, ?> lookupParams);
<T> List<T> findMany(Class<T> entityClass, String lookupName, Map<String, ?> lookupParams,
QueryParams queryParams);
<T> List<T> findMany(String entityClassName, String lookupName, Map<String, ?> lookupParams,
QueryParams queryParams);
<T> List<T> retrieveAll(Class<T> entityClass);
<T> List<T> retrieveAll(String entityClassName);
<T> List<T> retrieveAll(Class<T> entityClass, QueryParams queryParams);
<T> List<T> retrieveAll(String entityClassName, QueryParams queryParams);
long count(Class entityClass, String lookupName, Map<String, ?> lookupParams);
long count(String entityClassName, String lookupName, Map<String, ?> lookupParams);
long countAll(Class entityClass);
long countAll(String entityClassName);
}
For the examples below assume the following classes:
@Entity
public class Patient {
@Field
public String name;
@Field
public Integer age;
@Field
private Set<Visit> visits;
}
@Entity
public class Visit {
@Field
public Integer officeNumber;
@Field
public DateTime date;
}
with the following lookups defined in its data service:
public interface PatientService extends MotechDataService<Patient> {
@Lookup
Patient byName(@LookupField(name = "name") String name);
@Lookup
List<Patient> byAge(@LookupField(name = "age") Integer age);
}
The findOne methods can be used to execute single return lookups given the lookup name, the entity class name(or class object) and map consisting of the lookup params, where the key is the lookup parameter name and the value is the actual parameter. Usage example:
Map<String, ?> params = new HashMap<>();
params.put("name", "John");
// type safe method
Patient patient = mdsLookupService.findOne(Patient.class, "findByName", params);
// alternative method
Patient patient = (Patient) mdsLookupService.findOne("org.motechproject.example.Patient", "findByName", params);
The findMany method can be used to execute multiple result lookups. Additional versions of the method allow executing the lookup with QueryParams, which control/pagination ordering. Usage example:
Map<String, ?> params = new HashMap<>();
params.put("age", 29);
// type safe method
Patient patient = mdsLookupService.findOne(Patient.class, "findByAge", params);
// alternative method
List<Patient> patients = (List<Patient>) mdsLookupService.findOne("org.motechproject.example.Patient", "findByAge", params);
// with QueryParams
// first page, with pages consisting of 10 records
// order by name, descending
QueryParams queryParams = new QueryParams(1, 10, new Order("name", Order.Direction.DESC));
// type safe method
Patient patient = mdsLookupService.findOne(Patient.class, "findByAge", params, queryParams);
// alternative method
List<Patient> patients = (List<Patient>) mdsLookupService.findOne("org.motechproject.example.Patient", "findByAge", params, queryParams);
The retrieveAll methods can be used as above with omission of parameter maps, since instead of using a lookup, it retrieves all records from the database executing retrieveAll on the service.
The count and countAll methods are also no different in terms of usage. The only difference is that they return the number of instances returned by a lookup and the total number of instances respectively.
Lookups on relationship fields can be used like in the example below:
public interface PatientService extends MotechDataService<Patient> {
@Lookup
List<Patient> byVisitsDate(@LookupField(name = "visits.date") DateTime date);
@Lookup
List<Patient> byVisitsDateAndVisitsOffice(@LookupField(name = "visits.officeNumber") Integer officeNumber
@LookupField(name = "visits.date") Range<DateTime> date);
}
Note
MDS Lookups support only first depth level of relationships.
Executing custom queries¶
Executing JDO queries¶
MDS allows developers to use the JDO API offered by DataNucleus to execute any query they wish. A utility method for calling direct SQL queries through DataNucleus. Although the approach of executing custom queries gives the user all the flexibility he needs, the more easier and recommended approach is to use Lookups instead. This API remains in place however in order to fulfil the more complex requirements.
In order the execute a custom JDO query, the developer has to implement the org.motechproject.mds.query.QueryExecution interface and pass an instance of this implementation to the executeQuery(QueryExecution) method. This interface exposes one method - execute(javax.jdo.Query, org.motechproject.mds.util.InstanceSecurityRestriction). The first a parameter is the javax.jdo.Query instance class created using the PersistenceManager for the entity class of the data service being used, the second is an object describing security restrictions on the entity.
What is returned by the interface method will be also returned by the executeQuery() call on the data service. The interface is generic, the type parameter represents the return value.
Following is an example of executing a custom JDO query. Given a simple entity:
@Entity
public class Example {
public Integer amount;
public String name;
}
Here is an example of a JDO query that will check the amount value and based on that select only the names from the database:
// get the service for the entity you wish to execute the query on
MotechDataService<Example> service = getService();
QueryExecution<List<String>> queryExecution = new QueryExecution<List<String>>() {
@Override
public List<String> execute(Query query, InstanceSecurityRestriction restriction) {
// return objects with the amount value either less then 1000 or greater then 1000
query.setFilter("amount < 100 || amount > 1000");
// select only the name column
query.setResult("name");
// limit the results
query.setRange(0, 100);
return (List<String>) query.execute();
}
};
List<String> names = service.executeQuery(queryExecution);
More info on JDO queries can be found here: http://www.datanucleus.org/products/datanucleus/jdo/jdoql.html
Executing SQL queries¶
Similar to executing JDO queries MDS also provides developers with access to executing SQL queries. Instead of implementing the QueryExecution interface however, developers have to implement the org.motechproject.mds.query.SqlQueryExecution interface. This interface has two methods, execute(javax.jdo.Query) and getSqlQuery(). The contents of the SQL query should be returned by the getSqlQuery methods, so that MDS can construct the JDO query using that SQL.
Following is an example of executing a custom SQL query. Given a simple entity:
@Entity
public class Example {
public Integer amount;
public String name;
}
Here is an example of a SQL query that will return values with the given amount:
// there is really no impact on which data service is used, since this is raw sql
MotechDataService<Example> service = getService();
SqlQueryExecution<List<String>> sqlQueryExecution = new SqlQueryExecution<List<String>>() {
@Override
public List<String> execute(Query query) {
// usage of params
Map<String, Integer> params = new HashMap<>();
params.put("param", 5);
return (List<String>) query.executeWithMap(params);
}
@Override
public String getSqlQuery() {
// this query will be executed by MDS
return "SELECT name FROM MDS_EXAMPLE WHERE amount = :param";
}
};
List<String> names = service.executeSQLQuery(sqlQueryExecution);
Note that using raw SQL should be the absolute last resort, it is advised to stick to more high-level concepts in your code.
Using Spring Transactions with MDS¶
Spring transactions (the @Transactional annotation) can be used inside your MOTECH module with MDS, however this requires some setup inside the module that wishes to use these transactions.
Firstly, Spring annotation driven transactions must be configured in the Spring context. The transaction manager that is used, must be the one exposed by the MDS entities bundle as an OSGi service. Below is a minimal example configuration that defines a reference to the MDS transaction manager and uses it when declaring annotation driven transactions:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.eclipse.org/gemini/blueprint/schema/blueprint"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.eclipse.org/gemini/blueprint/schema/blueprint http://www.eclipse.org/gemini/blueprint/schema/blueprint/gemini-blueprint.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<tx:annotation-driven transaction-manager="transactionManager"/>
<osgi:reference id="transactionManager" interface="org.springframework.transaction.PlatformTransactionManager" context-class-loader="unmanaged"/>
</beans>
Note
Setting the context-class-loader to unmanaged will prevent switching the context classlaoder to the incorrect one, since the platform transaction manager is treated as an OSGi proxy itself. This issue can manifest in bundle ITs, where the wrong context classloader can be used, leading to errors about missing metadata.
Thanks to this configuration, Spring transaction annotations should work properly in your module, take note however that you might be required to explicitly import the following packages (example of the bundle plugin configuration):
<Import-Package>
org.aopalliance.aop,
org.springframework.aop,
org.springframework.aop.framework,
org.springframework.cglib.core,
org.springframework.cglib.proxy,
org.springframework.cglib.reflect,
org.springframework.transaction,
*
</Import-Package>
After this you can simply use the @Transactional annotation to mark your methods as transactions. Make sure you are using the correct @Transactional annotation (org.springframework.transaction.annotation.Transactional). Example of a bean using the annotation:
@Component
public class TransactionTestBean {
@Autowired
private BookDataService bookDataService;
@Transactional
public void addTwoBooks() {
bookDataService.create(new Book("Book1"));
bookDataService.create(new Book("Book2"));
}
@Transactional
public void addTwoBooksAndRollback() {
addTwoBooks();
// throwing a runtime exception rolls back the entire transaction
throw new IllegalStateException("Rollback the transaction");
}
}
More information on Spring transactions can be found here: http://docs.spring.io/spring/docs/current/spring-framework-reference/html/transaction.html
Note
Take note that these annotations will work only with Spring beans.
Security¶
Access to the Data Services module¶
MDS registers three permissions, that restrict access to certain parts of the Data Services module via MOTECH UI. They are:
- mdsSchemaAccess (grants access to the Schema Editor)
- mdsDataAccess (grants access to the Data Browser)
- mdsSettingsAccess (grants access to the Settings panel)
The MDS Admin role contains all of these three permissions.
Access to the instances¶
Depending on the chosen option, two security levels can be recognised in MDS:
Security level | Description |
---|---|
Instance | Defines access to certain instances of an entity. Only permitted users will be able to see the instance and perform any CRUD operations on it. |
Non-instance | Defines access to all the instances of an entity. Only permitted users will be able to see the link to the instances table and perform CRUD operations on them. |
Security settings can be set through the UI or by the @org.motechproject.mds.annotations.Access annotation for DDE. It works only with the @Entity annotation.
There are five security modes:
Option | Security level | Description |
---|---|---|
EVERYONE | None | The access to the instances is not limited in any way. |
OWNER | Instance | Only the user that has been selected as an owner of the instance has got access. An owner can be selected while adding/editing instance. |
CREATOR | Instance | Only the user that has created the instance has got access and can perform CRUD operations on it. |
USERS | Non-instance | An additional input field will appear, where a list of permitted users should be placed. Permitted users will be able to view and perform CRUD operations on all instances of an entity. |
ROLES | Non-instance | Similar to Users - an additional input field will appear, where a list of roles should be placed. Users that have got any of the permitted roles, will be able to view and perform CRUD operations on all instances of an entity. |
The code below shows an example usage of the annotation:
@Entity
@Access(value = SecurityMode.ROLES, members = {"admin"})
public class MyEntity { }
To update security settings via UI, pick the entity and click the Security button.
A new modal window will appear, where security settings can be updated.
Note
The security settings are applied to all means of access to the instances. It does not matter if an access is attempted via UI, through the code or REST - the necessary permissions will always be checked. This also means that it is possible to disallow the application itself to access the instances, so be careful when restricting access to the MOTECH entities.
CRUD Events¶
By default, MDS sends CRUD events after a Create/Update/Delete operation is completed, which can be optionally disabled through the UI or by the @org.motechproject.mds.annotations.CrudEvents annotation for DDE. It works only with the @Entity annotation.
The annotation has five options:
Option | Description |
---|---|
CREATE | Enable MDS to send events during creating instances of an entity. |
UPDATE | Enable MDS to send events during updating instances of an entity |
DELETE | Enable MDS to send events during deleting instances of an entity |
ALL | Enable MDS to send events during creating, updating and deleting instances of an entity |
NONE | None of the CRUD events will be sent by MDS |
The code below shows an example usage of the annotation:
@Entity
@CrudEvents(CrudEventType.CREATE)
public class MyEntity {
@Field
private String message;
}
Note
Of course you can mix options (for example using CREATE and UPDATE).
To turn off sending events for an EUDE you have to disable the feature in the Advanced settings, ‘Auditing & Revision Tracking’ section. You can also do the same for a DDE. After changes are made, a flag modifiedByUser will be set to true, which means for a DDE, that the crud event settings will not be reloaded from the annotation upon restart.
The subject of MDS CRUD events takes the form of “mds.crud.<module name>.<namespace>.<entity name>.<action i.e. UPDATE|DELETE|CREATE>”. The event payload contains 5 parameters:
- object_id - the ID of the object this event refers to
- entity_name - the name of the entity
- entity_class - the fully qualified class name of the entity
- module_name - the name of the module from which the entity comes from (optional)
- namespace - the namespace of the entity (optional)
A separate event is also fired once a CSV import is completed. The subject of the event is similar to a regular CRUD event and takes the form of “mds.crud.<module name>.<namespace>.<entity name>.csv-import.<success|failure>”.
The payload for a CSV import success event contains the following parameters:
- entity_name - the name of the entity for which this import was performed
- entity_class - the fully qualified class name of the entity for which this import was performed
- module_name - the name of the module from which the entity comes from (optional)
- namespace - the namespace of the entity for which this import was performed (optional)
- csv-import.filename - the name of the imported file
- csv-import.created_ids - a list of IDs for instances newly created during import
- csv-import.updated_ids - a list of IDs for instances updated during import
- csv-import.created_count - the count of instances newly created during import
- csv-import.updated_count - the count of instances updated during import
- csv-import.total_count - total count of instances created/updated by this import(sum of the created count and updated count)
The payload for the import failure event is different:
- entity_name - the name of the entity for which this import was performed
- entity_class - the fully qualified class name of the entity for which this import was performed
- module_name - the name of the module from which the entity comes from (optional)
- namespace - the namespace of the entity for which this import was performed (optional)
- csv-import.filename - the name of the imported file
- csv-import.failure_message - the message from the exception that caused the failure
- csv-import.failure_stacktrace - the stacktrace of the exception that caused the failure(as String)
Tasks integration¶
For the entities that expose these events, you can create tasks with these events as a trigger. To do it go to the Task module, click ‘New task’ and you should see the Data Services trigger list. A trigger is exposed for every crud event per entity:
In the Task module, you can also use Data Services as a channel and select an action you want :
Instance Lifecycle Listeners¶
In MDS you can register listeners for persistence events. You can provide listener to receive events for CREATE, DELETE, LOAD, and STORE of objects. To do this you have to use the @org.motechproject.mds.annotations.InstanceLifecycleListener annotation on service methods.
The annotation value is an array of one or more values :
Option | Description |
---|---|
POST_CREATE | Invoked after an instance is made persistent. |
PRE_DELETE | Invoked before a persistent instance is deleted. Access to field values within this call are permitted. |
POST_DELETE | Invoked after a persistent instance is deleted. This method is called after the instance transitions to persistent-deleted. Access to field values is not permitted. |
POST_LOAD | Invoked after a persistent instance is loaded from the data store. |
PRE_STORE | Invoked before a persistent instance is stored, for example during committing a transaction. |
POST_STORE | Invoked after a persistent instance is stored. It is called after the field values have been stored. |
Note
The listener is called within the same transaction as the operation being reported and so any changes they then make to the objects in question will be reflected in that objects state. Throwing a RuntimeException from a listener will fail the transaction.
The code below shows an example usage of the annotation:
public interface MyService {
@InstanceLifecycleListener(InstanceLifecycleListenerType.POST_CREATE)
void changeSubject(EmailRecord emailRecord);
@InstanceLifecycleListener(InstanceLifecycleListenerType.POST_STORE, packageName = "org.motechproject.example")
void entityChanged(Object o);
}
@Service("myService")
public class MyServiceImpl implements MyService {
public void changeSubject(EmailRecord emailRecord) {
emailRecord.setSubject("newSubject");
}
public void entityChanged(Object o) {
// process the entity
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:osgi="http://www.eclipse.org/gemini/blueprint/schema/blueprint"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.eclipse.org/gemini/blueprint/schema/blueprint
http://www.eclipse.org/gemini/blueprint/schema/blueprint/gemini-blueprint.xsd">
<osgi:service ref="myService" interface="org.motechproject.example.MyService"/>
</beans>
Note
If you want you can mix options (for example using POST_CREATE and POST_STORE).
You have to remember about the following when using InstanceLifecycleListeners :
- Methods annotated with @org.motechproject.mds.annotations.InstanceLifecycleListener must be in services exposed by OSGi
- Methods must have exactly one parameter and its type must be either a persistable class or java.lang.Object if the package is specified.
- You can annotate multiple methods for one type of event
The annotated method is a listener for class defined in the parameter type (in our example for EmailRecord).
Entities Migrations¶
In MDS you can use flyway migrations. These migrations will run after entities schema generation. MOTECH will automatically
copy migration files from installed modules to the .motech
directory. Files should be placed in db/migration/default
directory(if you are using mysql then use mysql
instead default
) in the bundle. Each file muse have
a proper name <http://flywaydb.org/documentation/migration/sql.html>`_(e.g. :code:`V1__Description.sql).
Schema Import/Export¶
This section explains how to import and export MDS Schema. It can be done with only a few steps using the MDS module UI.
Schema Import¶
The first thing you need to do is to enter Import tab under the Settings.
Once in the Import tab, you will have to click the “Select file” button and choose the file you want to import the schema from. It must be a valid JSON file that contains a valid schema definition, otherwise an error will occur while parsing it.
Here, all you have to do is to click the Submit button. MDS will now parse the JSON file and display entities for review on the following screen.
Now you can select which entities you want to import. You can achieve this by simply ticking or unticking the checkboxes next to the entity or module name in the Schema column. Ticking the checkbox next to the module name will result in importing all the entities originating from that module, while ticking the checkbox next to the entity name will result in importing only that entity. If the given JSON contains instances of the entities you are importing schema for, you can also import them by ticking the checkboxes next to the entity or module name in the data column. Once you have selected all the entities you want to import schema and/or instances for, simply click the Import button. Keep in mind that importing schema for entities that already exist will result in removing data related to those entities. Two entities are considered equal if they have the same class name. For information on how relationships are handled please visit the Relationship handling section.
Schema Export¶
The first thing you need to do is to enter Export tab under the Settings.
Now you can select which entities you want to export. You can achieve this by simply ticking or unticking the checkboxes next to the entity or module name in the Schema column. Ticking the checkbox next to the module name will result in exporting all the entities originating from that module, while ticking the checkbox next to the entity name will result in exporting only that entity. You can also export the instances of each of the entities. To achieve this simply tick the checkbox next to the entity or module name in the Data column. Once you have selected all the entities you want to export schema and/or instances for, simply click the Export Selected button. This will generate the JSON file that you can save under the location of your choice. Keep in mind that you can’t export instances of certain entities without exporting their schema. For information on how relationships are handled please visi the Relationship handling section.
Relationship handling¶
There are a few things related to the relationships that you need to remember about during schema export. If there is a relation between two entities both of them must be exported. Also, if you want to export instances of an entity that has relationship with other one you may want to export instances of the second entity as well. If you don’t do this the fields pointing to the other entity will be set to null and may potentially break the database integrity if the field is required.
Javadoc¶
org.motechproject.mds.annotations
/org/motechproject/mds/builder/package-index
/org/motechproject/mds/enhancer/package-index
/org/motechproject/mds/ex/package-index
org.motechproject.mds.repository
/org/motechproject/mds/web/package-index
Messaging in MOTECH Overview¶
Table of Contents
Introduction¶
Messaging in MOTECH is independent from the scheduling or message campaigns that fire using the event system. It is up to the implementer to connect that (or any other for that matter) logic messaging, either by writing code or creating tasks. This document is a short overview of the messaging options provided by MOTECH: email, SMS and IVR. Each of these has its own module, which can be used by implementers for sending messages through different channels.
The Email Module¶
MOTECH provides an Email module which allows to easily send email messages after connecting to an SMTP server. This module is a part of the platform, so it will be always available. The module is capable of parsing Velocity templates into HTML that will be sent as messages. More information on configuring and using the Email module can be found in the Email module documentation.
The SMS Module¶
SMS messaging can be utilised thanks to the SMS module. This module is optional, so you have to install it in your MOTECH instance if you wish to use it. After connecting to an SMS provider, the module allows both sending and receiving SMS messages. Sending messages is done through HTTP requests to the provider, receiving messages is similarly done by listening for HTTP requests from the provider. MOTECH provides a predefined list of configuration templates for different providers, it also allows you to use your own custom templates. More information on configuring and using the SMS the module can be found in the SMS module documentation.
The IVR module¶
MOTECH also provides a module that allows making and receiving calls by integrating with an IVR provider. This module is optional, so you have to install it in your MOTECH instance if you wish to use it. Similarly to the SMS module, the IVR also relies on making and receiving HTTP calls from the IVR system. The module allows you to upload Velocity templates, that will be processed and served to the provider. These are generally VoiceXML or a similar format, but the module can operate on any format the provider supports. More information on configuring and using the IVR module can be found in the IVR module documentation.
Connecting MOTECH to OpenMRS¶
Table of Contents
Introduction¶
MOTECH allows you to integrate with OpenMRS - an open source enterprise electronic medical record system platform. This is done using the OpenMRS-19 module, that communicates with OpenMRS through its REST API and exposes OSGi services which allow your implementation to easily integrate with OpenMRS. Refer to the module documentation for information on using the API it exposes, this document will describe setting up integration between MOTECH and OpenMRS.
You can easily configure the OpenMRS-19 module to integrate with MOTECH, and then use its API to retrieve or manipulate data in OpenMRS. MOTECH uses the REST API exposed by OpenMRS for integration and it will require HTTP access to OpenMRS and an account with rights to the operations you wish to perform.
Take note that the module was written with OpenMRS 1.9 in mind, and we will use that version for reference in this tutorial.
Getting OpenMRS¶
If you plan on hosting an OpenMRS instance yourself, you can download it from the OpenMRS website. Note that the MOTECH module was created and tested to work with version 1.9. You might encounter problems if choose to use different OpenMRS versions. Use the links below to get OpenMRS:
- OpenMRS website: http://openmrs.org
- OpenMRS 1.9.7 download: http://sourceforge.net/projects/openmrs/files/releases/OpenMRS_1.9.7/
Refer to the OpenMRS documentation for installation instructions: https://wiki.openmrs.org/display/docs/Installing+OpenMRS
Here is the simplest possible route of installing OpenMRS:
- Install Tomcat
- Install MySQL
- In MySQL, create a database called openmrs
- Place the OpenMRS war in the Tomcat webapps directory, making sure its name is openmrs.war
- Start Tomcat
- Go to http://localhost:8080/openmrs
- Follow the installation wizard instructions
Again, refer to OpenMRS documentation for more details.
Configuring the OpenMRS-19 module¶
The MOTECH OpenMRS-19 module exposes a configuration file called openmrs.properties. This file is registered with the configuration system. Based on what configuration mode the system is configured with, you can change the settings either by using the Admin UI(UI Mode) or the file in the config file location(File Mode). You can modify this file through the UI by clicking Admin > Manage Modules > Click the gear icon on the right of the OpenMRS module.

The default username and password match the defaults from OpenMRS(make sure that you change these in production environment).
The table below describes the properties declared in the file and their default values, that will work with a default localhost OpenMRS installation. The openmrs.motechIdName setting needs to match an identifier type from OpenMRS. More information on creating the identifier type in OpenMRS can be found in the next section
Key | Description | Default Value |
---|---|---|
openmrs.url | The top level url at which the OpenMRS Instance is accessible. Required since MOTECH integrates with OpenMRS through REST API calls. Using HTTPS in the openmrs.url requires a valid SSL certificate for connection. Otherwise, Java will return an error. For example, running the Bahmni demo with Vagrant automatically redirects all traffic to https regardless of the security certificate (https://192.168.33.10/openmrs). You can get around this by pointing to port 8080 as is done in the default value (http://192.168.33.10:8080/openmrs). | http://localhost:8080/openmrs |
openmrs.user | The OpenMRS username that MOTECH will use to identify with OpenMRS. | admin |
openmrs.password | The OpenMRS user password that MOTECH will use to identify with OpenMRS. | Admin123 |
openmrs.motechIdName | The name of the OpenMRS identifier used by MOTECH. This must match the identifier that you will create in OpenMRS. The default is MOTECH Id, but it could easily be changed to anything. For example, one could choose caseID if storing CommCare caseIDs in OpenMRS. | MOTECH Id |
openmrs.identifierTypes | By default, we support the one identifier type specified in openmrs.motechIdName property. Define additional identifier types here if you need to create or query an OpenMRS patient with multiple, custom identifiers via MOTECH (comma separated, if more than one). |
Note
The module must be restarted in order for configuration changes to take effect.
Creating a MOTECH Identifier in OpenMRS 1.9¶
In order to make the module work with OpenMRS, an identifier type that MOTECH will use for identifying patients must be created. The name of that identified must match the value of the configuration variable openmrs.motechIdName. In order to define the ID type, go to the Administration section of OpenMRS, then select Manage Identifier Types under the section Patients:
Next, select Add Patient Identifier Type:
Finally, enter the details of the identifier type. The name must match the one in the openmrs.motechIdName setting variable. You can specify the settings as you wish, note that for example making locations required or adding a regex format for the identifier will restrict what values you can use. Refer to the OpenMRS documentation for more information.
Installing Rest Web Services module in OpenMRS¶
MOTECH communicates with the OpenMRS via REST, which means that the OpenMRS instance must have a Rest Web Services module installed and activated. You can find the required module on the OpenMRS modules website. Pick the latest released version (2.9+) and download it. You can install the module using OpenMRS UI. Go to Administration tab, and select Manage Modules.
You will see the Add or Upgrade Module button. Click it, then select the downloaded file under “Add module” and upload it. The module will be installed and started. You can verify its status in the Manage Modules section.
You should now be able to use the OpenMRS-19 module. Refer to the module documentation for usage instructions.
Integrating MOTECH with CommCare¶
Table of Contents
Introduction¶
The Commcare module provides an ability to integrate MOTECH with CommCareHQ. At the moment, the Commcare module allows the following:
- View forms and cases, using MOTECH UI
- Receive notifications when a new form or case is received or when the application schema changes
- Use the exposed OSGi services, to query CommCareHQ for forms, cases, users and fixtures and upload certain data to CommCareHQ, like cases and data forwarding rules
- Import forms, each import form will result in firing an event
- Querying the CommCareHQ stock ledger
- Use the data from CommCareHQ to model more advanced logic, using the Tasks module
Please note, that throughout this document, two similar expressions will be used:
- Commcare - refers to the MOTECH module, that allows the integration with CommCareHQ
- CommCareHQ - refers to an external service, located under www.commcarehq.org
More information about Commcare module you will find in the Commcare module topic.
Configure Commcare module¶
Account settings¶
To allow MOTECH to connect to the CommCareHQ, you should first add a new configuration and provide correct credentials to the CommCareHQ account:
- CommCare Base URL (a link to the CommCareHQ instance; by default www.commcarehq.org)
- CommCare Domain (project name on CommCareHQ)
- Username
- Password
To add configuration you must use Add configuration button . After filling in the data, press the Save button.
To verify the provided data, click the Verify button. The Commcare module will send a test request to the CommCareHQ, attempting to authenticate with the credentials you have provided. If everything works OK, you will be notified about successful connection. If there were any problems connecting to the CommCareHQ, an error will be displayed and you will not be able to work with the Commcare module, until valid credentials are provided.
You can provide more than one account configuration. Only one of the supplied configuration can be the default. The default configuration will be selected whenever you do not specify a particular configuration. To mark the configuration as default you must save the configuration(if it is new) and use Make default button.
Event forwarding¶
This section allows you to configure the events, fired by the Commcare module. Currently, you can pick the Event Strategy for the forwarding of case events. There are three options available:
- minimal (the event will contain only the case ID)
- partial (the event will contain case ID, as well as other, not-case specific parameters (case metadata)
- full (the event will contain case ID, case metadata and all field values of a case)
Once you switch the option, the events fired by the Commcare module will contain only the fields you have chosen to forward.
Note
When you switch to a more strict strategy (forwarding less details), make sure that no listeners rely on the content of these events (eg. Task, triggered by “Received case”)
Connect CommCareHQ¶
To let CommCareHQ know, where the data should be forwarded, you also need to set up data forwarding URLs. This can be achieved in two ways. The first way is to do it via the checkboxes. If you want to set up CommCareHQ to forward the data to the Commcare module, select the checkbox and the Commcare module will automatically set up an URL on your CommCareHQ account.
Note
To use those checkboxes you must set the server URL in the Settings tab in the Admin module.
If for any reason, the first way doesn’t work or sets up invalid URL, the data forwarding rules can also be set in the project settings on your CommCareHQ account. If you have enabled the rules via the slider buttons, you can also verify that the correct rules (with proper URL to your server) have been set up on the CommCareHQ.
To disable the data forwarding rules, you have to open the project settings on your CommCareHQ account and disable them from there. The Commcare module can only set up the rules, but cannot disable them.
As you can see the provided URL http://demo.motechproject.org/module/commcare/forms/
doesn’t have specified configuration.
So if the Commcare module receives data, the default configuration will be used. To work with more than one configuration
you will have to use for example such URL http://demo.motecproject.org/module/commcare/forms/myProjectConf
. The URL
with the configuration name should be automatically added by the Commcare module.
Fired events¶
Subject | Info |
---|---|
org.motechproject.commcare.api.schemachange. | Fired, when the project schema gets changed on the CommCareHQ (module added, form edited, etc.). |
org.motechproject.commcare.api.forms | Fired, when a new form has been received on CommCareHQ or when form has been imported. One event per received/imported form. |
org.motechproject.commcare.api.case | Fired, when a new form has been received on CommCareHQ. One event will be fired per affected case. |
org.motechproject.commcare.api.formstub | Fired, when a new form has been received on CommCareHQ. Contains only IDs of affected form and cases. |
org.motechproject.commcare.api.receivedStockTransaction | Fired, when a stock transaction object was fetched by querying the CommCareHQ stock ledger. |
There are three more events, that are fired, when an internal exception occurs while parsing XML file, received from CommCareHQ. They are:
- org.motechproject.commcare.api.forms.failed (when parsing of a form fails)
- org.motechproject.commcare.api.formstub.failed (when parsing of a form stub fails)
- org.motechproject.commcare.api.exception (when parsing of a case fails)
Integration with the Tasks module¶
The Commcare module will automatically update the Tasks triggers and data sources, each time a schema change event is received. For each form and for each case type, a separate trigger and data source object will be created. This means that you can trigger tasks, when a certain form or case is received and use its fields in an action you select. The fields of forms and cases are based on the schema received from CommCareHQ. The Commcare module also provides an action for querying the CommCareHQ stock ledger for the stock transactions and a trigger for retrieving the stock transactions.
Using the Tasks Module¶
Table of Contents
Introduction¶
The Tasks module, as its name suggests, provides an ability to define and execute tasks. In MOTECH world, task is a piece of work (called action) that has to be performed in response to some event (trigger). In other words, the module provides a tool for defining simple logic that is ready to use without writing a single line of code.
The main features of the Tasks module include:
- Creating, managing and executing tasks
- Monitoring tasks execution
- Registering custom triggers, actions and data providers
Basic concepts¶
Channels¶
A channel contains information about all exposed triggers and actions within a given module. It can be considered as a module specific configuration that tells the Tasks module how it can make a use of it.
The most important elements of the channel are trigger and action definitions. In fact, if channel does not define neither triggers nor actions it is considered invalid. Other properties includes the channel display name, that will be visible on the Tasks UI (it may be a key from message.properties, in which case it will appear as a translated message). Module version and name are obtained at channel registration from the registering bundle. Additionally the channel may contain a short description.
Detailed definition:
Field | Attributes | Description |
---|---|---|
displayName | required | A channel name that will be displayed on the UI (may be an i18n key) |
moduleName | required, derived | A name of the module that registered the channel. By default derived from the bundle information |
moduleVersion | required, derived | A version of the module that registered the channel. By default derived from the bundle information |
description | optional | A brief channel description that will be displayed on the UI (may be an i18n key) |
triggerTaskEvents | optional | An array of triggers definitions |
actionTaskEvents | optional | An array of actions definitions |
Triggers¶
A trigger represents a precise definition of events exposed by module. In tasks, a trigger is something that, as the name suggests, triggers task executions. This means that when an event described by the trigger is published, all tasks with that trigger will get executed. Every trigger has an unique name and, in a simple case, corresponds to exactly one event. Parameters of this event are defined within the trigger. Each parameter contains its name (key) and type.
A good example of a trigger can be an inbound SMS. It would contain the following parameters: message (STRING), sender (STRING), recipients (LIST) etc. Those information will be accessible in the Tasks module.
In the basic case, the most important elements of a trigger are subject and event parameters. The subject corresponds to the event subject that is wrapped by this trigger, while event parameters are the parameters that will be exposed by the trigger. Providing this basic kind of the trigger makes Tasks module listen to the event with the given subject. Each time such an event is published, all active tasks with a corresponding trigger are executed.
However, in some cases the basic behaviour is not sufficient. Sometimes we want the event to correspond to many triggers. In this situation, the trigger listener subject comes in handy. It has to be used along with a custom event parser, which is a little more advanced component, thus it will be described later.
Detailed trigger definition:
Field | Attributes | Description |
---|---|---|
displayName | required | Trigger name that will be displayed on the UI (may be an i18n key) |
subject | required | Trigger subject that will be delivered to the task |
triggerListenerSubject | optional | Real event subject that is wrapped by this trigger. In a simple case it is identical to the subject above, so it can be omitted. |
description | optional | A brief trigger description that will be displayed on the UI (may be an i18n key) |
eventParameters | optional | An array of event parameters described below |
Detailed trigger event parameter definition:
Field | Attributes | Description |
---|---|---|
displayName | required | Event parameter name that will be displayed on the UI (may be an i18n key) |
eventKey | required, unique | Event parameter key. The event parameter value will be obtained from delivered event using this key |
type | optional | Type of the delivered event parameter. Default is UNICODE |
Actions¶
An action represents a definition of function that can be called in a response to a trigger. Every action can represent either a single method of an OSGi service that will be called or an event that will be sent. Each parameter contains it name (key), type and may contain its default value. In case of a method call, the way in which parameters will be passed may vary depending on the needs. They can be either passed directly to the method (matching its signature) or using a key-value pair map.
For instance, an action may correspond to sending an email message. That action would then contain some required fields such as recipients (as a LIST) and the message (STRING) and some optional fields, for example the delivery time (DATE).
As mentioned before, there are two forms in which an action can be represented. The first one is an event. In this case, the action must define a subject of that event. Action execution leads to creating an event with the defined subject and parameters that correspond to the exposed action parameters. The second form that action can take is a service method call. In that case, the action definition must contain the name of the OSGi exposed service interface and the method name to execute. Additionally, one can specify the way in which the method will be called. When it is specified as ‘named parameters’, the action parameters will be evaluated, casted and passed directly to the service method according to its signature and matching its parameter names. In the other case, when it is specified as ‘map’, the parameters are evaluated, packed into a hash map and passed to the method. In this situation the service method is supposed to take exactly one parameter of type java.util.Map<java.lang.String, java.lang.Object>.
An action is considered invalid if it does not define the method nor the event. However, it can define both of them, but the method call has the precedence before event passing. Thus event is send only if the method defining service is not available.
Detailed action definition:
Field | Attributes | Description |
---|---|---|
name | optional, unique | Action name |
displayName | required | Action name that will be displayed on the UI (may be an i18n key) |
description | optional | A brief action description that will be displayed on the UI (may be an i18n key) |
subject | optional event-required | A subject of the event that is to be sent |
serviceInterface | optional, method-required | A service containing a method that is to be called |
serviceMethod | optional method-required | A service method that is to be called |
serviceMethodCallManner | optional method-optional | A service method call manner. It can take one of two values: NAMED_PARAMETERS (default) - action parameters are passed to the function directly, matching its signature; MAP - action parameters are passed to the method as a map in which keys correspond to parameter names and values correspond to parameter values |
actionParameters | optional | An array of action parameter definitions described below |
Detailed action parameter definition:
Field | Attributes | Description |
---|---|---|
displayName | required | Action parameter name that will be displayed on the UI (may be an i18n key) |
key | required, unique | Action parameter key. Depending on action method call manner it will correspond either to a method parameter name or a map key |
value | optional | Action parameter default value. Depending on action method call manner it will correspond either to a method parameter value or a map value |
type | optional | Type of the action parameter value. Default is UNICODE |
required | optional | Indicates if this action parameter is mandatory. May be true or false. Default is false |
hidden | optional | Indicates if this action parameter should not be visible on the UI. May be true or false. Default is false |
order | optional | Specifies position at which this action parameter should appear among other parameters |
Parameters types¶
Available types that can be used with action parameters and trigger event parameters in the Tasks module are listed below.
Type Name | Java Type | Description |
---|---|---|
UNICODE | java.lang.String | Short Unicode string |
TEXTAREA | java.lang.String | Long Unicode string |
INTEGER | java.lang.Integer | Signed number without a fraction component |
LONG | java.lang.Long | Large signed number without a fraction component |
DOUBLE | java.lang.Double | Double precision floating point number |
DATE | org.joda.time.DateTime | Calendar date with time |
TIME | org.joda.time.DateTime | Calendar time without date |
PERIOD | org.joda.time.Period | Period of time |
BOOLEAN | java.lang.Boolean | True or false |
LIST | java.util.List | Collection of values |
MAP | java.util.Map | Collection of key-value pairs |
Data providers¶
A data provider can be considered as a source of various data that can be used in a task. It defines the structure of objects it supports as well as structure of the queries that it can perform. Each data provider is recognized by its name.
An example data provider is the one defined by the CMSLite module. It provides two types of objects: StreamContent and StringContent. For instance, StringContent objects contains several fields that can be used in the Tasks module. Those are value, language, name and metadata. It also contains two lookups. One of them is used to find a desired instance by id, the other one uses name and language fields.
Every data provider must implement the DataProvider interface. It contains a few methods responsible for retrieving the data provider name, performing a search, discriminating if a provided type is supported by this provider and finally, returning the provider JSON definition. The definition is in fact a TaskDataProvider object, thus it must follow its schema.
Detailed task data provider definition:
Field | Attributes | Description |
---|---|---|
name | required, unique | An unique data provider name |
objects | required | An array of task data provider objects |
Detailed task data provider object definition:
Field | Attributes | Description |
---|---|---|
displayName | required | Task data provider object name that will be displayed on the UI (may be an i18n key) |
type | required, unique | The symbolic type name of the object backed by this task data provider object. As it will be used to distinguish this object from other objects within this data provider, it has to be unique |
lookupFields | required | An array of lookup field parameters definitions used to in the lookup |
fields | required | An array of fields parameters definitions available from this task data provider object |
Detailed lookup field parameter definition:
Field | Attributes | Description |
---|---|---|
displayName | required | Lookup field parameter name that will be displayed on the UI (may be an i18n key) |
fields | required | An array of field names required by this lookup |
Detailed field parameter definition:
Field | Attributes | Description |
---|---|---|
displayName | required | Field parameter name that will be displayed on the UI (may be an i18n key) |
fieldKey | required | A key used to identify this parameter |
type | optional | Type of the field parameter value. Default is UNICODE |
Channel registration¶
To expose a module actions or triggers in Tasks module, a channel containing their definitions has to be registered in the Tasks module. It can be done in one of three different ways: using a static channel definition file, task annotations or programmatically, utilizing the ChannelService.
Using the channel file¶
It is the most common way to register a task channel. It comes down to creating a json channel definition file named task-channel.json and placing it right in the classpath root of your bundle. It will be automatically discovered by the Tasks module at your bundle start or update.
The file content, written in JSON format, has to follow a well defined structure. The root element must be a channel object that matches a specification defined above.
Example channel file:
{
"displayName": "sms",
"triggerTaskEvents": [
{
"displayName": "sms.inbound_sms",
"subject": "inbound_sms",
"serviceInterface": "org.project.service.SmsService",
"serviceMethod": "sendSms",
"eventParameters": [
{
"displayName": "sms.message",
"eventKey": "message"
},
{
"displayName": "sms.sender",
"eventKey": "sender"
},
{
"displayName": "sms.recipient",
"eventKey": "recipient"
},
{
"displayName": "sms.datetime",
"eventKey": "datetime",
"type": "DATE"
}
]
}
],
"actionTaskEvents": [
{
"displayName" : "sms.send_sms",
"subject" : "send_sms",
"actionParameters" : [
{
"displayName" : "sms.message",
"key" : "message"
},
{
"displayName" : "sms.recipients",
"key" : "recipients",
"type" : "LIST"
},
{
"displayName" : "sms.delivery_time",
"key" : "delivery_time",
"type" : "DATE",
"required": false
}
]
}
]
}
Note
The order of the elements in the action parameters array determines their order on the Tasks UI, unless an order parameter is specified.
Using annotations¶
This method allows to register a channel using the Tasks annotation processing mechanism and annotations from org.motechproject.tasks.annotations package. However, this approach is limited to registering actions only. In this scenario, channels correspond to classes and actions to their methods. To make a class recognized as a channel by the Tasks module, it has to be annotated with @TaskChannel. Channel display name can be provided as an annotation parameter. Additionally, module name and version have to be provided as annotation parameters.
Each channel class should have at least one method marked as @TaskAction. For this annotation as well, one can specify the action display name. Each parameter of the action method is considered as an action parameter with default properties: the parameter are marked as required, its type is set to UNICODE and its display name and key corresponds to the action method parameter name. Those default properties can be modified utilising the @TaskActionParam annotation.
Example channel class:
@Service
@TaskChannel(channelName = "sms", moduleName = "sms", moduleVersion = "1.0")
public class SmsServiceImpl implements SmsService {
@TaskAction
public void sendSms(
@TaskActionParam(displayName = "sms.message", key = "message") String message,
@TaskActionParam(displayName = "sms.recipients", key = "recipients", type = ParameterType.LIST) List recipients,
@TaskActionParam(displayName = "sms.delivery_time", key = "delivery_time", type = ParameterType.DATE) DateTime deliveryTime
) {
...
}
}
Using the ChannelService¶
The most elastic way to register a channel is to use the ChannelService. It allows to register both triggers and actions in a dynamic manner. The first step of typical usage of the ChannelService is to build a ChannelRequest object. The ChannelRequest is the Java representation of a channel, that follows already defined channel specification. Accordingly, TriggerEventRequest and EventParameterRequest corresponds to trigger and trigger event parameters and ActionEventRequest and ActionParameterRequest corresponds to action and action parameters. Note that in this scenario module name and module version must be provided manually as proper fields of the request. Once the ChannelRequest is ready, it can be passed to the ChannelService method called registerChannel. It will validate the request and register the tasks channel.
Example channel registration using the ChannelService:
@Component
public class SmsChannelRegistration {
@Autowired
private ChannelService channelService;
...
private void registerSmsChannel() {
EventParameterRequest inboundSmsMessage = new EventParameterRequest(
"message", // event key
"sms.message" // display name
);
EventParameterRequest inboundSmsSender = new EventParameterRequest(
"sender", // event key
"sms.sender" // display name
);
EventParameterRequest inboundSmsRecipient = new EventParameterRequest(
"recipient", // event key
"sms.recipient" // display name
);
EventParameterRequest inboundSmsDatetime = new EventParameterRequest(
"datetime", // event key
"sms.datetime", // display name
"DATE" // type
);
TriggerEventRequest inboundSmsTrigger = new TriggerEventRequest(
"sms.inbound_sms", // display name
"inbound_sms", // subject
null, // description
Arrays.asList(inboundSmsMessage, inboundSmsSender, inboundSmsRecipient, inboundSmsDatetime) // event parameters
);
ActionParameterRequest sendSmsMessage = new ActionParameterRequest(
"message", // key
null, // default value
"sms.message", // display name
0, // order
null, // type (default: UNICODE)
true, // required
false // hidden
);
ActionParameterRequest sendSms = new ActionParameterRequest(
"recipients", // key
null, // default value
"sms.recipients", // display name
1, // order
"LIST", // type (default: UNICODE)
true, // required
false // hidden
);
ActionParameterRequest sendSms = new ActionParameterRequest(
"delivery_time", // key
null, // default value
"sms.delivery_time", // display name
2, // order
"DATE", // type (default: UNICODE)
false, // required
false // hidden
);
ActionEventRequest sendSmsAction = new ActionEventRequest(
null, // name
"sms.send_sms", // display name
"send_sms", // subject
null, // description
"org.project.service.SmsService", // service interface
"sendSms", // service method
null, // service method call manner (default: NAMED_PARAMETERS)
Arrays.asList(sendSmsMessage, sendSmsRecipients, sendSmsDeliveryTime) // action parameters
);
ChannelRequest smsChannel = new ChannelRequest(
"sms", // display name
"sms", // module name
"1.0", // module version
null, // description
Arrays.asList(inboundSmsTrigger), // trigger requests
Arrays.asList(sendSmsAction) // action requests
);
channelService.registerChannel(smsChannel);
}
}
Data provider registration¶
To register a custom data provider, two things have to be done. As it was said before, every data provider has to implement the DataProvider interface. For your convenience we provide an abstract base class that implements the DataProvider interface and removes the requirement to write needles boilerplate. That class is called AbstractDataProvider and is extend by most of our data providers. Usually, this class is used along with a JSON data provider definition stored somewhere in the classpath. The only thing to do then is to provide the string or resource containing the JSON. Once the data provider is ready to use, it is time to actually register it in the Tasks module, which comes down to publishing it as an OSGi service.
Example data provider:
@Service
public class ExternalPatientDataProvider extents AbstractDataProvider {
@Autowired
public ExternalPatientDataProvider(ResourceLoader resourceLoader) {
setBody(resourceLoader.getResource("task-data-provider.json"));
}
@Override
public String getName() {
return "external-patient";
}
@Override
public Object lookup(String type, String lookupName, Map<String, String> lookupFields) {
if (supports(type) && lookupFields.containsKey("id")) {
String id = lookupFields.get("id");
return getExternalPatient(id);
} else {
return null;
}
}
@Override
public List<Class<?>> getSupportClasses() {
return Arrays.asList(ExternalPatient.class);
}
@Override
public String getPackageRoot() {
return "org.project.domain";
}
private ExternalPatient getExternalPatient(String id) {
...
}
}
{
"name": "external-patient",
"objects": [
{
"displayName": ext.external_patient,
"type": "ExternalPatient",
"lookupFields": [
{
"displayName": "ext.lookup.id",
"fields": [
"id"
]
}
],
"fields": [
{
"displayName": "ext.field.firstName",
"fieldKey": "firstName"
},
{
"displayName": "ext.field.secondName",
"fieldKey": "secondName"
}
]
}
]
}
Custom event parser¶
As it was mentioned earlier, there also exists a more advanced way to handle a trigger, by using a custom event parser. It allows to change the real event subject and parameters to a form in which they will be represented in the task trigger. In other words, it converts an event model to a tasks model.
An example of custom event parser usage can be found in the Commcare module. Once the form-received event occurs, the parser transforms the event payload containing a generic representation of the form xml to a trigger definition based on the schema of the concrete form, giving end-users intuitive access to the fields of that form.
To use a custom event parser, one has to implement TasksEventParser interface and expose it as an OSGi service. To make a use of the custom parser, the incoming event should contain a parameter with ‘org.motechproject.tasks.custom_event_parser’ as a key and the parser name returned by the getName() method as a value.
Example event parser:
@Service
public class FormsEventParser implements TasksEventParser {
@Override
public Map<String, Object> parseEventParameters(String subject, Map<String, Object> parameters) {
Map<String, Object> parsedParameters = new HashMap<>();
Map<String, Object> dataParameters = (Map<String, Object>) parameters.get("data");
for (Map.Entry<String, Object> entry : dataParameters.entries()) {
parsedParameters.put("data/".concat(entry.getKey()), entry.getValue());
}
return parsedParameters;
}
@Override
public String parseEventSubject(String subject, Map<String, Object> parameters) {
String formName = (String) parameters.get("name");
return subject.concat(".").concat(formName);
}
@Override
public String getName() {
return "org.project.forms-event-parser";
}
}
Tasks UI¶
An important part of the Tasks module is the Tasks UI. It is used to create, edit, manage and monitor tasks.
Overview¶
The main Tasks view contains a few elements. Firstly, the action buttons are on the top. They allow creating tasks, importing previously exported tasks and toggling the visibility of the filter view on the right.
The main view lists all currently existing tasks in the form of expandable boxes, that provide actions related to the tasks they represent. The list can be filtered using filters tab mentioned before. One can search the tasks by their name or description as well as be their state (active/paused).
The right panel, besides filters, contains also a recent task activity tab. It provides an instant overview of latest task executions and their results.
Creating a task¶
New task creation process begins with clicking the ‘New task’ button on the main view. The task creation view shows up.
Starting from the top, one can see three properties to provide: task name, task description and option which allow to set task retry in case of failure, from which the task name is mandatory. If the “Retry task on failure” option is checked, one should set the count of retries and the interval in seconds between each retry call. For each retry all the task’s actions are repeated, not only those that have failed.
Note
In the Tasks UI, if a property has invalid value it is signalled by highlighting its label and input field. There must not be any property with invalid value in order to save the task.
The trigger selection widget comes next. In this example there are four channels registered that expose at least one trigger. Once the channel icon is clicked, a popup shows up. It lists all triggers exposed by that channel.
Picking a trigger makes new actions available. One can add a data source, a filter set and finally select an action to execute.
After clicking the ‘Add data source’ button, the data source widget shows up. The first step is to select an actual source. The dropdown lists all registered data sources. After picking one, a data source object must be selected. Now, one has to choose a lookup that will be used to retrieve an object and provide its arguments. In this example the ‘find by id’ lookup is used, thus the only lookup parameter is ID. The argument value may be either entered by hand (hardcoded) or composed from available fields listed on the top of the widget. Additionally, it is possible to set that task execution will fail if the lookup will not find the desired object.
Note
Available fields that may be noticed on the top of the data source and action widgets can be used to compose an argument values for the parameters. To include those fields they may be dragged and dropped into the desired input or written as a token in a text form. The syntax in case of trigger fields (the blue bubbles) is {{trigger.[field_name]}} where field_name is the key of the trigger parameter. In case of data source fields (the orange bubbles) the syntax is {{ad.[data_source_name].[object_name]#[object_index].[field_name]}} where provider_name and object_name corresponds to the selected data source and object respectively, object_index is the index of the object (in a situation when the same object was selected several times in the same task) and field_name corresponds to the object property.
Another available option is to add a filter set. The filter allows to setup a set of conditions that must evaluate to true in order for the task to execute. One can choose if all conditions should be satisfied or just one of them. If the entire condition set is not fulfilled, the task execution is canceled.
Each filter corresponds to a single field, either from trigger or data source. After selecting a field, there is a possibility to manipulate its value using Tasks manipulations by clicking on the gear icon next to it. Then it has to be set if the filter should be satisfied on a condition result or its negation. Finally, the condition can be selected. All conditions are grouped in three categories including Date, Number and String. Each of those contains basic checks that can be performed on the types they represents.
The filter is executed after all previous steps (data source lookups, filters) before were executed. In order for a filter to perform a check on a given data provider object, it has to be placed after that data source step. This can be used to abort the task execution before doing costly data lookups.
At last, with the ‘Add action’ button there comes a possibility to add an action to a task. There can be multiple actions in a single task, but unlike filters and data sources, the task is obligated to contain at least one action to be valid.
Note
If a task contains multiple actions and if some action execution fails, the remaining actions will not be executed.
All channels that expose at least one action are listed in the channel dropdown. When one of them is selected, the action dropdown contains all actions available. After selecting both channel and action, a list of action parameters is presented. In order to be valid, the action must not contain any parameter with an invalid value. Like in the case of data source lookups, the parameters may be filled with hardcoded values or combined field available either from the trigger or a data source. In case of fields, its values can be modified using Tasks manipulations. Sometimes, when a property has a complex type, a question mark can be visible next to its label. When hovered over, a popup with a short tooltip is shown.
There are also two buttons at the bottom on the action widget. Once clicked, they provide a handy user manual related with fields syntax and string/date manipulations.
Note
Data sources, filter sets and actions can be removed from task by clicking an ‘X’ button at the top-right corner of the corresponding widget.
Once the task is defined, the last thing to do is to save it. There are two buttons on the bottom that allow to achieve this goal. One of them simply saves the task. This action is possible even if the task is not fully valid. The second option is to save and enable the task at once. In this case, the task must be valid. After clicking any of the buttons, the saved task can be seen in the main view.
Manipulations¶
In various situations related with task creation, there is a possibility to apply so called manipulations to fields originating from trigger or data sources. Manipulation allow to modify the incoming field values and transform them to something else. The most basic example might be changing all letters of a string value to uppercase.
Depending on the field type, distinct manipulations may be enabled. There are currently two categories of supported types: String and Date. An extensive description of them is available at the Tasks UI through a proper help button.
There might be multiple manipulations assigned to a single field. Moreover, they can be ordered in the widget by simply dragging and dropping them.
There is also possibility to define manipulations ‘by hand’ using plain text. The syntax in this case is {{[field]?[manipulation]}}, for example {{trigger.externalId?substring(0,8)?toUpper}}.
Note
Note that the modified value will not be written back to its source. For example, if the firstName field from the Motech Data Services Patient object will be edited with the uppercase manipulation, its value will not be changed in the database.
Managing and monitoring tasks¶
Once the task is created, it is shown in the main Tasks view in a widget form. In a basic form it contains information about modules related with the task, the task name, an icon indicating if the task is active or not and an icon that leads to a task editing view. Once the task name is clicked, the widget expands to expose all available actions related that task.
The first action allows to edit the task. The editin process is very similar to task creation. The editor view shows up and presents the task in a form in which it was saved. In a situation when a task is invalid, all validation errors are visible at the top of the view.
Second button toggles the task state between paused and active. Active task will be executed when their corresponding trigger will occur, while paused task will not. The task may be paused in order to temporarily disable the task execution.
The delete button allows to permanently delete tasks. Once deleted, a task cannot be restored.
There is also a button that leads to the task history view. It allows to monitor all events related to the task and especially track an execution of the task. It provides information about currently performing tasks (how many actions are and how many are completed), the task result status and the message, which in case of failure contains stacktrace and failure reason. You can also clean the tasks history. Task execution is marked as success when all actions finish without an error.
The last available option is to export the task. Selecting this action will trigger a file download. The file is a json representation of the task, that can be imported using ‘Import task’ action in the main view.
Settings¶
The only setting actually available is the limit of invalid executions for a single tasks. If the task will fails more times than it is allowed to by this parameter, it will be automatically paused until its manual activation. Once this happens, a message is added to the task events history. If the value of this parameter is set to 0, the task will be paused after only one failure.
It is worth mentioning that this parameter may be also set using file based config. The property name of the parameter is ‘task.possible.errors’.
Configuring Pill Reminders¶
There will be more text here.
Configuring Your MOTECH App to be HIPAA Compliant¶
Table of Contents
What is HIPAA?¶
From http://www.hhs.gov/ocr/privacy/hipaa/understanding/srsummary.html:
The Health Insurance Portability and Accountability Act of 1996 (HIPAA) required the Secretary of the U.S. Department of Health and Human Services (HHS) to develop regulations protecting the privacy and security of certain health information. To fulfill this requirement, HHS published what are commonly known as the HIPAA Privacy Rule and the HIPAA Security Rule. The Privacy Rule, or Standards for Privacy of Individually Identifiable Health Information, establishes national standards for the protection of certain health information. The Security Standards for the Protection of Electronic Protected Health Information (the Security Rule) establish a national set of security standards for protecting certain health information that is held or transferred in electronic form. The Security Rule operationalizes the protections contained in the Privacy Rule by addressing the technical and non-technical safeguards that organizations called “covered entities” must put in place to secure individuals’ “electronic protected health information” (e-PHI). Within HHS, the Office for Civil Rights (OCR) has responsibility for enforcing the Privacy and Security Rules with voluntary compliance activities and civil money penalties.
A unofficial version that presents all regulatory standards in one document (as of March 2013) is available on the website of the U.S. Department of Health & Human services:
http://www.hhs.gov/ocr/privacy/hipaa/administrative/combined/hipaa-simplification-201303.pdf
Scope of this document¶
Compliance with HIPAA requires implementing physical and technical safeguards, as well as technical and administrative policies when it comes to dealing with sensitive patient data. It is impossible for us to help you achieve full compliance, without knowing the details of your organization or the data you are storing. Ultimately it falls on your and/or your hosts shoulders to guarantee full HIPAA compliance.
This document focuses on the MOTECH part of the patient - what can be configured and what should be configured in MOTECH in order to be HIPAA compliant. Take note that this is only a part of the full picture and it is up to you to make sure you are fully compliant. More information on HIPAA and being compliant can be found on the website of the U.S. Department of Health & Human Services: http://www.hhs.gov/ocr/privacy/hipaa/understanding/srsummary.html
The Security Rule¶
The HIPAA Security Rule establishes national standards to protect individuals electronic personal health information that is created, received, used, or maintained by a covered entity. The Security Rule requires appropriate administrative, physical and technical safeguards to ensure the confidentiality, integrity, and security of electronic protected health information.
This section of the document will focus on the technical safeguards that should be configured in MOTECH in order to achieve HIPAA compliance.
Technical safeguards¶
Technical safeguards required for HIPAA are divided into standards. Every entity covered by HIPAA must comply with every standard. However, the HIPAA Security Rule categorizes certain implementation specifications as “addressable”, while others are “required”. Covered entities are required to comply with every Security Rule “Standard.” However, the Security Rule categorizes certain implementation specifications within those standards as “addressable,” while others are “required.” The “required” implementation specifications must be implemented. The “addressable” designation does not mean that an implementation specification is optional. However, it permits covered entities to determine whether the addressable implementation specification is reasonable and appropriate for that covered entity. If it is not, the Security Rule allows the covered entity to adopt an alternative measure that achieves the purpose of the standard, if the alternative measure is reasonable and appropriate.
Following are the HIPAA standards that must be adhered to in order to be HIPAA compliant.
Standard: Access control¶
To be in accordance with standard, only authorized persons or software programs should have access to e-PHI. MOTECH includes a web-security module, which covers this standard. Following are the implementation specifications for this standard:
Unique user identification (Required)¶
User identity must be tracked by assigning them unique names or numbers.
MOTECH implements a user based access system based on Spring Security. All users have unique user names. This is provided by default and nothing has to be changed in order for it to function. You can create multiple user accounts and associate them with different access roles. What you have to do however, is to make sure that all the users accessing the system have their own unique accounts with correct access permissions - remember that only authorized persons can have access to e-PHI.
Since MOTECH also provides a configurable security rule system, you must make sure that no parts of the system allowing any kind of access to ePHI can be accessed without authentication and authorization.
If you are implementing your own modules, you must make sure to secure all HTTP endpoints that require specific permissions using Spring Security measures, preferably annotations but other ways of doing it are also acceptable. If you add a new endpoint without adding any security safeguards, then by default it still will be restricted to only authenticated users (all authenticated users, which very often is not what you should do).
Refer to the Security Model documentation for more information.
You should also make sure to secure your MDS entities using appropriate annotations so that only authorized users can access them through the MDS Data Browser. Refer to the Security section of the MDS documentation for information on securing your entities.
Emergency access procedure (Required)¶
Establish (and implement as needed) procedures for obtaining necessary electronic protected health information during an emergency.
This is something you should define on your based on you infrastructure and/or hosting solution. All data stored by MOTECH goes to the database, so if you are using MDS for storing you e-PHI, you should develop a plan for emergency access to the database.
Automatic logoff (Addressable)¶
Implement electronic procedures that terminate an electronic session after a predetermined time of inactivity.
MOTECH has a setting that allows controlling this. By default the session timeout after inactivity is set to 30 minutes, but can configured (or turned off if set to 0) in the MOTECH settings. Set the timeout to an appropriate value for your situation.
Refer to the Security Model documentation for more information on this setting.
Encryption and decryption (Addressable)¶
Implement a mechanism to encrypt and decrypt electronic protected health information.
MOTECH does not provide any out of the box solution for this. It is up to you to either configure encryption and you have a few options for achieving this. The first one is to do this manually in your code - you would have to manually encrypt and decrypt all sensitive data going in and out of the database.
You can also use encryption on the database level, by either using database features or by placing the database data directory on an encrypted disk. Refer to this documentation for PostgreSQL. For MySQL you can use full disk encryption or third party products, more information can be found in this Article.
Standard: Audit controls¶
Implement hardware, software, and/or procedural mechanisms that record and examine activity in information systems that contain or use electronic protected health information.
If you are using MOTECH Data Services for persistence, then you are given a history recording feature for your data out of box. It is not enabled for new entities by default, so you will have to turn it on, either through UI or the @Entity annotation. The history feature will track all changes to an entity and record them in a separate table in the database. This history can be viewed through the MDS UI.
MDS also stores the last modification date and the modification author in the entity table itself - this is always turned on and gives you a view on who made changes to the given object.
The last login date for each user is recorded and stored in the database.
Moreover MOTECH implements a comprehensive logging system based on SLF4J that allows you to track the functioning of the system. The suggest logging level for operations is INFO, but you can tweak the logging levels of different components as you see fit, even during runtime.
A status message API for posting status messages that get persisted in the database is also exposed by the admin module and can be leveraged.
When you develop your own application, you should make sure you have enough logging statements to trace activity in the application.
Standard: Integrity¶
Implement policies and procedures to protect electronic protected health information from improper alteration or destruction.
Mechanism to authenticate electronic protected health information (Addressable)¶
Implement electronic mechanisms to corroborate that electronic protected health information has not been altered or destroyed in an unauthorized manner.
This ultimately falls on your shoulders, since you know your data. Take note that MDS allows easy usage of javax.validations - you can set them up across your entities to validate the data being persisted automatically. If a validation fails, the object will not be persisted and you will be notified about that in the logs. If you need more advanced validation measures, then it is up to you to implement them.
Standard: Person or entity authentication¶
Implement procedures to verify that a person or entity seeking access to electronic protected health information is the one claimed.
This is covered by MOTECH user based access system. Users identify with a password and are given roles composed of permissions. These permissions can be used to restrict to which parts of the system he has access to.
Refer to the Security Model documentation for more information.
Standard: Transmission security¶
Implement technical security measures to guard against unauthorized access to electronic protected health information that is being transmitted over an electronic communications network.
Integrity controls (Addressable)¶
Implement security measures to ensure that electronically transmitted electronic protected health information is not improperly modified without detection until disposed of.
This means using encryption for all e-PHI data being sent over the wire. This includes, but is not limited to HTTP communication, database communication (if it’s over a network), emails and so forth. Since MOTECH runs on Tomcat, it can be configured to use communication level cryptographic protocols such as TLS or SSL. This is described in the Apache Tomcat SSL/TLS Configuration HOW-TO.
MOTECH can be also configured to connect to the database using SSL.
This is important to note when communicating with outside services such as the IVR provider, SMS provider, the SMTP server for sending emails, outside systems such as OpenMRS or Commcare and so on. When using these services that are not the same host as the MOTECH server, make sure that use HTTPS instead of plain HTTP or in other cases, such as the email server, make sure that proper cryptographic configuration is being used - this is not configured out of the box.
Encryption (Addressable)¶
Implement a mechanism to encrypt electronic protected health information whenever deemed appropriate.
As mentioned, MOTECH does not provide out of the box encryption utils. You can implement your own encryption methods using JAVA cryptography or any other tool.
The Privacy Rule¶
The HIPAA Privacy Rule establishes national standards to protect individuals’ medical records and other personal health information and applies to health plans, health care clearinghouses, and those health care providers that conduct certain health care transactions electronically. The Rule requires appropriate safeguards to protect the privacy of personal health information, and sets limits and conditions on the uses and disclosures that may be made of such information without patient authorization. The Rule also gives patients rights over their health information, including rights to examine and obtain a copy of their health records, and to request corrections.
It is up to you as an implementer and an entity covered by HIPAA to adhere to the privacy rule. You have to take care to always send the required minimum of data at all times. Moreover the rule covers rules around disclosing PHI, sharing it with your business partners and so on.
You can find more information looking at the Guidance on Significant Aspects of the Privacy Rule and the Guidance in de-identification of PHI in accordance with HIPAA:.
Embedded MDS grids¶
Table of Contents
Introduction¶
Embedded MDS grids are grids that originate from the MDS module, but are used by other modules in their own UI. MDS allows it by providing easy and highly-customizable functionality that will not only let you embed the grid but also give you the possibility of overriding the default behavior of that grid.
Preparation¶
Before you can use the embedded MDS grid you to add the support for this functionality to your module. There are only few steps that you need to take in order to achieve this. Below I’ll illustrate the whole process along with some examples. I will expand the example javascript file and explain everything as we go.
The example javascript:
(function () {
'use strict';
var modulename = angular.module('moduleName');
}());
The first thing you will have to do is to include MDS module as a dependency in you modules app.js
. Here’s a
code snippet:
(function () {
'use strict';
var modulename = angular.module('moduleName', ['mds']);
}());
This is required for proper loading of the angular controllers that will be used by the embedded grid.
You are also going to need the ID of the entity you want to embed the grid for. Keep in mind you can load multiple grids for multiple entities. All you need to is to add the following code snippet to your javascript file.
var entityId;
$.ajax({
url: '../mds/entities/getEntity/Module Name/{entityName}',
success: function(data) {
entityId = data.id;
},
async: false
});
This will send a request to the MOTECH server and retrieve the ID of the entity with the given name. This ID will be needed later to build the URL pointing to the MDS grid for that entity.
Your javascript should look similar to this.
(function () {
'use strict';
var modulename = angular.module('moduleName', ['mds']), entityOneId, entityTwoId;
$.ajax({
url: '../mds/entities/getEntity/Module Name/{entityOneName}',
success: function(data) {
entityOneId = data.id;
},
async: false
});
$.ajax({
url: '../mds/entities/getEntity/Module Name/{entityTwoName}',
success: function(data) {
entityTwoId = data.id;
},
async: false
});
}());
Now that you have the IDs, you can add some redirects that will load the embedded MDS grid to the AngularJS view(more information about this will be provided later on). Here’s the code snippet you need to include.
modulename.config(function ($routeProvider) {
$routeProvider.when('/{moduleName}/EntityOne', {redirectTo: 'mds/dataBrowser/' + entityOneId});
$routeProvider.when('/{moduleName}/EntityTwo', {redirectTo: 'mds/dataBrowser/' + entityTwoId});
});
Adding this will result in embedding MDS grid in the AngularJS view whenever the '/{moduleName}/EntityOne
and
/{moduleName}/EntityTwo
URLs are called.
Your javascript file should look something like this now.
(function () {
'use strict';
var modulename = angular.module('moduleName', ['mds']), entityOneId, entityTwoId;
$.ajax({
url: '../mds/entities/getEntity/Module Name/{entityOneName}',
success: function(data) {
entityOneId = data.id;
},
async: false
});
$.ajax({
url: '../mds/entities/getEntity/Module Name/{entityTwoName}',
success: function(data) {
entityTwoId = data.id;
},
async: false
});
modulename.config(function ($routeProvider) {
$routeProvider.when('/{moduleName}/EntityOne', {redirectTo: 'mds/dataBrowser/' + entityOneId});
$routeProvider.when('/{moduleName}/EntityTwo', {redirectTo: 'mds/dataBrowser/' + entityTwoId});
});
}());
This was the last step of preparing the module for embedded MDS grids support. For information about how to display it, please proceed to the next section.
Displaying the grid¶
Now that you’re done with preparing the module you need to display the grid with our HTML. There are two ways of doing
this and both of them will be explained in the following subsections. I will use the following index.html
file
as a base for all the examples.
<!--Module main div-->
<div id="inner-center" class="inner-center ui-layout-center ui-layout-pane ui-layout-pane-center">
<!--div responsible for tabs handling-->
</div>
Displaying the grid using directives¶
To include the grid we need to add two divs with directives, one for the grid itself and the second for the filters tab that will allow you to filter the grid.
<!--Module main div-->
<div id="inner-center" class="inner-center ui-layout-center ui-layout-pane ui-layout-pane-center">
<!--div responsible for tabs handling-->
<!--This div is responsible for embedding the grid-->
<div tab-layout-with-mds-grid></div>
</div>
<!--This div is responsible for embedding the filters panel-->
<div embedded-mds-filters></div>
With those divs added the default implementation of the embedded grid will be loaded. For more information about customizing it, please visit the Customizing embedded MDS grids section.
Displaying the grid through extending modules main controller¶
The more advanced way of displaying the grid(and also the one that allows more customization) is extending your module
main controller with MdsEmbeddableCtrl
provided by the MDS module. To achieve this you need to include the
following code snippet into your modules main controller.
angular.extend(this, $controller('MdsEmbeddableCtrl', {
$scope: $scope,
MDSUtils: MDSUtils
}));
With this code snippet your controller should look something like this.
controllers.controller('ModuleBasicCtrl', function ($scope, $location, $route, $controller, MDSUtils) {
angular.extend(this, $controller('MdsEmbeddableCtrl', {
$scope: $scope,
MDSUtils: MDSUtils
}));
});
And the index.html
file should look something like this.
<!--Module main div-->
<div ng-controller='ModuleBasicCtrl' id="inner-center" class="inner-center ui-layout-center ui-layout-pane ui-layout-pane-center">
<!--div responsible for tabs handling-->
</div>
Now you need to include divs responsible for displaying the grid itself.
<div class="ui-layout-content">
<div class="tab-content" id="tab-content">
<div id="main-content" class="active">
<div ng-view></div>
</div>
</div>
</div>
This contains the AngularJS that will display the embedded MDS grid.
Here’s the whole .html
file so far.
<!--Module main div-->
<div ng-controller='ModuleBasicCtrl' id="inner-center" class="inner-center ui-layout-center ui-layout-pane ui-layout-pane-center">
<!--div responsible for tabs handling-->
<div class="ui-layout-content">
<div class="tab-content" id="tab-content">
<div id="main-content" class="active">
<div ng-view></div>
</div>
</div>
</div>
</div>
Some of the entities allows filtering by several fields and values. To use this functionality you need to add the
following divs to your .html
file.
<div id="inner-east" class="mds inner-east ui-layout-pane ui-layout-pane-east">
<div class="header-toolbar header-footer"></div>
<div class="filter-header">{{msg('mds.filters')}}</div>
<div class="ui-layout-content" ng-controller="MdsFilterCtrl">
<div class="inside">
<fieldset class="inside" ng-repeat="filter in filters">
<legend>{{filter.displayName}}</legend>
<div class="form-group btn-group-vertical">
<button clickfilter singleSelect='{{(filter.type === "java.util.Date" || filter.type === "org.joda.time.DateTime" || filter.type === "org.joda.time.LocalDate")}}' ng-repeat="filterType in filter.types" class="btn btn-info btn-sm"
type="button" ng-click="selectFilter(filter.field, filterType, filter.type)"><i class="fa fa-fw fa-square-o"></i> {{msgForFilter(filterType)}}</button>
</div>
</fieldset>
</div>
</div>
</div>
This will load the right filter panel along with it’s controller.
The whole .html
file should look similar to the one belowe.
<!--Module main div-->
<div ng-controller='ModuleBasicCtrl' id="inner-center" class="inner-center ui-layout-center ui-layout-pane ui-layout-pane-center">
<!--div responsible for tabs handling-->
<div class="ui-layout-content">
<div class="tab-content" id="tab-content">
<div id="main-content" class="active">
<div ng-view></div>
</div>
</div>
</div>
<div id="inner-east" class="mds inner-east ui-layout-pane ui-layout-pane-east">
<div class="header-toolbar header-footer"></div>
<div class="filter-header">{{msg('mds.filters')}}</div>
<div class="ui-layout-content" ng-controller="MdsFilterCtrl">
<div class="inside">
<fieldset class="inside" ng-repeat="filter in filters">
<legend>{{filter.displayName}}</legend>
<div class="form-group btn-group-vertical">
<button clickfilter singleSelect='{{(filter.type === "java.util.Date" || filter.type === "org.joda.time.DateTime" || filter.type === "org.joda.time.LocalDate")}}' ng-repeat="filterType in filter.types" class="btn btn-info btn-sm"
type="button" ng-click="selectFilter(filter.field, filterType, filter.type)"><i class="fa fa-fw fa-square-o"></i> {{msgForFilter(filterType)}}</button>
</div>
</fieldset>
</div>
</div>
</div>
You don’t have to worry yourself with variables used by the code added, they are all handled by the
MdsFilterCtrl
and MdsEmbeddableCtrl
controllers.
When you’re done your module will now be using the embedded MDS grid. For more information about customizing it, please visit the Customizing embedded MDS grids section.
Customizing embedded MDS grids¶
MDS allows enhancing the default behavior of the embedded grids by overriding the default implementation of javascript methods handling those grids. For this to work, the user needs to provide file with its own implementation of those methods. Next sections will explain how to do this.
Preparation¶
There are a few steps you need to take in order to be able to customize the embedded MDS grid. First of all, you’re
going to need a controller that will handle the /mds-databrowser-config
requests sent to your module. This
controller should return a string containing the overriding javascript methods that will be used in place of the default
MDS ones. This doesn’t have to be a file loaded through the settings facade. It can also be a static file or the whole
content can be hardcoded(though it isn’t the best programming practice).
Here’s a code example:
@ResponseStatus(HttpStatus.OK)
@RequestMapping(value = "/mds-databrowser-config", method = RequestMethod.GET)
@ResponseBody
public String getCustomUISettings() throws IOException {
return IOUtils.toString(settingsFacade.getRawConfig(Constants.UI_CONFIG));
}
Here you can see that custom-ui.js
file is loaded through the settings facade as a raw configuration file. In
order to use this code snippet you’ll have to include the setting facade bean in your modules application context
(blueprint.xml file
) and add a custom-ui.js
file as the raw configuration. This doesn’t have to be a
file loaded through the settings facade. It can also be a static file or the whole content can be hardcoded(though it
isn’t the best programming practice).
Here’s a code example:
<bean id="settingsFacade" class="org.motechproject.config.SettingsFacade" autowire="byType">
<property name="rawConfigFiles">
<list>
<value>classpath:custom-ui.js</value>
</list>
</property>
</bean>
You also need to add the custom-ui.js
file to your modules resource directory.
Usage¶
Once you are done with the preparation, your module will now support UI customization for the embedded MDS grid, but won’t use it out of the box. In order to do that some URL changes must be made. If your module has been using MDS embedded grid before your javascript code probably contains some redirects to the MDS grids, like this:
$routeProvider.when('/{moduleName}/tab', {
redirectTo: 'mds/dataBrowser/' + entityId
});
This will load the default MDS grid and WON’T load the custom UI for it. In order for it to load it you need to add module name as a query parameter, like this:
$routeProvider.when('/{moduleName}/tab', {
redirectTo: 'mds/dataBrowser/' + entityId + "/{moduleName}"
});
This will result in loading the custom-ui.js
and using method implementation stored in it (if a method isn’t
defined in the file the default implementation will be used).
Now all you need to do is to place some javascript code in the custom-ui.js
file and check out your new,
Custom UI.
Examples¶
Here’s some code examples with explanation:
$scope.showBackToEntityListButton
$scope.showAddInstanceButton
$scope.showLookupButton
$scope.showFieldsButton
$scope.showImportButton
$scope.showExportButton
$scope.showViewTrashButton
$scope.showFiltersButton
$scope.showDeleteInstanceButton
Those variables let you decide which buttons will be visible in the embedded MDS grid.
$scope.backToEntityList
$scope.showLookupDialog
$scope.importEntityInstances
$scope.exportEntityInstances
$scope.showInstanceTrash
Overriding those methods lets you change the action of the Back to entity list
, Lookup
,
Import CSV
, Export Data
, View trash
buttons.
Tour of MOTECH UI¶
The MOTECH user interface currently focuses on supporting the needs of system administrators. We will to improve this after the MOTECH 1.0 release. This document presents a tab-by-tab description of the MOTECH user interface and is best viewed while looking at the UI.
Table of Contents
Tab-by-tab features¶
Admin Tab¶
- Managing Modules (Manage Modules)
Admins can install, remove, start, restart and configure modules through the user interface. Some modules expose user interfaces under the Modules tab (i.e. Commcare), but others have their configuration area embeded within this screen (i.e. OpenMRS-19).
- Automated Email and SMS Notification (Messages)
Admins can setup MOTECH so system administrators receive emails or SMS when errors occur in MOTECH.
- View and download the server log (Server Log)
Admins are able to view the tomcat server log within the UI as well as manage log options to log more endpoints.
Security Tab¶
- Role Based Access Controls
Users are able to manage role based access control from the user interface.
Modules Tab¶
The modules tab is the location where users interact with specific modules that present a user interface. These modules are loaded under the admin tab > manage modules. Note that some modules expose underlying features that do not have a User Interface element. The following modules are present in the core platform.
Data Services¶
- User Defined Entities (Schema Editor > + New Entity)
Users are able to create entities in the data base through the user interface with automatic Tasks Integration. This is commonly used to store elements from incoming sources, compile them and push them to other sources.
- User Defined Lookups (Schema Editor > Advanced > Indexes & Lookups)
Users are able to create lookups on any entity in MOTECH that return one or many results.
- User Defined REST endpoints (Schema Editor > Advanced > REST API)
Users are able to define REST endpoints through the user interface.
- Entity Auditing and Access Control (Schema Editor > Advanced > Auditing & revision Tracking)
Users are able to turn on auditing and access control for any entity in data services.
Email¶
- Configure an email server
- Send emails through the UI
- View email logs
Scheduler¶
- View scheduler jobs
Tasks¶
- Create and manage tasks (note: one task can perform one action)
- View task activity and troubleshoot failed tasks
REST API Tab¶
- View exposed REST API documentation created in the Data Services entities (Utilizes Swagger.io to automatically generate this documentation.)
Security Rules - Dynamic URLs¶
Table of Contents
Security Rules¶
Security rules are used to build the Spring SecurityFilterChain which is used to filter incoming requests. By default, MOTECH blocks access to any resources if you are not logged in, therefore, accessing any URL will redirect to the login page. If you need an endpoint using a different configuration, you must add a new rule or edit an existing one.
Each rule contains the following parameters:
Display name | Parameter name | Description | Values |
---|---|---|---|
Active | active | You can enable the rule using this parameter | true, false |
URL Pattern | pattern | URL pattern the security rule applies to (? matches one character, * matches zero or more characters, ** matches zero or more ‘directories’ in a path) | all |
Protocol | protocol | Protocol which will be used for communication | HTTP or HTTPS |
HTTP Method | methodsRequired | HTTP methods that have access to the endpoint | ANY, GET, POST, HEAD, OPTIONS, PUT, DELETE, TRACE |
Rest | rest | Whether the endpoint is meant for a form login process or as an REST endpoint that does not create a session for the client | true, false |
Priority | priority | Rule which has a higher priority will be checked first | priority value |
Supported Schema | supportedSchemes | Specify which authentication is required | NO_SECURITY or USERNAME_PASSWORD, BASIC, OPEN_ID |
User access | userAccess | Specify which users has access | list of users names |
Permission Access | permissionAccess | Requires user has at least one of the listed permissions to access the URL | list of permissions names |
(Not present in GUI) | origin | The module or user the rule originated from. Rules with SYSTEM_PLATFORM origin will be cleared at server start, so that they are always reloaded by the server | all |
(Not present in GUI) | version | The version of the module or platform in which the rule was created | all |
Priority¶
You can specify the order of processing using the priority parameter. Rules with greater priority will be checked first. In case of conflicting rules, the ones with higher priority will block the ones with lower priority. In this case it is worth considering to use more accurate URL patterns. It is very helpful for a hierarchy model of urls.
User access and permission access¶
When you are using permission access with user access in one rule you must know that these options operate separately. For example you gave User access to sampleUser
and Permission access to viewSecurity
permission. Access to the endpoint will be granted to sampleUser
and each other user with viewSecurity
permission.
Supported Schema, Rest and @PreAuthorize¶
If resources are protected using @PreAuthorize annotation you must remember that NO_SECURITY
schema will not work because access to these resources will be granted only to users
with respective roles. If other schemas are used, the user will still have to have the appropriate roles. The value of the rest option is important, you must know that if it’s true
then only NO_SECURITY
and BASIC
schemas will be supported.
Configuration via GUI¶
Attention
Before saving configuration remember to check the correctness of the settings, because you can lock yourself access to change them or you could provide access to the whole system. If you have lost access to the system, read the information on regaining access, due to incorrect security rules configuration.
If you want edit those settings via GUI, your user account must have viewSecurity and updateSecurity permissions. To open the configuration you want to select ‘Manage dynamic URLs’ option under Security tab in the Admin panel. You should see a list of all security rules. When you start editing or adding a new security rule form will expand and you will see options that were described earlier. To activate current configuration you must save changes.
Configuration via files¶
You can add rules to your module using configuration files. To do this you must create a file named securityRules.json
and place it in the resources
directory and then build the module. Security rule configuration files are discovered automatically by MOTECH when the module starts.
Sample file:
[
{
"active": true,
"pattern": "/**/myModuleApi/someResources/**",
"supportedSchemes": [
"NO_SECURITY"
],
"protocol": "HTTP",
"priority": 2,
"rest": true,
"origin": "SYSTEM_MODULE_MY_MODULE",
"version": "0.25",
"methodsRequired": [
"GET",
"POST"
]
},
{
"active": true
"pattern": "/**/myModuleApi/otherResources/**",
"supportedSchemes": [
"BASIC"
],
"protocol": "HTTP",
"userAccess": [
"userName"
],
"priority": 3,
"rest": true,
"origin": "SYSTEM_MODULE_MY_MODULE",
"version": "0.25",
"methodsRequired": [
"ANY"
],
}
]
Regaining access¶
To regain access to MOTECH, restart it. When server starts, default platform rules are always reloaded so it may help you regain access. If that doesn’t work you should try drop database table holding security rules or delete only rules that block access.
Automatic REST API documentation UI in MOTECH¶
MOTECH uses Swagger for generating a user interface that documents and allows testing of REST APIs. An interface can be generated for each module that wishes to register a REST API for documenting. This document will describe the process of registering a REST API for the module with the system.
It is worth noting that this documentation will always be generated for MDS entities that have REST access enabled.
Overview of the UI¶
Swagger will generate documentation for each endpoint specified in the API description:
For each HTTP method allowed for a given endpoint, the user will be able to view the details of the operation, such as the structure of the response, structure of the expected request, allowed parameters.
Users can use that UI to easily execute REST calls against the API and view the responses.
Registering REST documentation¶
The first step for registering rest documentation is creating a Swagger spec file that will describe the API. More information on spec files, ways of generating them and so on can be found on the Swagger spec Wiki.
After generating the file, it has to be exposed by the module through HTTP. You can achieve this either by placing the file in your webapp resources or by creating a Spring controller that will serve this content. For more information on exposing a resource, refer to the UI documentation.
After the resource is exposed through the UI, its path should be specified in the ModuleRegistrationData bean using the restDocsPath property. Below is an example of a simple module registration that registers the spec file with the system.
<bean id="moduleRegistrationData" class="org.motechproject.osgi.web.ModuleRegistrationData">
<constructor-arg name="url" value="../mymodule/resources/index.html"/>
<constructor-arg name="moduleName" value="my-module"/>
<property name="restDocsPath" value="/mymodule/resources/spec.json"/>
</bean>
After these steps, the module and its API will be incorporated into the Swagger UI exposed by MOTECH.
Implementers’ best practices¶
Table of Contents
The goal of this document¶
The goal of this document is to provide a set of tips, instructions and good practices for implementations built on top of the MOTECH platform or using MOTECH in the backend. The content of this document has been built based on our experiences with the implementations and the MOTECH platform in general.
Hardware recommendations¶
The hardware requirements will vary, depending on the amount and type of requests that your instance will serve at the same time and the amount of data, that you plan to store. This includes the installed bundles, log files and the database. We recommend that the instance running the MOTECH server has got at least 4GB of RAM. Lower amounts may considerably slow down the processing.
Of course the best way to find out the optimal configuration is to perform some stress testing. There are a lot of tools that can simulate the traffic to the server. Some examples are Apache JMeter or The Grinder. Running such stress tools on servers with various configurations will help to determine at which point adding more resources stops adding up to the amount of processed requests.
Topology recommendations¶
MOTECH can run in a clustered environment. This means that you can run several MOTECH instances in order to distribute the workload across multiple processing units. Similarly, you can set up multiple ActiveMQ instances that handle MOTECH events. In case one of the ActiveMQ instances goes down for any reason, the whole system remains functional, thanks to the failover mechanism. In order to make use of failover logic, a failover URI should be specified. You can read more about failover mechanism in ActiveMQ documentation.
In a topology with several MOTECH instances, you can choose whether to have the event handled by one instance only or, what is a rare case, by all instances. Using the first option (posting to a queue), the ActiveMQ event queue serves as a load balancer between multiple MOTECH instances. The second option (posting to a topic) is usually only used to notify the instances about some changes that must be immediately reflected on all of the instances. Finally, it is also possible to have clustered databases. There are two approaches when it comes to clustering databases. In the master-master model, all of the databases can update the data and the changes get replicated across all of the instances. In the master-slave model, only one of the databases (considered master) handles data updates and pushes the updated data to the slave servers. Of course using clustered environment is not a requirement. You can use single MOTECH, ActiveMQ and database instance, depending on the expected traffic.
Releases¶
Major MOTECH releases usually do not come periodically. The release date is dictated by the amount of tickets assigned to next versions and the time it takes to resolve them. Each new major release is announced on our mailing list. We strongly recommend using stable MOTECH versions.
In case the MOTECH version your implementation uses contains some bug, that seriously impacts your implementation, feel free to contact us. We will see if we can deliver the bug fix in form of a point release.
Building modules¶
Building implementations is often connected with the need to create additional modules, that will work with MOTECH. To ease and speed up the process of building a new module, we have prepared a set of maven archetypes, that help to start developing the module. In simple words, archetypes are “Hello World” MOTECH modules, containing all the basic configuration and files. You can pick a minimal archetype, that will contain only files and code required to have a module, or add more features, like module UI and controllers, communication with the database and module configuration and settings. If you plan to develop modules for your implementation, we highly recommend using our archetypes. You can read more about archetypes in our documentation.
Security¶
MOTECH implements several mechanisms to provide security on the application level. The access to the application or modules requires a login and necessary permissions. The security configuration allows to set up certain elements of the MOTECH security, like the limit of invalid logins, session timeouts or minimum password lengths. We recommend taking a close look at the documentation of the MOTECH Security Model.
Despite the application level solutions, there are still several security aspects that must be kept in mind while implementing web applications. The HTTP protocol does not provide any encryption of the data, therefore no guarantee can be given that the communication over HTTP is secure. To enhance the security of the communication between the server and the client browser, a secure protocol, like HTTPS, should be used. The data kept in MOTECH database is not encrypted as well. Establishing a secure connection with the database lies with the implementation as well.
Warning
Some of MOTECH modules allow integration with other systems. That usually requires providing account data for the external system. That data is kept in its plain form in the database or the property file!
One more thing to consider is the security of the property files. The bootstrap configuration is kept in the .motech/config directory in the user’s home directory and contains all the credentials required to access the database. Securing the access to that file rests with the implementation. We recommend setting strict access rights on the file and ensuring it cannot be accessed by unauthorized people.
Logs¶
While having logging enabled is a good thing, due to the ability to audit actions and possible server failures, it must be taken into consideration, that logs can use a considerable amount of disk space. MOTECH allows to control the logging levels via a property file (log4j.properties) and its Admin UI. Available levels, in the decreasing order of importance, are: FATAL, ERROR, WARN, INFO, DEBUG and TRACE. It is also possible to set up logging ALL or disable logging at all, by setting OFF. Setting up logging to a certain level will log all the statements of that level, plus all statements with the higher level. It means that setting up the logging for WARN level, will log all WARN, ERROR and FATAL statements.
The loggers always have names. In MOTECH, the name of a logger corresponds to the class name it logs from, however for the logs coming from the external libraries, the convention for logger names can differ. If you want to set up logging for external libraries, please check their website or documentation for logger names. There’s one logger that has got a special function and its name is root. If you have not explicitly provided different level for a logger, then this level is used. Please be cautious when changing the root logger level, as the amount of loggers in MOTECH and its libraries is huge. The default level is ERROR. We do no recommend going lower than WARN for the root logger. If you need more detailed logs, set up lower log levels for concrete loggers.
When developing your own modules to use with MOTECH, we recommend that you remember to set up proper logging in the code. This helps to debug issues and find problems faster. Try to use proper logger levels when logging information.
Data backup¶
MOTECH does not provide any tools or support for data backup out of the box. Taking care of performing regular data backups lies with the implementations. Of course most of the data is kept in the database. Please remember, that MOTECH uses two databases. One of them is managed by the Motech Data Services module (the main persistence layer in MOTECH). Another database belongs to the Quartz scheduler and contains scheduler schema and scheduled jobs data. The most popular way to backup data are SQL dumps, that are complete snapshots of the current state of the database. Such snapshots can be used to restore database from scratch at any time. The creation of such backups can be easily automatized, by having a script that runs periodically and creates necessary snapshots.
Besides databases, MOTECH can store some data in property files and read configurations from environment variables. The bootstrap configuration, containing database and ActiveMQ access data resides in .motech/config or is read from environment variables. MOTECH settings reside in .motech/config directory or database, depending on the chosen configuration source. Moreover, if the configuration mode has been set as FILE, the .motech/config directory will also contain property files of all modules, that store some settings. Depending on your implementation, you might want to backup this directory as well.
Get in touch¶
In case of any questions or problems during the implementation, feel free to contact us via mailing list. We will be happy to hear about your implementation and will try to resolve your doubts.
Architecture and Technical Overviews¶
Core Architecture¶
Architecture Overview¶
MOTECH can logically be broken into the core platform and modules. The core platform wraps several well-known open source systems, and augments and exposes their features to the other components. The main functions of the core are to wrap ActiveMQ (which provides the message queue and the message topic) and present an internal pub/sub like event interface to the module and implementation layers. The core also provides a module loading environment (OSGi), an interface to the Scheduler, and access to the database.
Modules within MOTECH are self-contained bits of functionality that are loaded into the server via the OSGi host. Typically a module provides one type of functionality, such as SMS or access to an external health system. For more information, see Modules Architecture. For a list of current and planned modules, see Modules.
MOTECH is designed to be horizontally scalable with multiple MOTECHs all acting as workers connecting to the same message queue and topic.
Design Philosophy¶
Stateless¶
A core design principle of the MOTECH platform is that the server should be stateless across requests to allow for horizontal scalability. It is expected that code running within the MOTECH server should perform a single action per request and then return. The module should never persist any state in memory or local disk and expect that state to be available to later requests.
Events¶
To aid in the development of stateless services, the MOTECH engine provides a pub/sub like event system. (The event system follows the publish-subscribe pattern but does not implement the standard Java pub/sub protocol.) It helps to decouple emitters of events from the modules that wish to consume them. Any module can emit an event by calling the EventRelay and passing it a MotechEvent and a subject. To register for an event, a module just needs to annotate a method with the list of event subjects of interest.
@MotechListener(subjects={EventKeys.SAMPLE_EVENT_SUBJECT})
public void handle(MotechEvent event) {
logger.info("Received sample event");
}
For more information, see Event and Scheduler Architecture.
Scheduled Events & Timers¶
To assist in the development of a stateless event-based server, the MOTECH platform provides access to a flexible scheduling system. Using the open source Quartz engine, MOTECH can easily schedule events for future consumption. For more information, see Event and Scheduler Architecture.
Subsystems¶
Tasks System¶
The Tasks system allows you to connect modules without code by using tasks. Each task consists of three parts:
- Trigger: an event raised by Module A (or the Scheduler)
- Filter: a conditional statement specifying whether the task should run
- Action: an action executed by Module B in response
In between the trigger and the action, tasks may use data loaders to look up data from other modules that are registered as data sources.
Data Services¶
MOTECH Data Services is a flexible data modeling system that allows users to define and share custom schemas without code, and provides auditing and revision tracking. It is a JDBC-based user configurable database abstraction layer on top of a standard SQL database. It provides generated POJOs and OSGi service interfaces for the data objects, generated CRUD events, and generated user interface for data browsing and editing. In a future release it will also support auto-generation of REST APIs.
Dependencies on Third-Party Systems¶
Quartz Scheduler¶
Quartz is an open source job scheduling engine that enables MOTECH modules to schedule events for future consumption.
Tomcat¶
Apache Tomcat provides the application container for MOTECH.
ActiveMQ¶
Apache ActiveMQ is an open source message broker that provides the message queue and the message topic.
OSGi¶
Each MOTECH module is an OSGi bundle. Using OSGi allows the platform to manage the bundle lifecycle (adding, removing, starting, and stopping modules), and allows modules to expose service interfaces. For more information, see Modules Architecture.
Event and Scheduler Architecture¶
Event Handling and Scheduling among Modules¶
The following diagram provides three examples of Motech modules:
Motech module A publishes events, schedules new jobs and listens for events. An example of a Motech platform that has these three responsibilities is the Message Campaign module.
Motech module B schedules new jobs.
Motech module C listens to events of subject X and Y: listener X listens to events of subject X, and listener Y listens to events of subject Y.
Event Handling and Scheduling Architecture¶
To schedule a job in MOTECH, the core platform exposes the MotechSchedulerService. Clients of the service have an instance of it injected into the class that uses it. This service employs Quartz to schedule MotechScheduledJobs. When triggered, MotechScheduledJobs raise events that are sent through an event relay to the event queue. These messages are dequeued and then received by a consumer, the event listener registry, which in turn discovers all of the listeners on the event and invokes the appropriate method that was listening on that event.
Notes¶
- The scheduler service retrieves the Quartz Scheduler from the SchedulerFactoryBean. The service can only schedule MotechScheduledJobs, which all must include a MotechEvent.
- When the trigger for the scheduled job is satisfied, the job is executed and the accompanying Motech event is sent to the SchedulerFireEventGateway interface. This gateway is defined in schedulerFiredEventChannelAdapter.xml and a proxy is generated by Spring at runtime.
- The SchedulerFireEventGateway serves as an outbound message gateway to shuttle messages to the event relay, which then sends JMS messages to the event queue.
- The event queue dequeues messages and routes them to the event listener registry. The core platform has one consumer for events, a channel that routes messages to an event listener registry.
- The event listener registry retrieves the listeners that are listening on the motech event it is relaying (listening is based on the value bound to the motech event’s subject key).
- The core platform scans new bundles for any method annotated as a MotechListener, and registers those methods with the listener registry.
- If the event has a specific destination or only one listener, the listener’s handle method is called. This will invoke the method that was annotated as a MotechListener. These listener classes can be project specific and will reside outside of the core platform.
- If the event has multiple listeners, a separate event is raised for each listener. The original event object is not handled by a listener in this case.
- The EventListener’s handle method will invoke the method that was annotated as a MotechListener. The MotechEvent will be passed to that method as a parameter.
- If you wish to use ActiveMQ web console to view MotechEvents, please note that the server running the console must have the motech-platform-event bundle in its classpath. Therefore, either place the jar in the default location, or add a classpath that will contain the motech-platform-event jar.
- Note that MOTECH Scheduler is not a real-time system. There’s no guarantee that your scheduled job will fire the exact same minute it has been scheduled for. Everything depends on the present CPU usage, other jobs that must be served and many more factors. Pay special attention to this, when scheduling jobs close to midnight, in case the date matters in your use case.
Modules Architecture¶
Modules within MOTECH are self-contained bundles of functionality that are loaded into the server via the OSGi host. Modules interact with the core platform through its APIs and with other modules, either through their APIs or by consuming their events. Modules can expose service interfaces of their own as well as emit their own events. Modules may also register servlet controllers, which allow them to respond to HTTP requests.
Through MOTECH Data Services, a modules may expose entities from its data model. This allows a module to provide a data editor, REST APIs, record-level security, and field-level auditing. Via the Tasks system, modules can expose triggers, data and actions to be orchestrated by other modules.
See Modules for the list of current and planned modules.
Reasons to create a module include developing application-specific UI, business logic, and data models. Another reason is to develop generic reusable functionality to share with the MOTECH community.
The MOTECH war already contains all platform modules required for operation and two additional modules: Admin Module and Scheduler Module.
The Admin Module allows installing additional modules at runtime, either by uploading a module jar or by selecting a module to be downloaded from our repository.
Except from war modules, all MOTECH modules live in ~/.motech/bundles
. Module jars placed in that directory will be loaded by MOTECH at startup, if a module placed there has
the same Bundle-Version and Bundle-SymbolicName as a module from the war,
that module will override the platform one.
Data Services Architecture¶
There will be text here.
Security Model¶
Table of Contents
Introduction¶
Security aspects in MOTECH are handled by the web-security module. It is responsible for users, roles and permissions management, authentication, filtering requests and more. The web-security module uses Spring security in the backend and allows to use certain tools from the Spring security, like @PreAuthorize and @PostAuthorize annotations or SecurityContextHolder, that makes it possible to retrieve current authentication data. The web-security module provides an ability to administer users, roles, permissions and security rules via UI, for users that have been given the necessary permissions. The web-security module uses MDS as the datastore. User details, as well as roles, permissions and configured security rules are kept there. User passwords are hashed before storing, using bcrypt hashing algorithm.
MOTECH roles and permissions¶
MOTECH permissions can be used to secure an access to methods, functionalities or even whole modules. MOTECH roles are containers, that can keep one or more MOTECH permissions. MOTECH roles can be assigned to MOTECH users. MOTECH defines several permissions and roles that secure access to certain parts of the system, but both users and developers may create further roles and permissions, based on their needs.
Default MOTECH roles¶
MOTECH defines 5 default roles.
MOTECH role | Description |
---|---|
Motech Admin | Contains all MOTECH permissions. Any new permissions will get added to this role automatically. |
Email Admin | Grants access to the Email module, allowing to send e-mails, change Email module settings and view detailed e-mail logs (containing e-mail addresses and e-mail contents). |
Email Junior Admin | Similar to the Email Admin, grants access to the Email module, however the Junior Admin can only see basic e-mail logs (status and timestamp). |
Bundle Admin | Allows to install, uninstall, update, start and stop modules. |
Campaign Manager | Grants access to the Message Campaign module. |
Access to modules¶
You can use the MOTECH permissions to secure an access to the module. To do so, you must set the roleForPermission property of the org.motechproject.osgi.web.ModuleRegistrationData bean. The value of this property can either be a String, that represents a permission name, or a list of permission names, in which case, the user will be granted an access if they have at least one of these permissions.
The sample definition of the ModuleRegistrationData bean in the blueprint context, with the roleForAccess property is shown below.
<bean id="moduleRegistrationData" class="org.motechproject.osgi.web.ModuleRegistrationData">
<constructor-arg name="url" value="../email/resources/index.html"/>
<constructor-arg name="moduleName" value="email"/>
<property name="roleForAccess">
<list>
<value>viewBasicEmailLogs</value>
<value>viewDetailedEmailLogs</value>
</list>
</property>
<property name="settingsURL" value="/email/settings" />
<property name="defaultURL" value="/email/send"/>
</bean>
Securing methods¶
MOTECH permissions can also be used to secure the execution of methods. This is achieved, using the Spring annotations. To enable Spring security annotations, add the following entry to the blueprint.xml context file of your module:
<security:global-method-security pre-post-annotations="enabled" proxy-target-class="true"/>
Once the security is enabled, you can annotate the methods to secure them using Spring security annotations. You can find the description of the supported annotations in the Spring documentation. The most commonly used annotation in the MOTECH modules is the @PreAuthorize annotation, which checks logged user credentials before executing the method and if they are insufficient, an attempt to execute the method will be denied. A method signature, that would get executed only for the users with the “admin” permission, could look like this:
@PreAuthorize("hasRole('admin')")
public void mySecureMethod() {
doSomething();
}
Similar to the above, we can specify a set of roles. The execution will be allowed, if the user has got at least one of the listed permissions. The sample code could look like this:
@PreAuthorize("hasAnyRole('admin', 'junior_admin')")
public void mySecureMethod() {
doSomething();
}
Note
Do not get fooled by the hasRole and hasAnyRole names. Despite the name suggesting otherwise, you should place MOTECH permissions there, not MOTECH roles!
The MOTECH web-security module will look for the @PreAuthorize and @PostAuthorize annotations in the modules, and add the permissions, that are not yet present in the system.
Retrieving security context¶
If you want to implement a custom security processor for your module or retrieve certain security information, you can do so, using the org.springframework.security.core.context.SecurityContextHolder util class. It allows you to retrieve information about current authentication. See the code below for the example on retrieving current user and his permissions.
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null) {
User user = (User) auth.getPrincipal(); // RETRIEVE USER
Collection<GrantedAuthority> authorities = auth.getAuthorities(); // RETRIEVE PERMISSIONS
}
Login modes¶
The MOTECH platform allows two ways of authenticating users. The two modes are called:
- Repository
- Open ID
The login mode is chosen by the administrator, during first server startup or in the motech-settings.properties file, depending on the chosen config source.
Using the Repository login mode, MOTECH will provide a way to create an initial user, during first server startup. The initial user is granted all default permissions (Motech Admin role). New users can be created via UI, or using the MotechUserService from web-security module. All the users are stored in the MOTECH database, using MDS.
If the chosen login mode is Open ID, it is also necessary to provide a valid URL to the Open ID provider, that will handle authentication. For example, to set Google as your Open ID provider, the URL should be https://www.google.com/accounts/o8/id. It will be possible to authenticate to MOTECH, by logging in at the provider. The first user that logs in will be granted all default permissions (Motech Admin role). Next users that log in will not be given any permissions, but that may be altered via UI, or using the MotechUserService.
Warning
When choosing Open ID as the login mode, please remember that everyone who has got an account at the specified provider will be able to access your server. If that’s not what you want, use the Repository login mode.
HTTP access¶
If you are not authenticated, the access to any MOTECH resources is blocked by default. Therefore, most of the requests will get a 301 HTTP response, with a redirection to the login page. It is possible to configure exceptions to this rule, by creating dynamic URLs. They can be used to alter the security settings for specified URLs or to disable the security at all (meaning everyone will be able to access the resource). Security rules can be altered via UI or via properties file, placed in your module.
Security Configuration¶
The MOTECH platform allows you to configure security options. You can easily change those setting via Admin UI(Settings
tab),
or by editing motech-settings.properties
file. For more details you should read the configuration system section.
Below you can find available options.
Email required (security.required.email
) - Indicates whether you must provide an email address when creating
the user. Possible values: true
, false
.
Failure login limit (security.failure.login.limit
) - The permissible number of incorrect login attempts, default
value is 0. After this limit is reached the user is blocked. After a successful login counter is reset. If the value is 0
then blocking is inactive.
Session timeout (security.session.timeout
) - The session timeout in seconds, default 30 minutes. After this
time session will be closed.
Minimum password length (security.password.minlength
) - The minimum length of the password, default 0. If the
value is 0 then length checking is disabled.
Password restriction (security.password.validator
) - Name of the password validator which will be used for checking
passwords. Validator specifies password restriction e.g. 1 number, 1 special character. You can use 1 of 4 validators implemented
in MOTECH(default is none
) or you can create your own password validator. Below you
can find the names of validators provided by MOTECH.
none
lower_upper
- at least 1 uppercase and lowercaselower_upper_digit
- at least 1 uppercase lowercase and digitlower_upper_digit_special
- at least 1 uppercase, lowercase, digit and special character
Days until password expiration (security.password.reset.days
) - The number of days after which the users
password will expire. When a password expires the user will be forced to change his new password after logging into MOTECH.
The user will have to provide the old password for verification and the new password which has to be different from the
old one. An expired password will never result in the user being absolutely blocked out of the system - they will always
be able to regain access by changing their password to a new one. The last password change date is used to calculate the
date of the password expiration. The default is 0, meaning password will never expire.
Enable password expiration reminders (security.password.reminder.sendReminder
) - Whether email reminders
should be sent for users with their passwords nearing expiration. Takes true or false, false is default. The number
of days until sending reminder is controlled by security.password.reminder.daysBeforeExpiration
setting.
Days before password expiration to send the reminder (security.password.reminder.daysBeforeExpiration
) - The number
of days before password expiration that mark the date on which an email reminder will be sent to the user if
security.password.reminder.sendReminder
is set to true. The reminders are sent on midnight.
Creating Password Validator¶
Description¶
To create your own password validator you must create new validator class which will implement PasswordValidator
interface. The next step is to create OSGI service from your new validator. To do this you must add
@Service
annotation to the class and service reference information in the blueprint file.
PasswordValidator
interface contains following methods:
- void validate(String password) throws PasswordValidatorException - validates password.
- String getValidationError(Locale locale) - returns the error message(should be treated as a literal) for the validator. Message should explain what is expected in password.
- String getName() - Returns the name of the validator used for retrieval. Must match the value from the configuration in order to be used.
Example Code¶
Below you can find example of a validator which requires 3 special characters in password.
@Service("serviceName")
public class MyValidator implements PasswordValidator {
private String name = "validator_name";
@Override
public void validate(String password) {
CharacterCount count = new CharacterCount(password);
if (count.getSpecial() < 3) {
throw new PasswordValidatorException("Invalid password, validator name - " + name);
}
}
@Override
public String getValidationError(Locale locale) {
return "Password must have 3 special characters";
}
@Override
public String getName() {
return name;
}
}
To enable it you must add <osgi:service ref="serviceName" interface="org.motechproject.security.validator.PasswordValidator"/>
to the blueprint file and set it in config(security.password.validator=validator_name).
Modules¶
Appointments¶
Provides appointment scheduling and reminders
Atom Client¶
Fetches Atom feed(s) and publishes events when content changes
Batch¶
An implementation of Spring batch (version: 3.0.0.M3); it essentially deals with scheduling triggering of jobs
Care Services Discovery (CSD)¶
Consumes the IHE Care Services Discovery Profile from a CSD registry such as OpenInfoMan, representing the information natively in MOTECH within MDS.
CommCare¶
Integrates the MOTECH platform with CommCareHQ, an open-source platform to help manage community health workers
Data Services¶
Integrates data from external data sources and provides sharable data schemas
Event Logging¶
Allows MOTECH modules to easily see each others’ events
Hindi Transliteration¶
Supports transliteration of English strings to Hindi using ITRANS encoding
Hub¶
Provides an implementation of the PubSubHubbub Hub spec; exposes an API so other modules can act as publisher and make contents available to it for distribution
IVR¶
Integrates the MOTECH platform with Interactive Voice Response (IVR) providers thus enabling support for voice/audio dialogs
Message Campaign¶
Enrolls users in message campaigns with flexible content-scheduling rules
mTraining¶
Provides data containers and APIs for defining mobile (e.g. SMS or IVR-based) training courses and tracking user enrollment and progress
OpenMRS¶
Integrates the MOTECH platform with OpenMRS, an open source electronic medical record platform
Pill Reminder¶
A flexible reminder system that may be used to alert patients when it is time to take their medications
Schedule Tracking¶
Enrolls users for alerts based on complex scheduling rules
Developing the MOTECH Platform¶
This section of the documentation is aimed at developers and maintainers of the MOTECH Platform. These docs help MOTECH devs get up and running, from configuring a machine, to getting the code, and committing and reviewing changes. If you find any errors in the topics below, or you have any other questions about MOTECH development, please contact us via the mailing list.
Setting up a Development Environment¶
The topics below will walk you through installing MOTECH on a Mac or Linux machine. Note that the Docker-based setup is much faster than the “official” method but the instructions are in beta. If you have any trouble with either approach, please feel free to contact us via motech-dev@googlegroups.com.
Installing MOTECH for Developers (“Official” Method)¶
Table of Contents
Installing on Ubuntu¶
The versions below may change, most likely the latest stable release will work for your purposes. We upgraded from Java 7 to Java 8 in MOTECH version 0.28. The instructions are annotated with this change. If you have any trouble, please feel free to send feedback to our developer list.
- Install Ubuntu Desktop 14.04 LTS 64bit
Install Maven, Git, Curl, ActiveMQ, NodeJS, NPM, Bower, Gulp and a database of your choice
In terminal, type
sudo apt-get install curl git maven activemq npm curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash - sudo apt-get install -y nodejs sudo npm install -g bower gulp
The two datastores officially supported by MOTECH are MySQL and PostgreSQL. It is not required to install both of them to run MOTECH, but provided you intend to introduce some changes to the code, it may be required that you test the outcome on both databases.
sudo apt-get install mysql-server sudo apt-get install postgresql
On a fresh Ubuntu installation, you may need to run the following first
sudo apt-get update
Configure ActiveMQ
Run the following
sudo ln -s /etc/activemq/instances-available/main /etc/activemq/instances-enabled/main
Note
For ActiveMQ scheduled delivery to work, you must set the attribute: schedulerSupport=”true” for the broker element in your activemq.xml config file. This file should be located at (active-mq-folder)/conf/activemq.xml.See ActiveMQ docs.
Install JDK 8 (For Developing MOTECH v.0.28 and greater)
Go to The Java JDK Download Page
Accept License Agreement
Click on jdk-8u73-linux-x64.tar.gz (or latest stable version)
Extract the file into your home directory, ie:
/home/*<user>*/jdk1.8.0_73
Set the proper Java environment and change maven options:
Start a new terminal session
Edit your .profile file
nano ~/.profile
append the following at the end of the file:
export PATH="$HOME/jdk1.8.0_73/bin:$PATH" export JAVA_HOME=$HOME/jdk1.8.0_73 export MAVEN_OPTS="-Xmx512m -XX:MaxPermSize=128m" export CATALINA_OPTS="-Xms1024m -Xmx2048m -XX:MaxPermSize=1024m"
Save the changes (Ctrl+X) and quit
Confirm the settings are right
Log out & log back in & start a new terminal
Type
java -version && env | grep "\(MAVEN_OPTS\|CATALINA_OPTS\)"
You should see something like:
java version "1.8.0_73" Java(TM) SE Runtime Environment (build 1.8.0_73-b02) Java HotSpot(TM) 64-Bit Server VM (build 25.73-b02, mixed mode) MAVEN_OPTS=-Xmx512m -XX:MaxPermSize=128m CATALINA_OPTS=-Xms1024m -Xmx2048m -XX:MaxPermSize=1024m
Install Tomcat7
Go to Tomcat’s download page
Under 7.0.68 (or the latest stable version) - Binary Distributions - Core, click on tar.gz
Once downloaded, expand the file to your home directory, i.e.:
/home/*<user>*/apache-tomcat-7.0.68
Edit the
tomcat-users.xml
file (located under\etc\tomcat7\conf\
) to add an admin user:In the terminal type
nano ~/apache-tomcat-7.0.68/conf/tomcat-users.xml
Insert a line similar to the following before the closing </tomcat-users> tag:
<user username="*<username>*" password="*<password>*" roles="manager-gui"/>
Save the changes (Ctrl+X) then quit
Edit the web.xml of the manager application(located under
\webapps\manager\WEB-INF\web.xml
):nano ~/apache-tomcat-7.0.68/webapps/manager/WEB-INF/web.xml
Edit the lines in multipart-config defining the max upload value. Change it from 50MB to a bit more, 100MB should suffice:
<!-- Before changes --> <multipart-config> <!-- 50MB max --> <max-file-size>52428800</max-file-size> <max-request-size>52428800</max-request-size> <file-size-threshold>0</file-size-threshold> </multipart-config>
<!-- After changes --> <multipart-config> <!-- 100MB max --> <max-file-size>100000000</max-file-size> <max-request-size>100000000</max-request-size> <file-size-threshold>0</file-size-threshold> </multipart-config>
Save the changes by hitting
Ctrl+X
then quitNow edit
~/.bashrc
to setup tomcat’s environment variablenano ~/.bashrc
Append the following line:
export CATALINA_HOME=$HOME/apache-tomcat-7.0.68
Save the changes (Ctrl+X) then quit
Start a new terminal session or type
source ~/.bashrc
Setup MySQL (skip if you did not install MySQL server)
Access your database, by typing in the terminal:
$ mysql -u root -p
Create required databases (note: when you’re using account with privilages for DB connection, MOTECH will create necessary DBs and fill them with data; otherwise you have to create them yourself)
sql> create database motechquartz; sql> create database motechschema; sql> create database motechdata; sql> exit;
(Optional) Create user for the motechquartz database. MOTECH will use the user and password from the bootstrap configuration by default, but you can adjust that in the Scheduler settings and provide different credentials.
sql> create user 'quartz'@'localhost' identified by 'quartz2123'; sql> grant all privileges on motechquartz.* to 'quartz'@'localhost';
Note
Sometimes it is needed to set the proper database character encoding. For example, to create motechdata database and motechschema database with UTF-8 character encoding, change your sql query to:
sql> create database motechdata default character set utf8 collate utf8_general_ci; sql> create database motechschema default character set utf8 collate utf8_general_ci;
Setup PostgreSQL (skip if you did not install PostgreSQL server)
Access your database, by typing in the terminal:
$ sudo -u postgres psql postgres
Set a password for the “postgres” database role
postgres=# \password postgres
and give your password when prompted.
Create required databases (note: when you’re using account with privilages for DB connection, MOTECH will create necessary DBs and fill them with data; otherwise you have to create them yourself)
postgres=# create database motechquartz; postgres=# create database motechschema; postgres=# create database motechdata; postgres=# (ctrl + D)
(Optional) Create user for the motechquartz database. MOTECH will use the user and password from the bootstrap configuration by default, but you can adjust that in the Scheduler settings and provide different credentials.
postgres=# create user quartz with password 'quartz2123'; postgres=# grant all privileges on database motechquartz to quartz;
Note
MD5 authentication is required and should be enabled by default in latest versions of PostgreSQL. If it’s not the case, you might need to enable this by hand. For more information refer to: http://www.postgresql.org/docs/9.3/static/auth-methods.html
- Start Tomcat
In terminal, type:
~/apache-tomcat-7.0.68/bin/catalina.sh jpda start
You should see messages similar to:
Using CATALINA_BASE: /home/*<user>*/apache-tomcat-7.0.68 Using CATALINA_HOME: /home/*<user>*/apache-tomcat-7.0.68 Using CATALINA_TMPDIR: /home/*<user>*/apache-tomcat-7.0.68/temp Using JRE_HOME: /home/*<user>*/jdk1.8.0_73 Using CLASSPATH: /home/*<user>*/apache-tomcat-7.0.68/bin/bootstrap.jar:/home/*<user>*/...
You can also confirm tomcat was started by going to http://localhost:8080 in a browser
Jump to the Building and Installing MOTECH section to install MOTECH
Installing on a Macintosh¶
Installing Prerequisites for MOTECH
Installing HomeBrew
To install Homebrew, run the following in the terminal
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
- Use Homebrew to install git, erlang, ActiveMQ, NodeJS and Apache Tomcat:
brew install git brew install activemq brew install tomcat brew install maven brew install node
Homebrew installations are located
in /usr/local/Cellar` with symlinks in ``/usr/local/bin
, which should already be part of your $PATH environment variable.Note
Homebrew provides instructions about how to run these applications, as well as how to have launchd start them automatically on system startup.
Use NPM (installed with NodeJS) to install Bower and Gulp.
npm install -g bower gulp
Configuring Tomcat
Edit the
tomcat-users.xml
file to add an admin user. Insert a line similar to the following before the closing</tomcat-users>
tag:<user username="motech" password="motech" roles="manager-gui"/>
Edit the web.xml of the manager application(located under
\webapps\manager\WEB-INF\web.xml
) and change the lines in multipart-config defining the max upload value. Change it from 50MB to a bit more, 70MB should suffice:<!-- Before changes --> <multipart-config> <!-- 50MB max --> <max-file-size>52428800</max-file-size> <max-request-size>52428800</max-request-size> <file-size-threshold>0</file-size-threshold> </multipart-config>
<!-- After changes --> <multipart-config> <!-- 70MB max --> <max-file-size>71680000</max-file-size> <max-request-size>71680000</max-request-size> <file-size-threshold>0</file-size-threshold> </multipart-config>
Installing JDK 8:
Mac OS includes JDK6 by default, however JDK 8 is required for MOTECH. Use these instructions to install the latest version of the JDK or these instructions to install JDK 7 for development on MOTECH v.0.27 and prior.
Installing MySQL:
Before installing MySQL, you will need Xcode from the App Store. This can take a while; it’s a big download.
Next start Xcode from the Launchpad (rocketship icon in the dock) and select Install. Then you can quit Xcode; you don’t need to keep it running.
Note
(Command Line Tools using Xcode are included in OS X Mavericks, but not previous OS versions. If you are running Mountain Lion, you can follow these instructions:)
Go to http://dev.mysql.com/downloads/mysql/ and download the appropriate DMG archive. Open it, double-click on the installer, and follow directions.
d. Once mysql has finished installing, double-click the MySQL preferences pane in the DMG and follow instructions. For more details see these instructions .
Note
Homebrew can be used to install MySQL, however Homebrew will not install the Mysql System Preferences control panel.
Setting up Symbolic Link and Environment Variables
Create a symbolic link from the Tomcat directory (Homebrew installs into
/usr/local/Cellar/tomcat/<version number>/libexec
) to/usr/local/tomcat
:ln -s /usr/local/Cellar/tomcat/`brew info tomcat | grep stable | awk '{print $3}' | sed 's/,//'`/libexec /usr/local/tomcat
Edit your
~/.bash_profile
to set environment variables (catalina is Tomcat):export JAVA_HOME="/Library/Java/Home" export MAVEN_OPTS="-Xmx512m -XX:MaxPermSize=128m" export CATALINA_HOME="/usr/local/tomcat" export CATALINA_OPTS="-Xms1024m -Xmx2048m -XX:MaxPermSize=1024m" export PATH=/usr/local/mysql/bin:$PATH
- When you’re done editing:
source ~/.bash_profile
Jump to the Building and Installing MOTECH section to install MOTECH
Building and Installing MOTECH¶
Getting the MOTECH code
Building MOTECH
Assuming you issued the git clone command in your home directory root, in the terminal
$ cd ~/motech $ mvn install
b.) It takes some time to build MOTECH, but eventually you should see:
[INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 29:19.284s [INFO] Finished at: Fri Jun 07 12:12:43 PDT 2013 [INFO] Final Memory: 152M/378M [INFO] ------------------------------------------------------------------------
Note
Should you get a java.lang.OutOfMemoryError exception, it may be because you forgot to set MAVEN_OPT as described in [3.5]. But you may need to increase -Xmx. So something like -Xmx1024m might work.
Install MOTECH
In a browser, go to http://localhost:8080
Click on Manager App
Type the user/password you used in tomcat-users.xml (if you installed via docker the default username/password is motech/s3cret).
temporary hack you need to remove ~/.motech/config/motech-settings.conf to allow the create initial user wizard.
In the Tomcat Web Application Manager, scroll down to the Deploy section and the WAR file to deploy subsection, click on Browse and select or navigate to
~/motech/platform/server/target/motech-platform-server.war
then click on DeployDepending on your machine it could take a while for motech-platform-server to deploy
If you get an error of the form: “the request was rejected because its size (68032892) exceeds the configured maximum (52428800)” follow these instructions to
In the Tomcat Web Application Manager page, click on
/motech-platform-server
, you get the MOTECH initial user screen
Note
The war file contains all modules required for starting and managing MOTECH. You can either use the Admin UI to install additional modules at runtime or place them in the
~/.motech/bundles
directory and restart MOTECH. Note that doing a mvn clean install on any of our modules will place that module in the~/.motech/bundles
directory automatically. Modules from that directory always override the ones contained in the war if their Bundle-Version and Bundle-SymbolicName are the same.
Installing the IDE, Intellij IDEA Community Edition & open MOTECH project¶
Go to the Jetbrains home page and click on Download Now in the Community Edition box, then expand the file to your home directory.
From a terminal, assuming you extracted IntelliJ to ~/idea-IC-143.2287.1, start IntelliJ
$ ~/idea-IC-143.2287.1/bin/idea.shSelect Import Project
Select ~/motech/pom.xml, a dialog box will appear. Set the options as shown:
Click Next
In Select Profiles, do not select any profile, click Next
In Select Maven projects to Import, there should only be one project: org.motechproject:motech:1.0-SNAPSHOT, click Next
In Please select project SDK, if the 1.8.0_73 is present, select it, otherwise add it:
Click +
Select JDK
Select /home/YOURUSERNAME/jdk1.8.0_73, then click OK
Click Next
Click Finish
Background processes will take a long time
You can also create a menu launcher, so you can start IntelliJ from the gui:
From the Tools menu select Create Desktop Entry
A IntelliJ menu item will be created in the Development application group
Debug demo module in IntelliJ
Start IntelliJ (from the command line, or from launcher icon if you created one)
It’ll automatically open the motech project (if it was the last project you worked on)
From the Run menu select Edit Configurations
Click on the green +
Select Remote
Give a name to your Run/Debug configuration and change the port to 8000 as:
Hit OK
Set a breakpoint somewhere in the demo module code, i.e.:
From the Run menu, select Debug ‘Tomcat’ where Tomcat is the name of your configuration.
In the browser go to the place that will hit the breakpoint, i.e.: if you setup a breakpoint as in the previous screen, then in the Demo module, click the Decision Trees tab, and you should hit the breakpoint!
Installing MOTECH Using Docker (“Beta”)¶
Note
These instructions assume you’re running on Ubuntu. If you are using MAC OSX or Windows, consider using Docker Toolbox for running Docker and Docker Compose. After installing and running the Docker Toolbox, the steps for running MOTECH containers shouldn’t be much different.
This document provides instructions for creating a MOTECH environment using Docker containers. These instructions are “in beta” (the official installation guide is still the one here), but many members of the MOTECH dev team have been following this approach with success. This installation method is much faster than the official route.
There are two supported ways to install MOTECH with Docker:
- As an implementer - follow this approach if you want to install a released version of MOTECH.
- As a developer - follow this approach if you will be developing MOTECH and want to build the platform and modules from source code. If you install as developer, only the development environment will be set up for you - you will have to build and deploy MOTECH yourself.
Get Docker, Docker-Compose and motech-docker¶
Whether you’re installing as an implementer or a developer, you’ll need Docker and Docker-Compose:
Docker¶
Follow the instructions on the Docker website to get the latest version of Docker.
Execute the following to configure Docker to work for non-root users:
sudo groupadd docker sudo gpasswd -a ${USER} docker (logout and re-login) sudo service docker restart
Docker-Compose —
Execute the following to install Docker-Compose in Linux:
sudo curl -L https://github.com/docker/compose/releases/download/1.2.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
If you get a memory error, you may need to run these commands in root (sudo -i)
motech-docker¶
Clone the motech-docker project from GitHub or download it as a zip file and extract it. You’ll need to run all commands from the motech-docker directory.
sudo apt-get install git
git clone https://github.com/motech/motech-docker
cd motech-docker
Implementer Setup¶
Go to your motech-docker directory. To setup as an implementer (everything is automagically installed):
./setup_as_imp.sh
Type the following to start MOTECH in the background:
docker-compose up -d
Voila! MOTECH has started. Wait a little bit (about 30s) then direct your browser to: http://localhost:8080/motech-platform-server
Note
‘docker-compose up’ ERASES ALL YOUR DATA (well not really all, but pretend it does). You have to run it at least once to setup MOTECH. If you run it again, it’ll erase everything you did in MOTECH. It’s useful to start afresh, but remember: it nukes everything!
Developer Setup¶
Go to your motech-docker directory. To setup as a dev:
./setup_as_dev.sh
Type the following to start all the pieces that MOTECH needs to run in the background:
docker-compose up -d
Once you start the containers with the docker-compose up -d command above and before you build MOTECH for the first time. If you wish to add additional modules to MOTECH, then you can either use the Admin UI or copy them into /root/.motech/bundles directory of the container.
Conveniently, the container’s /root/.motech/bundles directory is exposed as the docker-motech-bundles directory (with a-rw access) in your home directory (also note that the container’s /root/.motech/config dir is also exposed as ~/docker-motech-config). So, you can either manually copy the binaries you require, or you can create a symbolic link to ~/docker-motech-bundles from ~/.motech/bundles.
Assuming the latter, and that you never built MOTECH before, you’d run the following commands:
# go to your home dir
cd
# create the .motech dir
mkdir .motech
# create the symlink
ln -s ~/docker-motech-bundles .motech/bundles
If you built MOTECH before, you can just delete the bundles directory and create the symlink using the command above.
Build, deploy and run MOTECH: see the Developer Installation Guide:.
Note
For your convenience, the max upload in the Tomcat Manager is already increased to accept the MOTECH war.
Some Useful Docker Compose Commands¶
Stop MOTECH¶
docker-compose stop
Restart MOTECH¶
docker-compose start
Watching logs¶
To watch all the logs (very verbose):
docker-compose logs
To watch only the tomcat logs:
docker-compose logs tomcat
See the sections in the generated docker-compose.yml to see what other logs you can watch.
Configuring MOTECH¶
There will be more text here. This doc may belong in “Setting up a Development Environment” or in “Getting Started”.
Introduction¶
Motech provides Maven archetypes in its Nexus repository which you can use to create a new Motech module. The archetypes supply basic source code needed for a new module, as well as configuration files for packaging the module as a bundle to be loaded into a Motech server.
The first archetype is the minimal bundle archetype. This supplies just enough source code and configuration to make a “Hello World” module.
- Additional archetypes can add functionality to the minimal archetype:
- The http bundle archetype adds a servlet to respond to HTTP requests, and a simple web user interface.
- The repository bundle archetype adds a repository layer for storing and retrieving data from
MOTECH's data services
. - The settings bundle archetype adds a properties file to store custom module configuration, and exposes the configuration through Motech’s web user interface
Any combination of these additional archetypes may be added to the minimal archetype.
Minimal Bundle Archetype¶
To create a new minimal bundle from the minimal bundle archetype, use the following command:
mvn archetype:generate -DinteractiveMode=false -DarchetypeRepository=http://nexus.motechproject.org/content/repositories/releases -DarchetypeGroupId=org.motechproject -DarchetypeArtifactId=minimal-bundle-archetype -DmotechVersion=0.26-SNAPSHOT -DgroupId=org.motechproject -DartifactId=motech-test-module -Dpackage=archetype.test -Dversion=0.1-SNAPSHOT -DbundleName="Archetype Test Module"
This will create a new Maven project in your current directory.
This is a long command. Here is an explanation of the parameters:
parameter | value | explanation |
---|---|---|
-DinteractiveMode | false | no need to wait for user input |
-DarchetypeRepository | http://nexus.motechproject.org/content/repositories/releases | where to find the archetype |
-DarchetypeGroupId | org.motechproject | group name for the archetype |
-DarchetypeArtifactId | minimal-bundle-archetype | which archetype to use |
-DmotechVersion | 0.26-SNAPSHOT | Motech version to use with the new module |
-DgroupId | org.motechproject | group name for the new module |
-DartifactId | motech-test-module | artifact name for the new module |
-Dpackage | archetype.test | Java package for new module classes |
-Dversion | 0.1-SNAPSHOT | version of the new module itself |
-DbundleName | “Archetype Test Module” | name of the new module |
HTTP Bundle Archetype¶
To create a new bundle that has HTTP support, use the following two commands from the same directory.
Create a minimal bundle with configuration modified for HTTP:
mvn archetype:generate -DinteractiveMode=false -DarchetypeRepository=http://nexus.motechproject.org/content/repositories/releases -DarchetypeGroupId=org.motechproject -DarchetypeArtifactId=minimal-bundle-archetype -DmotechVersion=0.26-SNAPSHOT -DgroupId=org.motechproject -DartifactId=motech-test-module -Dpackage=archetype.test -Dversion=0.1-SNAPSHOT -DbundleName="Archetype Test Module" -Dhttp=true
Note the new parameter:
-Dhttp | true |
Add new source files from the HTTP archetype:
mvn archetype:generate -DinteractiveMode=false -DarchetypeRepository=http://nexus.motechproject.org/content/repositories/releases -DarchetypeGroupId=org.motechproject -DarchetypeArtifactId=http-bundle-archetype -DmotechVersion=0.26-SNAPSHOT -DgroupId=org.motechproject -DartifactId=motech-test-module -Dpackage=archetype.test -Dversion=0.1-SNAPSHOT -DbundleName="Archetype Test Module"
Note the new archetype Id:
-DarchetypeArtifactId | http-bundle-archetype |
Attention
For the names of the new controllers in angular you should add prefix associated with the module so that the name is unique.
Repository Bundle Archetype¶
To create a new bundle that has support for MOTECH's data services
, use the following two commands from the same directory.
Create a minimal bundle with configuration modified for repository:
mvn archetype:generate -DinteractiveMode=false -DarchetypeRepository=http://nexus.motechproject.org/content/repositories/releases -DarchetypeGroupId=org.motechproject -DarchetypeArtifactId=minimal-bundle-archetype -DmotechVersion=0.26-SNAPSHOT -DgroupId=org.motechproject -DartifactId=motech-test-module -Dpackage=archetype.test -Dversion=0.1-SNAPSHOT -DbundleName="Archetype Test Module" -Drepository=true
Add new source files from the repository archetype:
mvn archetype:generate -DinteractiveMode=false -DarchetypeRepository=http://nexus.motechproject.org/content/repositories/releases -DarchetypeGroupId=org.motechproject -DarchetypeArtifactId=repository-bundle-archetype -DmotechVersion=0.26-SNAPSHOT -DgroupId=org.motechproject -DartifactId=motech-test-module -Dpackage=archetype.test -Dversion=0.1-SNAPSHOT -DbundleName="Archetype Test Module"
Settings Bundle Archetype¶
To create a new bundle that has module settings support, use the following two commands from the same directory.
Create a minimal bundle with configuration modified for settings:
mvn archetype:generate -DinteractiveMode=false -DarchetypeRepository=http://nexus.motechproject.org/content/repositories/releases -DarchetypeGroupId=org.motechproject -DarchetypeArtifactId=minimal-bundle-archetype -DmotechVersion=0.26-SNAPSHOT -DgroupId=org.motechproject -DartifactId=motech-test-module -Dpackage=archetype.test -Dversion=0.1-SNAPSHOT -DbundleName="Archetype Test Module" -Dsettings=true
Add new source files from the settings archetype:
mvn archetype:generate -DinteractiveMode=false -DarchetypeRepository=http://nexus.motechproject.org/content/repositories/releases -DarchetypeGroupId=org.motechproject -DarchetypeArtifactId=settings-bundle-archetype -DmotechVersion=0.26-SNAPSHOT -DgroupId=org.motechproject -DartifactId=motech-test-module -Dpackage=archetype.test -Dversion=0.1-SNAPSHOT -DbundleName="Archetype Test Module"
Combined Bundle Archetype¶
The minimal bundle archetype can be supplemented with any combination of additional archetypes. To create a bundle that uses them all, use all the following commands from the same directory.
Create a minimal bundle with configuration modified for all additional archetypes:
mvn archetype:generate -DinteractiveMode=false -DarchetypeRepository=http://nexus.motechproject.org/content/repositories/releases -DarchetypeGroupId=org.motechproject -DarchetypeArtifactId=minimal-bundle-archetype -DmotechVersion=0.26-SNAPSHOT -DgroupId=org.motechproject -DartifactId=motech-test-module -Dpackage=archetype.test -Dversion=0.1-SNAPSHOT -DbundleName="Archetype Test Module" -Dhttp=true -Drepository=true -Dsettings=true
Add source files from all the additional archetypes:
mvn archetype:generate -DinteractiveMode=false -DarchetypeRepository=http://nexus.motechproject.org/content/repositories/releases -DarchetypeGroupId=org.motechproject -DarchetypeArtifactId=http-bundle-archetype -DmotechVersion=0.26-SNAPSHOT -DgroupId=org.motechproject -DartifactId=motech-test-module -Dpackage=archetype.test -Dversion=0.1-SNAPSHOT -DbundleName="Archetype Test Module"
mvn archetype:generate -DinteractiveMode=false -DarchetypeRepository=http://nexus.motechproject.org/content/repositories/releases -DarchetypeGroupId=org.motechproject -DarchetypeArtifactId=repository-bundle-archetype -DmotechVersion=0.26-SNAPSHOT -DgroupId=org.motechproject -DartifactId=motech-test-module -Dpackage=archetype.test -Dversion=0.1-SNAPSHOT -DbundleName="Archetype Test Module"
mvn archetype:generate -DinteractiveMode=false -DarchetypeRepository=http://nexus.motechproject.org/content/repositories/releases -DarchetypeGroupId=org.motechproject -DarchetypeArtifactId=settings-bundle-archetype -DmotechVersion=0.26-SNAPSHOT -DgroupId=org.motechproject -DartifactId=motech-test-module -Dpackage=archetype.test -Dversion=0.1-SNAPSHOT -DbundleName="Archetype Test Module"
Using Archetypes Locally¶
You can also use the archetypes locally, without the Motech Nexus repository. First, you must build the archetypes locally. You can either follow the developer guidelines
to set up your developer environemt, or to build locally without commiting:
git clone https://github.com/motech/motech/
cd motech
mvn clean install
Then you can use the archetypes from your Maven local catalog:
mvn archetype:generate -DinteractiveMode=false -DarchetypeCatalog=local -DarchetypeGroupId=org.motechproject -DarchetypeArtifactId=minimal-bundle-archetype -DmotechVersion=0.26-SNAPSHOT -DgroupId=org.motechproject -DartifactId=motech-test-module -Dpackage=archetype.test -Dversion=0.1-SNAPSHOT -DbundleName="Archetype Test Module"
Note the new parameter:
-DarchetypeCatalog | local |
Developing and Submitting a Patch¶
We use GitHub to manage our source code. MOTECH org members are able to create branches and commit changes to the MOTECH code repositories. Community members utilize the fork and pull GitHub workflow.
Community Member Development Workflow¶
This is the most straightforward way to submit a patch as a community member. Note that GitHub allows you to submit only one pull request per branch at a time. If you wish to work on multiple features at once, it’s best to create a branch for each feature and create a pull request from that branch to our repository.
Fork the MOTECH repository you wish to develop
Clone your fork on your development machine
Add an upstream branch to your fork for easy syncing
Checkout a new feature branch
git checkout -b newfeature
Make changes/test/multiple commits
When ready to submit changes: update master from upstream, squash commits and merge the feature branch
git checkout master git fetch upstream git merge upstream/master #This merge is optional because you can push your local branch to your fork and create a pull request from there git merge --squash newfeature git gui
Edit commit message using the proper commit message format
Push changes
git push origin
Submit a pull request from your fork to the motech repo.
Submitting Changes to Incorporate Review Comments¶
Our team will review your pull request in GitHub. If you received feedback during this process, GitHub allows you to add commits to your pull request. Just commit your changes and the pull request will automatically update.
MOTECH Code Repositories¶
We use GitHub to host our source code. Our core platform is available on the motech repository and our modules are hosted on the modules repository. Use the following comands to clone these repos.
MOTECH Platform¶
The platform repo contains the motech-platform-server Tomcat servlet. In addition it also contains the essential Admin, Config, Tasks, Motech Data Services, Email, and Scheduler modules.
git clone https://github.com/motech/motech
MOTECH Modules¶
This repo is the home of all optional MOTECH modules.
git clone https://github.com/motech/modules
Commit Message Format¶
To ensure that our commit messages are both concise and informative, all MOTECH committers are asked to follow the git commit message format outlined below. For reference, Linus Torvalds provides a description of a good commit message here.
Format¶
- First line is the Jira issue ID + subject (max 50 chars)
- Leave a blank line (if not, the entire message is interpreted as subject)
- Summary (ensure it is wrapped to a reasonable number of characters, e.g. 72, because git log does not handle wrapping).
The description of the change should be both brief and informative. The Linux kernel documentation has this to say about good commit summaries:
...the “summary” must be no more than 70-75 characters, and it must describe both what the patch changes, as well as why the patch might be necessary. It is challenging to be both succinct and descriptive, but that is what a well-written summary should do.
Author/Committer¶
There is no need to include the names of the developers who developed the change in the subject line. If there is more than one person working on a change, the committer is asked to include the –author parameter in his/her git commit to specify the second person’s name.
Example¶
Here is an example of a MOTECH commit message:
MOTECH-678 Moves campaign modules to github
Disables pillreminder, message-campaign and scheduletracking modules from main pom.xml as they’ve moved to a new repo on github - https://github.com/motech/platform-campaigns
Coding Conventions¶
Table of Contents
Introduction¶
Goals¶
The primary goal of the MOTECH coding guidelines is to minimize the cost of maintaining and innovating on code through its lifetime.
Additional goals are:
- Increased developer efficiency when working with code written by others.
- Promoting engineering excellence.
- Compliance with legal and company policies.
- Consistency of the codebase.
There are many guidelines in this document. The decision to introduce a guideline as well as choices between alternative approaches was informed by the following assumptions:
- The benefit of each guideline must significantly surpass the cost of enforcing it.
- During its lifetime, each unit of code is read many more times than it is written or modified. Therefore, the guidelines are optimized for code readability. Cost of writing or modifying code is a secondary consideration.
Many of the following guidelines are adapted from Sun’s Java Coding Conventions document (PDF).
Guideline Presentation¶
The guidelines are organized as simple recommendations using Do, Consider, Avoid, and Do not.
Each guideline describes either a good or bad practice and all have a consistent presentation.
Good practices have a check () in front of them, and bad practices have an ‘x’ (
) in front of them.
The wording of each guideline also indicates how strong the recommendation is.
A Do guideline is one that should be always followed.
On the other hand, Consider guidelines should be generally followed, but if you fully understand the reasoning behind a guideline and have a good reason to not follow it anyway, it is ok to break the rule.
Similarly, Do not guidelines indicate something you should never do.
Less strong, Avoid guidelines, indicate that something is generally not a good idea, but there are known cases where breaking the rule makes sense.
Some more complex guidelines are followed with additional background information, illustrative code samples, and rationale.
Coding Guidelines¶
Naming¶
Class and Interface Names¶
Do use PascalCasing (the first letter of each internal word is capitalized) for interface,
and class names. Class names should be nouns. Keep your class names simple and descriptive. Use whole words — avoid
acronyms and abbreviations. If the abbreviation is much more widely used than the long form, such as URL or HTML,
capitalize only the first letter of the acronym.
class Raster;
class SurveyResults;
class HtmlView;
Service Interfaces & Implementations¶
Do append Impl to the implementations class names and place the implementations in a /impl/ subdirectory. So for example
the Foo service interface should have the following structure:
- /
Foo.java /impl/
FooImpl.java
Method Names¶
Do use camelCasing for method names (the first letter is lowercase, with the first letter of each additional word
capitalized). Methods should be verbs, for example:
run();
runFast();
getBackground();
Variables¶
All instance, class, and class variables are in camelCase. Additional words start with capital letters. Variable names should be short yet meaningful. The choice of a variable name should be mnemonic — that is, designed to indicate to the casual observer the intent of its use. One-character variable names should be avoided with the possible exception of temporary “throwaway” variables, e.g. for loops. Even in these cases, more readable names can be provided (e.g. “surveyIndex” instead of “i”).
Do not use a prefix for member fields or methods (for example do not start your names with: underscore, m, s, etc.)
Do use camelCasing for member variables
Do use camelCasing for parameters
Do use camelCasing for local variables
Do not prefix enums or classes with any letter
Correct:
public class Button
Incorrect:
public class CButton
Do not make local declarations that hide declarations at higher levels. For example, do not declare a previously
occurring variable name in an inner block:
int count;
...
func() {
if (condition) {
int count; // DON'T DO THIS!
...
}
...
}
Do not declare more than one variable per line, even if the language supports it.
Correct:
int startIndex;
int endIndex;
Incorrect:
int startIndex, endIndex;
Do not assign a value to more than one variable per statement, even if the language supports it.
Correct:
int surveyCount = 10;
int farmerCount = 10;
Incorrect:
int surveyCount = farmerCount = 10;
Constants¶
Do name constants with all uppercase words separated by underscores.
int MIN_WIDTH = 4;
int MAX_WIDTH = 999;
Enum Values¶
Do name enum values the same way as constants - all uppercase, with words separated by underscores.
public enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
THURSDAY, FRIDAY, SATURDAY
}
File Names¶
Do not have more than one public type in a source file. Each Java source file contains a single public class
or interface.
Do name the source file with the name of the type it contains. For example, MotechScheduler class
should be in the MotechScheduler.java file.
Do use the same casing when mapping the type name to file name.
File Content¶
Do put package and import statements (in that order) directly following the copyright banner, and prior to the
class definition:
import java.applet.Applet;
import java.util.List;
import java.util.Map;
Do group class members into the following sections in the specified order:
- Static fields
- Instance fields
- Constructors
- Methods
- Inner classes
Do order fields by public, then protected, then private.
Do group methods by related functionality.
Consider organizing overloads from the simplest to the most complex number of parameters (which often
corresponds to complexity of the body).
Do not declare imports not used within the file.
Element ID¶
To allow for easier integation testing of MOTECH-UI, we are using a naming convention for the element IDs of navigational and action based items in the UI. The element IDs should follow the format below, unless there is a clear reason the format shouldn’t be followed.
Do use lowercase names only.
Do replace spaces with dashes.
Do keep names as short as possible, while using full english words.
Do use following pattern:
{module}.{location}.{entity-id}.{error}.{action}
1. Module Module refers to the OSGI bundle or AngularJS module name that the element belongs to.
Do not start name with “motech”.
If the module name starts with “motech” that should be omitted.
Correct:
Incorrect:
2. Location Location refers to where in the interface the html element is located. This location is relative to the module, not with absolute relation to the entire interface. For tasks breadcrumb would be:
3. Entity Id (optional) The entity id refers to a repeating id which is used in lists of links.
Consider using appropriate non-numeric id, in preference to a numeric id.
4. Error (optional) If element is used for error messages use ”.errors.” before action.
5. Action Action should describe what the button, input, or form does. If this is a link it should refer to where the link goes.
Common Conventions for API creation¶
HTTP methods and endpoints¶
Do use the following, general pattern for endpoints:
/{resource}
/{resource}/{path-variable}
Path can take params.
Do use HTTP methods verbs:
- GET for read resource by id or collection.
- PUT to update resource by id.
- DELETE to delete resource by id.
- POST for create new resources and other operations.
Do use plurals in resource names.
Correct:
GET /shoes/<id>
Incorrect:
GET /shoe/<id>
Avoid use verbs in URL if there is equivalent in HTTP methods.
Correct:
DELETE /shoes/<id>
PUT /shoes/<id>
POST /shoes/<id>/sell
Incorrect:
POST /shoes/<id>/delete
PUT /shoes/<id>/update
Avoid use collection words in URL.
Correct:
GET /shoes
Incorrect:
GET /shoe/list
Response codes¶
Do use response codes:
- 200 OK - For successful operation.
- 400 Bad Request - The body or parameters provided in the request are invalid.
- 401 Unauthorized - The caller is not authorized and thus not permitted to execute the operation.
- 403 Forbidden - The user does not have necessary rights to execute the operation.
- 404 Not Found - Either the given entity or the requested object does not exist.
Code Comments¶
Do use code comments to document code whose operation is not self-evident to the professional
developer (e.g. code reviewer). For example, consider commenting:
- Pre-conditions not evident in code, e.g. thread-safety assumptions
- Complex algorithms
- Complex flow of control, e.g. chained asynchronous calls
- Dependencies on global state
- Security considerations
- Return values, e.g. returning either an object or null
- DateTime parameters, are we expecting UTC or local date/times, or is the timezone encapsulated in the DateTime object?
Avoid using comments that repeat self-commenting information found in many code structures. For example,
do not add vacuous comments such as “Constructors”, “Properties”, “Using Statements”. Avoid commenting:
- Type declarations (e.g. method signatures)
- Assertions
- Method overloads
- Well-understood patterns (e.g. enumerators)
Do use Javadoc comments before your public field and method definitions.
/**
* Short one line description.
*
* Longer description. If there were any, it would be
* here.
*
* @param variable Description text text text.
* @return Description text text text.
*/
Do use // commenting style for both single and multi-line prose comments. For example:
// This method assumes synchronization is done by the caller
Byte[] ReadData(Stream stream)
or
// This AsyncResult implementation allows chaining of two
// asynchronous operations. It executes the second operation only
// after the first operation completes.
Avoid leaving unused code in a file, for example by commenting it out. There are occasions when leaving unused
code in a file is useful (for example implementing a single feature over multiple checkins), but this should be rare
and short in duration.
Avoid using #if/#endif commenting style for purposes other than excluding code from the compilation process:
Console.WriteLine(“Hello”);
#if false
Console.WriteLine(“Press to continue...”);
Console.Readline();
#endif
Console.WriteLine(“Finished”);
Syntax¶
Braces¶
Do use braces with if, else, while, do, and dowhile statements.
Do not omit braces, even if the language allows it.
Braces should not be considered optional. Even for single statement blocks, you should use braces. This increases code readability and maintainability.
for (int i = 0; i < 100; i++) {
doSomething(i);
}
The only exception to the rule is braces in case statements. These braces can be omitted as the case and break statements indicate the beginning and the end of the block.
case 0:
doSomething();
break;
Do place opening braces on the same line as their associated statement, with a space before the opening brace.
Do place closing braces in their own line.
Do align the closing brace with its corresponding opening statement.
if (someExpression) {
doSomething();
}
Indents and Tabs¶
Do use 4 consecutive space characters for indents.
Do not use the tab character for indents.
Do indent contents of code blocks.
if (someExpression) {
doSomething();
}
Do indent case blocks even if not using braces.
switch (someExpression) {
case 0:
doSomething();
break;
}
Spacing¶
Do use a single space after a comma between function arguments.
Correct:
read(myChar, 0, 1);
Incorrect:
read(myChar,0,1);
Do not use a space after the parenthesis and function arguments
Correct:
createFoo(myChar, 0, 1)
Incorrect:
createFoo( myChar, 0, 1 )
Do not use spaces between a function name and parenthesis.
Correct:
createFoo()
Incorrect:
createFoo ()
Do not use spaces inside brackets.
Correct:
x = dataArray[TDG:index];
Incorrect:
x = dataArray[TDG: index ];
Do use a single space before flow control statements
Correct:
while (x == y)
Incorrect:
while(x==y)
Do use a single space before and after comparison operators
Correct:
if (x == y)
Incorrect:
if (x==y)
Do use a single space before and after arithmetic operators
Correct:
x = x + y;
Incorrect:
x = x+y;
Do use a single space before and after assignment operations
Correct:
x = y;
Incorrect:
x=y;
Do use a space or newline before and after the conditional operator
Correct:
x = ((p > q) ? y : z);
Incorrect:
x = (p > q)?y:z;
Do use parenthesis around the conditional operator
Correct:
x = (foo ? y : z);
Incorrect:
x = foo ? y : z;
Do use a single space for class derivation
Correct:
class Button extends Control
Do use a single space for variable declarations.
Do not use multiple spaces to try and align variable names separately from their types.
Correct:
int groupSize = 10;
Do use a single blank line in between method definitions.
Page Width¶
Do try to limit the width of your code to 120 characters.
Do Use common sense. If changing an existing file with obvious 80 column formatting keep it that way. If a
particular line will be much more readable but break the width rule, use common sense.
Changing Existing Code¶
Do comply with the ‘when in Rome, do as the Romans do’ principle. When working on an existing file, please limit
your changes to the issue you’re working on so as to not overwhelm the person reviewing your code with unnecessary
changes.
Do feel responsible to fix a really messy file. Making overall changes to a file to make it look good, outside
the needs of your actual change, is an acceptable exception to the preceding rule when dealing with a real mess.
Code Review Workflow and Checklist¶
Principles¶
In general, we aim to have all code reviewed prior to submission, with very few – hopefully rare – exceptions. Please be conscientious about turning around reviews quickly. Investing in good code review karma will pay off when it comes time for you to solicit reviews from your peers.
Exceptions to Code Review Requirement¶
Urgent fix for a build break. Unless the fix is completely trivial, please remember to get a code review after submission.
Workflow¶
- Write code: Follow the development workflow described here to develop code changes and submit a pull request for review
- Choose code reviewers: Add your chosen code reviewers as reviewers to your pull request. For most changes, one reviewer should be sufficient; if your change is complex and/or represents core platform functionality, it is ideal to involve more than one reviewer. If a particular individual has significant expertise in the code you are changing, it’s a good practice to include that person as a revewier. If not, it’s a great practice to choose someone from a different organization to review your code, in order to facilitate cross-pollination of ideas across the project.
- Wait for reviews to come in: Code reviewers should attempt to provide comments within 2 business days – in the case of time-sensitive fixes, reviews should be turned around faster. (TIP: If you aren’t seeing email notifications for code reviews assigned to you, check your junk mail folder.)
- Address feedback: It should be possible to address most code review feedback prior to merging. If changes are non-trivial, create a new pull request and send it out for re-review as described here.
- Track any future work identified: For larger issues that are flagged during code review, discuss with the reviewer whether the feedback should block merging. If not, open a new Jira ticket to track the suggestion for a later code change.
- Merge: Once reviewers have signed off, they’ll merge the pull request. If this is the only feature for that branch, it is best to delete the branch after the code is merged.
Checklist¶
Correctness¶
- Does the code completely and correctly implement the design?
- Does every code change in the submission map to a ticket in Jira?
Maintainability¶
Does the code make sense?
Code reuse
- Are there any blocks of repeated code that could be encapsulated into methods?
- Can the desired functionality be achieved by reusing any existing code?
Does the code comply with the accepted Coding Conventions? (Indentations, varable/method names, bracket style, commenting, etc.)
Error Handling¶
- Are all thrown exceptions handled properly?
- Does the code catch (or throw) general exceptions, e.g. java.lang.Exception?
- If a method could return null, does the caller check for null?
Control Flow and Structure¶
- Are loop termination conditions obvious and invariably achievable?
Test Coverage¶
- Have sufficient unit tests been provided to cover the basic functionality being provided?
- Do unit tests cover all error conditions of a method call?
Documentation¶
- Are the classes properly documented? Do they contain at least a short description of what they do?
- Is the code self-documenting? If its very cryptic what a piece of code does or why, it should either get reworked or properly documented.
- Are documentation changes required? If the change is modifying the API or behavior of already documented components, it should also contain appropriate updates to the documentation.
- Is new documentation required? In case of a new module or new functionality, it should get properly documented.
The documentation should either be included with the change or a ticket for documenting the functionality should exist. If there is no documentation and no ticket on Jira, a ticket for adding the documentation should get created on Jira with “Inbox” set as the fix version. That ticket will get discussed during our weekly review call and scheduled accordingly.
Resources¶
The resources below contain a number of good ideas (and some bad ones). Many of the checklist items above were borrowed from these documents, with some tweaking.
Authoring Documentation¶
This document provides information specific to setting up and authoring Sphinx documentation for MOTECH. The Sphinx Documentation Guide is also a good resource.
Each MOTECH repository contains a docs directory populated with reStructured Text (reST) files. These files are built by Sphinx and hosted at http://readthedocs.org. A Sphinx plugin, called Javasphinx, builds Javadoc for the MOTECH codebase.
Installing Sphinx and Javasphinx¶
If you are working on MOTECH documentation, it is helpful to build the docs locally and review changes in advance of checkin. The steps below will get your environment configured to build Sphinx docs.
Install python utils
sudo apt-get install python-setuptools python-dev python-pip
Install javasphinx and motechjavasphinx
sudo apt-get install libxslt-dev libxml2-dev zlib1g-dev
cd docs
sudo pip install -r requirements.txt
Building Docs¶
ReadTheDocs.org automatically builds Sphinx projects, but it is a good idea to build your documents and make sure they render correctly before you push your changes up to the code repository.
To build Sphinx docs, go to the docs directory and type:
make html
You can then use a web browser to view docs/build/html/index.html and make sure everything looks good.
Authoring and Submitting New Documents¶
To create a new documentation topic, simply create a file with extension .rst under the docs directory. Create a table-of-contents entry for your new doc in the appropriate index.rst file. The reStructuredText Primer is good to have handy as you write your doc.
When your document is ready for review, follow the instructions for creating and submitting a patch to submit it for code review.
Managing External OSGi dependencies¶
OSGi dependencies¶
All MOTECH modules run in a Felix OSGi framework instance embedded within the platform war. Because of this all libraries you make use of in your module should be packaged as actual OSGi bundles. Since everything that is (theoretically) needed to make a library ready for OSGi is adding a few entries in the META-INF/MANIFEST.MF many popular java libraries are already OSGi enabled by default. However this might not be the case for all the libraries you would wish to use. While you are urged to use libraries that are OSGi bundles, it is still possible to use non OSGi compatible libraries. This document will take you through the process of evaluating a given dependency and using it in MOTECH.
Recognizing whether the library is an OSGi bundle¶
First of all you should check whether the library itself is an OSGi dependency. An easy way to do this is to open its jar file using any of the tools that allow browsing zip files (jars are actually zip files after all). After opening the jar, check the META_INF/MANIFEST.MF file for presence of OSGi related entries such as: Bundle-SybmolicName, Bundle-Version, Import-Package, Export-Package, etc. If they are present it means that the library supports OSGi.
Note
Always check the source library for OSGi support before doing anything else, like looking for alternatives or OSGifying it yourself.
Finding an existing OSGi version of the dependency¶
If your dependency is not an OSGi bundle at source, don’t worry, it’s possible that someone has already OSGified the bundle for you. You can search for an OSGified version using Google (or any other search engine). There are however a few particular repositories excelling in providing OSGi versions of common libraries:
- Spring EBR - http://ebr.springsource.com/repository/app/ - while the future is not certain for this project, the
Enterprise Bundle Repository remains a good source of OSGi bundles. This repository is proxied through our Nexus.
- ServiceMix Bundles - http://servicemix.apache.org/developers/source/bundles-source.html - this repository is a good place
to search for existing OSGi compatible versions of popular java libraries. The bundled versions from this repository go to maven central.
- Pax Tipi - https://ops4j1.jira.com/wiki/display/PAXTIPI/Pax+Tipi - OPS4J’s answer to this problem. Pax Tipi is an umbrella project
for third-party artifacts repackaged as OSGi bundles. These OSGi bundles are all available from Maven Central with groupId org.ops4j.pax.tipi.
If none of these resources provide the OSGi version of the library you are looking for, it seems you will have to get your hands dirty and follow the good old principle - if you want something done, do it yourself.
Creating an OSGi-ready version of the dependency¶
Creating an OSGi version of given library is not an awfully complicated process. All you have to do is to create a version with the correct META-INF/MANIFEST.MF file. There are tools that can help you with this and you are not required to have access to the library code in order to accomplish this task. In MOTECH we use the Felix Bundle Plugin for Maven for creating bundles. A dependency to OSGify should be added as a maven module in our External OSGi Bundles repository. Everything you should need to place there is the pom file with the correct configuration for creating the bundle. The following code is an example of such a pom.xml file for creating a bundle from org.example.example-artifact, version 1.0:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<properties>
<example.version>1.0<example.version>
</properties>
<parent>
<groupId>org.motechproject</groupId>
<artifactId>external-osgi-bundles</artifactId>
<version>1.0.8</version>
</parent>
<!-- We prefix the groupId for our bundles with org.motechproject -->
<groupId>org.motechproject.org.example</groupId>
<artifactId>example-artifact</artifactId>
<!-- The release tag property is important. It allows us to update the version of the bundle
without making changes to the base version -->
<version>${example.version}-${release.tag}</version>
<!-- The library we are OSGifying has to be declared as a dependency -->
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>example-artifact</artifactId>
<version>${example.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- This will make Felix scan the library for imports -->
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-sources</id>
<goals>
<goal>unpack</goal>
</goals>
<phase>package</phase>
<configuration>
<outputDirectory>${project.build.directory}/sources</outputDirectory>
<artifactItems>
<artifactItem>
<groupId>org.example</groupId>
<artifactId>example-artifact</artifactId>
<version>${example.version}</version>
<classifier>sources</classifier>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<!-- This configuration will tell the Felix bundle plugin to generate
the bundle for the library. The original library will be embedded in the newly
created bundle jar -->
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.4</version>
<extensions>true</extensions>
<configuration>
<instructions>
<!-- All library packages that are supposed to be exposed must be declared as exports -->
<Export-Package>
org.example;version=${project.version},
org.example.subpackage;version=${project.version}
</Export-Package>
<!-- You can specify additional imports that were not found by Felix -->
<Import-Package>
hidden.import,
*
</Import-Package>
<!-- Bundle metadata for the newly created bundle -->
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Vendor>Example.com</Bundle-Vendor>
<!-- We embed the original library -->
<Embed-Dependency>example-artifact;inline=true</Embed-Dependency>
<Embed-Transitive>true</Embed-Transitive>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>
It is important to note that by adding the release tag to the version of the bundle, we allow ourselves to make updates i.e. add an export we forgot about, without changing the base version. The value of the release tag is in the main pom of the external OSGi bundles repository.
Releasing a new version of external OSGi dependencies¶
For making a release of the external bundles, three steps are required:
Update the version in the parent pom. You can use the following command, where X is the new old number increased by one.
mvn versions:set -DnewVersion=1.0.X
Increment the release tag in the parent pom. For example if its value is r30, change it to r31
Trigger the external-osgi-bundles build on Jenkins, it should trigger automatically when new commits come in
to the repository.
After the repository gets updated, the release tag values defined in parent poms for the MOTECH platform and MOTECH modules must be updated in order to use the new versions.
Note
We would prefer to keep the number of bundles we maintain to a minimum. So please only commit additional bundles when it’s necessary and you are absolutely sure the library is not already an OSGi bundle itself and there are no existing OSGi compatible versions. Also, if you have knowledge that one of the dependencies we maintain was OSGified at source, please let us know, so that we can get rid off the burden of maintaining it. Remember that in an ideal world, the external-osgi-bundles repository would not exist.
Project Management¶
There will be text here.
Release Process¶
MOTECH releases are created roughly quarterly, with some bigger releases taking longer. See the Roadmap for guidance on when to expect the next release.
This page provides step-by-step instructions for creating an official release. Many of these steps require elevated permissions in Gerrit and Jenkins, and are intended to be performed by a member of the release management team.
Create the Release Branch and Associated CI jobs¶
There are two ways to create a release branch and the associated release jobs in our CI:
- Using our handy release script that automates most of the steps
- Manually
Option 1 - Release Script¶
We have a Python script at https://github.com/motech/release that automates all of the steps for branching. It expects the following paramaters:
Required¶
--jenkinsUsername | |
A user in jenkins who has permission to create new jobs | |
--jenkinsPassword | |
The password for the jenkins user | |
--gerritUsername | |
A username in gerrit who is in the Bypass Review group. | |
--version | The version of the release i.e. 0.22 |
--developmentVersion | |
The next development version on the branch i.e. 0.22.1-SNAPSHOT | |
--nextMasterVersion | |
The next working version on master i.e. 0.23-SNAPSHOT |
Optional¶
--buildDirectory | |
The base location to check out all source to. Will delete if it exists. Defaults to ./builds | |
--verbose | Be a little chatty on stdout |
Option 2 - Manual Process¶
Cut and paste the following commands to set your environment variables to the appropriate values:
VERSION={version}
Create branches for the release (one for each repo):
mvn release:branch -!DbranchName=0.$VERSION.X -Dscm.connection=scm:git:git@github.com:motech/motech.git -Dscm.developerConnection=scm:git:git@github.com:motech/motech.git mvn release:branch -!DbranchName=0.$VERSION.X -Dscm.connection=scm:git:git@github.com:motech/modules.git -Dscm.developerConnection=scm:git:git@github.com:motech/modules.git
In the Jenkins UI, create CI jobs for the new branches. List of jobs:
Platform-{VERSION}.X
Modules-{VERSION}.X
The most straightforward way to create the jobs is to copy the config from a previous release. Any other method will be error-prone, as there are many fields to configure, several of which are hidden under “Advanced” sections.
Test the Release Candidate¶
After the release branch has been created, user acceptance testing (UAT) begins. The release management team will make an initial pass over the tickets that were resolved for the release, and close those that are low-priority for UAT. All others should be tested and closed before building the official release. If testing reveals that an issue requires more work, the ticket should be reopened with fixVersion=Inbox so that it can be triaged at the next Inbox Review Meeting. A decision will be made as to whether the issue should be fixed on the release branch or moved to the next release.
Additional release criteria or functional areas for UAT may be added for specific releases, depending on the needs of partners or the desire to stress major new functionality. In future, release criteria will also include API freeze tools passing (API freeze tools aren’t in place yet), documentation requirements, and a code coverage minimum.
Build the Release¶
Once the build has been tested and you are ready to create the official release, you can do so from the Jenkins UI.
- Trigger the platform release build from the platform-{VERSION}.X CI job first.
- Wait and ensure that the platform build completes successfully.
- Trigger the modules release build from the modules-{VERSION}.X CI job.
If Something Goes Wrong...¶
If the release build fails for any reason, it will be necessary to do some cleanup before attempting a retry.
Depending on how far along the build process got before failing, some artifacts may have been uploaded to Nexus. You will need to expand the directories for each bundle and delete these artifacts manually if they exist. Subsequent release attempts will fail if these artifacts aren’t removed.
- Jenkins makes two checkins when preparing the release and preparing for the next development iteration. These will need to be reverted. The commit message subjects will be similar to the following:
[maven-release-plugin] prepare for next development iteration
[maven-release-plugin] prepare release motech-{VERSION}
Push changes to the remote branch via Gerrit using git push origin HEAD:refs/for/{VERSION}.X
- If the tag for the new release was created, it will need to be deleted.
git push –delete origin motech-{VERSION}
After these issues are addressed (and the root cause of the release failure is investigated/fixed), it should be safe to retry the release build.
Release Notes¶
Release notes should be published under the Release Notes section on our documentation site. They should contain pointers to the binaries and source code, a summary of major changes delivered in the new release, and a list of known issues (with workarounds when applicable).
Browser Compatibility¶
Supported Browsers¶
MOTECH project uses new technologies (HTML 5, CSS3) and new frameworks like AngularJS, Bootstrap which means that the compatibility of the browsers depends on the extent to which these frameworks support old browsers.
We officialy support IE11 and up, Chrome, Firefox, Safari and Opera. We don’t support older versions of Internet Explorer due to framework compatibility, as mentioned above.
Screen Resolution¶
Currently we tested MOTECH on screen resolution 1024 x 768 px and higher, but the best results will be achieved using resolution 1680 x 1050 px or higher, especially for wide tables. That means we do not support mobile and tablet devices.
Browser Settings¶
All browsers must have cookies and JavaScript enabled to use MOTECH.
Our approach to maintain compatibility with browsers¶
- Even if we declare the latest HTML 5 in MOTECH, we try not to use the latest tags, if possible.
- Newer versions of browsers provide debugging tools directly or as a plugin. These developer tools also allow you to inspect specific HTML and alter CSS styles.
- We do not use inline JavaScript events inside HTML markup. An example would be <button onclick=”validate()”>Validate</button>. This practice breaks the clean separation that should exist between markup, presentation, and behavior.
Static resources - faster UI development¶
This short manual explains how to enable hot deployment of static files (.js,.css files etc). This will help to view the changes made to the static files without having to redeploy the module/bundle each time a change is made. After following the described steps, static files will be read from specified location on your local machine, rather than from bundle resources.
Details¶
You need to do two things:
- Set environment as development
- For the bundle for which static resources are to be hot deployed, create an environment variable with the “bundle symbolic name” but after replacing all special characters and spaces with underscore; this variable should contain a path to the module resources directory
If you add a new javascript file, you need to deploy the bundle with the new file at least once to register it. Otherwise the script will not be registered on the UI.
Note
By default, the bundle symbolic name is constructed, based on the groupId and artifactId, in the following way: {groupId}.{artifactId}.
Example¶
Let’s assume the following properties of a module:
groupId: | org.motechproject |
artifactId: | sms |
bundle symbolic name: | org.motechproject.sms |
path to resources: | /home/me/modules/sms/src/main/resources |
Set up two environment variables (from the same shell which starts up tomcat). Remember to replace all spaces and special characters with an underscore. Note, that the configuration is case-sensitive.
export ENVIRONMENT=DEVELOPMENT
export org_motechproject_sms=/home/me/modules/sms/src/main/resources
In case you find the changes are not being reflected even after correctly setting up the environment variables, clear browser cache and delete the directory ${tomcat_installation_dir}/work/Catalina/localhost/${motech_dir}/
Hot deployment with Docker container¶
It is also possible to configure hot deployment of static files running MOTECH with the Docker container. To do so, you must make some edits in the fig.yml file.
First of all, you must link your local directory, containing module resources to a volume visible in the Docker container. This can be achieved by adding an appropriate entry in the volumes section of the tomcat configuration. The entry must be in the form of “yourLocalDirectory: virtualDirectoryOnDocker”. This is how exposing your local “/home/you/modules/sms/src/main/resources” directory could look like:
volumes:
- /home/you/modules/sms/src/main/resources:/home/modules/sms/resources
Adding this entry will cause that your local directory will be visible in the Docker container, under the virtual path “home/modules/sms/resources”.
You must also set up the environment variables in your configuration. In your file find tomcat section and then “environment”. Add required entries. The names and values of the environment variables must follow the rules stated above. Note, however, that Docker will only see resources that you have manually exposed as volumes (virtual directories within Docker). It might look like this:
environment:
JAVA_OPTS: -Xms1024m -Xmx2048m -XX:MaxPermSize=1024m
DB_TYPE: mysql
DB_USER: root
DB_PASSWORD: password
DB_DRIVER: com.mysql.jdbc.Driver
ENVIRONMENT: DEVELOPMENT
org_motechproject_sms: home/modules/sms/resources
The variables must be added in the “variableName: variableValue” format. Set environment as development and add paths to the resource directories, for the modules you wish to have hot deployment for.
The complete configuration for the tomcat section in the fig.yml could look like this:
tomcat:
image: motech/tomcat:7.0.53
ports:
- "8080:8080"
- "8000:8000"
links:
- couchdb
- db
- activemq
environment:
JAVA_OPTS: -Xms1024m -Xmx2048m -XX:MaxPermSize=1024m
DB_TYPE: mysql
DB_USER: root
DB_PASSWORD: password
DB_DRIVER: com.mysql.jdbc.Driver
ENVIRONMENT: DEVELOPMENT
org_motechproject_sms: home/modules/sms/resources
volumes:
- /home/you/docker-motech-config:/root/.motech/config
- /home/you/docker-motech-bundles:/root/.motech/bundles
- /home/you/modules/sms/src/main/resources:/home/modules/sms/resources
Deployment¶
Load Balancing with Apache 2 WebServer - Sticky Session¶
Table of Contents
Overview¶
Sticky Session is a method used with Load Balancing, to achieve server affinity. In other words, it assigns a particular client with a particular server instance behind Load Balancer, so that HTTP session doesn’t get lost across application instances. It is essential if we are deploying Motech in a cluster configuration and we want to be able to access its UI. This tutorial describes two methods of setting up Sticky Session feature with Apache Server used for Load Balancing.
Method 1: Using existing session cookie¶
Attention
This method requires Apache Tomcat to be used as instance server.
In this approach you will have to configure both Load Balance Server (LBS) and all Tomcat Instance Servers (IS). For session tracking, we will use existing session cookie - JSESSIONID - and let IS to modify it a bit.
In LBS VirtualHost configuration, you have to provide names for your instances (If you haven’t done so yet). To do so, for each BalancerMembers you have to specify a route parameter:
BalancerMember http://{i'th instance ip:port} route=tomcat_instance_i
where tomcat_instance_i is the i’th instance unique name.
In the same file you have to provide session ID cookie name to LBS under its VirtualHost Proxy definition:
<Proxy balancer://mycluster>
(...)
ProxySet stickysession=JSESSIONID
(...)
</Proxy>
Finally, for each tomcat, you have to edit $CATALINA_HOME/conf/server.xml. In the <Engine> node add jvmRoute attribute which corresponds with BalancerMember route of this particular IS from LBS configuration:
(...)
<Engine name="Catalina" defaultHost="localhost" jvmRoute="tomcat_instance_i">
(...)
After restarting all Instance Servers and Load Balance Server, sticky session should work.
Method 2: Using additional session cookie¶
This approach requires changes only to Load Balance Server (LBS) VirtualHost configuration. For session tracking, a brand new cookie named ROUTEID will be used. It will be managed by LBS, so we need to enable its ability to modify headers (thus cookies). The advantage of this method is that it doesn’t require any Instance Server (IS) configuration, so it potentially can be used with any backend web servers.
Same as in previous method, you have to name your instances:
BalancerMember http://{i'th instance ip:port} route=tomcat_instance_i
Then, ensure that ‘headers’ Apache module is enabled. To enable this module in Ubuntu, you can use following command:
sudo a2enmod headers
Next, you have to tell LBS to store its own cookie (ROUTEID) on client side. That cookie will contain instance name (route):
<VirtualHost *:80>
(...)
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
(...)
</VirtualHost>
Finally, tell LBS the cookie name:
<Proxy balancer://mycluster>
(...)
ProxySet stickysession=ROUTEID
(...)
</Proxy>
After restarting Load Balance Server, sticky session should work.
Using MOTECH with multibyte characters¶
Table of Contents
Overview¶
In most of Tomcat, MySQL and PostgreSQL versions by default ISO-8859-1 character encoding is used. If you want to use multibyte characters like for example polish or chinese letters this tutorial will help you.
MySQL multibyte characters support¶
If you want to add support for a new character set that includes multi-byte characters, you need to add the following lines into my.cnf file:
[client]
default-character-set = utf8
[mysqld]
collation-server = utf8_unicode_ci
init-connect='SET NAMES utf8'
character-set-server = utf8
After settings this, restart the MySQL server.
PostgreSQL multibyte characters support¶
To create a new database with UTF-8 encoding you have to type the following line in terminal:
postgres=# create database motechdata with encoding='UTF-8' lc_collate='en_US.utf8' lc_ctype='en_US.utf8';
However you can encounter the following error:
ERROR: new encoding (UTF8) is incompatible with the encoding of the template database (SQL_ASCII)
It means that you have to change template’s encoding to UTF-8. You can do this like so:
postgres=# update pg_database set datallowconn = TRUE where datname = 'template0';
postgres=# \c template0.
template0=# update pg_database set datistemplate = FALSE where datname = 'template1';
template0=# drop database template1;
template0=# create database template1 with template = template0 encoding = 'UTF8';
template0=# update pg_database set datistemplate = TRUE where datname = 'template1';
template0=# \c template1
template1=# update pg_database set datallowconn = FALSE where datname = 'template0';
After setting this, you can once again type the database creation command.
Tomcat multibyte characters support¶
To support the feature you have to configure the connector in Tomcat’s server.xml like so :
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8"
useBodyEncodingForURI="true"/>
Now if you want to use multibyte characters in a request url properly you can add manually the following header to the request headers:
Content-Type : application/x-www-form-urlencoded; charset=UTF-8
However you can set this globally by adding the following filter in Tomcat’s web.xml, otherwise your controller’s request mapping will not work correctly :
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Using Felix Web Console with MOTECH¶
Table of Contents
Overview¶
MOTECH is built on top of the Felix OSGi Framework. Thanks to this, users can install the Felix Web Console on their installations and then use it for monitoring the server.
Benefits of using the Web Console¶
The Felix Web Console allows viewing details of all bundles installed in the system. It also allows installing and uninstalling modules. Generally speaking the only benefit of using the web console over the MOTECH Admin module is that it gives access to bundles that are not MOTECH modules - for example third party libraries such as Spring. More information on the Web Console can be found in the Web Console Documentation.
Installation¶
The Web Console can be installed by simply downloading it from the Felix Downloads Page into the ~/.motech/bundles directory belonging to the user running MOTECH. The console should become active after starting MOTECH.
Accessing the Console¶
The console should be available after appending module/system/console to your MOTECH server url. The default login is admin/admin. Refer to the Web Console Documentation for ways to change it.
Demos¶
Demo: Hello World¶
Table of Contents
Overview¶
This “Hello World” tutorial aims to get you started with Motech development. The tutorial is separated into two phases. In the first, we generate the Hello World module incrementally from a series of archetypes provided by the Motech platform. We briefly tour the project code, configuration, and layout that make up a minimal Motech module, and then add in additional archetypes to support web requests and data services. Finally, we build and deploy the module to our Motech server.
In the second phase, we introduce an essential feature of the Motech platform: the Event system. The Event system allows our module to communicate with other modules by emitting and listening for events. We also introduce the Tasks module, which allows us to wire up Motech events using a graphical user interface. Finally, we introduce Motech Data Services, which we use to persist entities. Using these tools, we modify the archetype-generated code to save a new record whenever users request a URL defined by our module.
This tutorial assumes you are at least somewhat familiar with Java, Maven, and the Spring Framework, and have completed the instructions to set up your development machine. We use Intellij IDEA 13 Community Edition as the integrated development environment, but this is not a requirement.
This tutorial was written with Motech 0.24.
Generating the Module from Archetypes¶
Motech is a modular system. Modules are units of functionality that encapsulate application-specific business logic in a reusable package. The Open Service Gateway initiative specification (OSGi) provides the framework to describe this modular architecture: each Motech module is also an OSGi bundle. The OSGi host manages the lifecycle of a module (adding, starting, stopping, and removing), and allows a module to expose services for use by other modules.
To mitigate some of the complexity of configuring OSGi bundles, the Motech platform provides a number of Maven archetypes. The archetypes are also modular: each new module begins from the minimal bundle archetype, and additional capabilities–serving web requests, managing data, and more–are enabled by adding their respective archetypes to the minimal bundle’s foundation.
Generating the Minimal Bundle¶
The minimal bundle archetype generates the basic project layout and configuration sufficient to begin module development in Motech. To generate the bundle, open a terminal from the directory you wish to contain the project, then enter the following command:
mvn archetype:generate -DinteractiveMode=false -DarchetypeRepository=http://nexus.motechproject.org/content/repositories/releases -DarchetypeGroupId=org.motechproject -DarchetypeArtifactId=minimal-bundle-archetype -DarchetypeVersion=0.24-SNAPSHOT -DgroupId=org.motechproject -DartifactId=helloworld -Dversion=0.1-SNAPSHOT -DbundleName="Hello World Module" -Dpackage=org.motechproject.helloworld -Dhttp=true -Drepository=true
The flags given with the Maven command instruct Maven to generate a minimal bundle from the 0.24-SNAPSHOT branch of the Motech repository. Once the process completes, the generated project resides in a folder named after the artifact ID, in this case “helloworld.”
Tour of the Minimal Bundle¶
First, import the module into your favorite IDE. If using Intellij IDEA, from the “Welcome to Intellij IDEA” splash screen, select Import Project, navigate to the helloworld folder, and click OK. Select Import project from external model, select Maven, and accept the defaults by clicking “Next” and finally “Finish” through the remaining options.
The minimal bundle archetype generates a standard Maven project layout. In the Java folder, the archetype created a service package under our top level org.motechproject.helloworld package
. Inside the package, the archetype created the interface and implementation of a very simple Spring service. We’ll modify this service later in the tutorial to make it a bit more interesting.
As for configuration, the resources/META-INF directory contains folders for Motech and Spring XML files. In the motech folder, the applicationContext.xml file enables Spring component scanning of our base Java package, and declares details of our module as a ModuleRegistrationData
bean. In the spring folder, the blueprint.xml file exposes our HelloWorldService
as an OSGi service. Since we activated repository support when generating the minimal bundle, the HelloWorldRecordService
is also exposed. This code will be added later in the tutorial, when we add the repository archetype. Similarly, we get an OSGi reference to the HelloWorldRecordsDataService
, also to be added later. Any additional references to Motech platform services will be added to this blueprint file.
Adding the HTTP Archetype¶
Now that we have some perspective on the basic module layout, let’s add the HTTP archetype into the mix. With a terminal open at the same folder you issued the first Maven command, enter the following:
mvn archetype:generate -DinteractiveMode=false -DarchetypeRepository=http://nexus.motechproject.org/content/repositories/releases -DarchetypeGroupId=org.motechproject -DarchetypeArtifactId=http-bundle-archetype -DarchetypeVersion=0.24-SNAPSHOT -DgroupId=org.motechproject -DartifactId=helloworld -Dpackage=org.motechproject.helloworld -Dversion=0.1-SNAPSHOT -DbundleName="Hello World Module"
This archetype pulls in additional dependencies to interact with and integration test Spring web servlets. Returning to the IDE, notice that our top level package now contains an additional subpackage called web, with a simple Spring controller. The controller makes our module a little more interesting by injecting our previously generated HelloWorldService
and providing a URL route to exercise the service’s public API.
The HTTP archetype also creates a webapp folder in the resources directory. This folder contains the module’s static files, including HTML partials, stylesheets, JavaScripts, and internationalized messages. Motech modules use the AngularJS framework to drive the front-end client, so the archetype created the top-level module, controllers, directives, and services necessary for a simple Angular client in the js folder.
Adding the Repository Archetype¶
As the final step in setting up our basic Hello World module, let’s generate the repository archetype code with the following Maven command:
mvn archetype:generate -DinteractiveMode=false -DarchetypeRepository=http://nexus.motechproject.org/content/repositories/releases -DarchetypeGroupId=org.motechproject -DarchetypeArtifactId=repository-bundle-archetype -DarchetypeVersion=0.24-SNAPSHOT -DgroupId=org.motechproject -DartifactId=helloworld -Dpackage=org.motechproject.helloworld -Dversion=0.1-SNAPSHOT -DbundleName="Hello World Module"
The repository archetype created two new packages, domain
and repository
, which contain a simple data model and repository service, respectively. In addition, the archetype added an interface and implementation to the service package, so we can interact with the data layer.
Taking a closer look at the domain and repository packages, the HelloWorldRecord
is a typical Java bean that models a record with name and message fields. The class-level @Entity
annotation identifies the record as a data type to be managed and persisted by the core Motech Data Services (MDS) module. The MDS @Field
annotations provide object-relational mappings between the bean’s fields and columns in the database. The HelloWorldRecordsDataService
interface extends the base MotechDataService
interface, inheriting functionality to provide basic CRUD operations for our HelloWorldRecord
objects. Using the MDS @Lookup
annotation, we provide a custom method by which to find a HelloWorldRecord
, in this case by name. Additional custom lookups can be defined here.
In the service package, the HelloWorldRecordService
injects the data service and exposes a public interface by which to retrieve and persist records.
Building and Deploying the Module¶
To build the project in Maven, create a new run configuration in Intellij by clicking Run -> Edit Configurations.... Click the green plus sign to add a new configuration, and select Maven. Name the configuration “Maven clean install”, enter “clean install” in the command line field, and click OK. Finally, click the Run button in the upper right hand corner to package the module.
Alternatively, from the command line, change directory to the helloworld module’s folder and type “mvn clean install”.
Once the build succeeds, the project directory will contain our module packaged as a jar in the /target subfolder. With your Tomcat server running, open a browser and navigate to http://localhost:8080/motech-platform-server/, then log in with your administrator credentials. Click the Admin tab, then click Manage Modules from the sidebar navigation. In the dropdown labeled Install module from, choose File, then click the Select File and choose our packaged helloworld-0.1-SNAPSHOT.jar. Click the Start on Install button to toggle the icon to a check mark, and then finally click Install or Update.
If all goes well, our Hello World Module should appear alongside the other installed modules in the user interface. The state should be “Active.”
As a small test of our web controller, navigate your browser to http://localhost:8080/motech-platform-server/module/helloworld/sayHello. The controller should respond with the JSON string {"message":"Hello World"}
.
An Event-Driven Hello World¶
In this second phase of the tutorial, we implement a feature that creates a new record whenever a user requests the sayHello
URL route defined by our module. To accomplish this, we emit an event when the URL is accessed, listen for an event instructing our module to create a new record, and finally wire these two separate events together using the Tasks module.
Declaring the Event System Dependency¶
To include events in our module, we first need to declare the dependency on the event system in our pom.xml file. Between the <dependencies>
opening and closing tags, add the following:
<dependency>
<groupId>org.motechproject</groupId>
<artifactId>motech-platform-event</artifactId>
<version>${motech.version}</version>
</dependency>
Secondly, our module will hook into Motech’s Event Relay, so we need to add a reference to the relay alongside our other OSGi configuration in blueprint.xml:
<osgi:reference id="eventRelayOsgi" cardinality="0..1" interface="org.motechproject.event.listener.EventRelay" />
With these dependencies, we are now able to inject the event relay into our own code, send events, and define event listeners.
Event Subjects and Event Parameters¶
Motech events are identified by a String value called the subject. To encapsulate these values as constant values, let’s create an event package under our main module package to contain the following class:
package org.motechproject.helloworld.event;
public final class HelloWorldEventSubjects {
public static final String SEND_HELLO = "helloworld_hello_event";
public static final String CREATE_HELLO_RECORD = "helloworld_create_hello_record";
private HelloWorldEventSubjects() {}
}
Similarly, each event can be supplied with parameters, represented by a map of key-value pairs in which the keys are also constant String values. This class encapsulates those values:
package org.motechproject.helloworld.event;
public final class HelloWorldEventParams {
public static final String NAME = "name";
public static final String MESSAGE = "message";
private HelloWorldEventParams() {}
}
Finally, let’s create a helper class to simplify packaging our parameters together into a functional Motech event:
package org.motechproject.helloworld.event;
import org.motechproject.event.MotechEvent;
import java.util.HashMap;
import java.util.Map;
public final class HelloWorldEvents {
public static MotechEvent sendHelloWorldEvent(String name, String message) {
Map<String, Object> params = new HashMap<>();
params.put(HelloWorldEventParams.NAME, name);
params.put(HelloWorldEventParams.MESSAGE, message);
return new MotechEvent(HelloWorldEventSubjects.SEND_HELLO, params);
}
private HelloWorldEvents() {}
}
Given a name and a message, our static helper method will bundle up the parameters and return a Motech event, which in turn will be passed to the event relay.
Sending an Event¶
To send our event, let’s modify our implementation of the HelloWorldService
to send events whenever the sayHello
method is called:
package org.motechproject.helloworld.service.impl;
import org.motechproject.event.listener.EventRelay;
import org.motechproject.helloworld.event.HelloWorldEvents;
import org.motechproject.helloworld.service.HelloWorldService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("helloWorldService")
public class HelloWorldServiceImpl implements HelloWorldService {
@Autowired
private EventRelay eventRelay;
@Override
public String sayHello() {
eventRelay.sendEventMessage(HelloWorldEvents.sendHelloWorldEvent("HWEvent", "Hello world!"));
return "Hello World";
}
}
In the HelloWorldServiceImpl
listing, we declare a private field to contain a reference to the Event Relay. Annotating the field with Spring’s @Autowired
annotation injects the dependency we declared earlier in the blueprint.xml configuration file. Then, in the body of the sayHello
method, prior to the return statement, we use the event relay’s sendEventMessage
method to send our Motech event.
And that’s it! Any Motech module that defines a listener for our SEND_HELLO
subject can inspect our event and its parameters.
Listening for Events¶
In our Hello World module, we provide a data service layer to create HelloWorldRecord
instances, but currently do not make use of it. Rather than keep that functionality to ourselves, let’s define an event listener that allows other modules to send us requests to create new records. First, create a new subpackage to the event package called handler, then add the following class:
package org.motechproject.helloworld.event.handler;
import org.motechproject.event.MotechEvent;
import org.motechproject.event.listener.annotations.MotechListener;
import org.motechproject.helloworld.domain.HelloWorldRecord;
import org.motechproject.helloworld.event.HelloWorldEventParams;
import org.motechproject.helloworld.event.HelloWorldEventSubjects;
import org.motechproject.helloworld.service.HelloWorldRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class HelloWorldEventHandler {
@Autowired
private HelloWorldRecordService helloWorldRecordService;
@MotechListener(subjects = {HelloWorldEventSubjects.CREATE_HELLO_RECORD})
public void handleCreateHelloEvents(MotechEvent event) {
String name = (String)event.getParameters().get(HelloWorldEventParams.NAME);
String message = (String)event.getParameters().get(HelloWorldEventParams.MESSAGE);
HelloWorldRecord record = new HelloWorldRecord(name, message);
helloWorldRecordService.add(record);
}
}
In our event handling class, the @MotechListener
annotation does the work of transforming a standard Java method into an event-handling method. Using the annotation’s subjects element, we declare our interest in receiving CREATE_HELLO_RECORD
events. Our event-handling method accepts the MotechEvent
as an argument, extracts the name and message parameters, creates a new HelloWorldRecord
, and finally uses the injected data service to persist the new record.
Since we are listening for a different event than the one we emit, there is no interaction between our module’s event-emitting functionality and event-listening functionality. In the next section, we look at a way to integrate these two systems with the Tasks module’s graphical user interface.
Task Triggers and Task Actions¶
The Tasks module allows implementers to define interactions between modules through a graphical user interface. A Task consists of a trigger and an action. A trigger is a standard Motech event that has been exposed to the Task module. An action is an event for which the implementer’s module provides a listener. Between the trigger and action, an implementer can add filters to control whether a task should run based on conditional logic. Also, tasks may use data loaders to query Motech Data Services for additional information.
In the listings that follow, we will declare a Task channel for our module in the form of a JSON document. We will expose our SEND_HELLO
event as a task trigger, declare our CREATE_HELLO_RECORD
event as a Task action, and then link the two in Motech’s GUI.
First, create a new file called task-channel.json in our module’s main/resources directory. Each Task channel must define a display name, a module name, and a module version as JSON properties. A Task channel may provide a list of triggers, identified by the triggerTaskEvents
property. Each trigger must define a display name and event subject, and may provide a list of parameters passed with the event, in which case each event has an event key and a display name. Similarly, a Task channel may provide a list of Task actions, identified by the actionTaskEvents
property. Like triggers, each action must provide a display name and an event subject, and an optional list of parameters identified by key and display name:
{
"displayName": "helloworld.task.channel.name",
"moduleName": "${project.artifactId}",
"moduleVersion": "${parsedVersion.osgiVersion}",
"triggerTaskEvents" : [
{
"displayName" : "helloworld.task.trigger.send_hello.name",
"subject" : "helloworld_hello_event",
"eventParameters" : [
{
"eventKey" : "name",
"displayName" : "helloworld.task.trigger.send_hello.param.name"
},
{
"eventKey" : "message",
"displayName" : "helloworld.task.trigger.send_hello.param.message"
}
]
}
],
"actionTaskEvents" : [
{
"displayName" : "helloworld.task.action.create_hello_record.name",
"subject" : "helloworld_create_hello_record",
"actionParameters" : [
{
"key" : "name",
"displayName" : "helloworld.task.action.create_hello_record.param.name"
},
{
"key" : "message",
"displayName" : "helloworld.task.action.create_hello_record.param.message"
}
]
}
]
}
In the listing above, the subjects for the trigger and action are the hard-coded String constants we defined in our HelloWorldEventSubjects
class. Since our HelloWorldRecord
provides fields for name and message, we pass that data as parameters on the trigger, and accept that data as parameters of the action.
Throughout the JSON listing, the values we provide as display names are not String literals, but rather references to Strings in our message properties files. To provide the String literals for the references above, open our main/resources/webapp/messages/messages.properties file and append the following:
#Tasks
helloworld.task.channel.name=Hello World
helloworld.task.trigger.send_hello.name=Hello World
helloworld.task.trigger.send_hello.param.name=Name
helloworld.task.trigger.send_hello.param.message=Message
helloworld.task.action.create_hello_record.name=Create Hello World Record
helloworld.task.action.create_hello_record.param.name=Name
helloworld.task.action.create_hello_record.param.message=Message
Now, all of the components of our task channel will display correct English values in Motech’s graphical user interface. Before we turn to the user interface, let’s rebuild the module with mvn clean install and install our module in the Admin -> Manage Modules user interface, as we did when touring the minimal bundle.
Creating a Task in the User Interface¶
Once the module has been updated, we’ll create the relationship between task trigger and action in the Motech user interface. Navigate to the Tasks interface by clicking Modules -> Tasks. Click the New Task button and enter “Create Hello Record” in the Task Name field. Our module appears in the Trigger dropdown with the default module icon, a clipboard. Click on the icon, and select Hello World from the available triggers.
New buttons will appear allowing us to add filters, data sources, and actions. Click the Add action button, then, from the Channel dropdown menu, select our Hello World module. Click the Action dropdown menu, and select the Create Hello World Record action that we defined as part of our Task channel.
Finally, notice that the fields we declared as parameters of our Task trigger appear as draggable elements in the Available Fields list. Also notice that our Task action allows us to enter a name and message as text in two form input fields. To complete the association between the trigger and action parameters, drag the Name element to the Name input field, and the Message element to the Message input field. Once the form fields are populated, click the Save & Enable button to activate our new task.
Final Walkthrough¶
To review, in the Event-driven Hello World section of the tutorial, we added the Motech event system to our module. We defined two event subjects: a SEND_HELLO
event that our module emits to other modules in the system, and a CREATE_HELLO_RECORD
event to which our module listens for and responds. Our module emits the SEND_HELLO
event whenever the HelloWorldService’s sayHello
method is called (in this case, when a user loads the /sayHello route as defined by the HelloWorldController
). Using the Tasks module’s user interface, we defined a task linking the SEND_HELLO
and CREATE_HELLO_RECORD
events as a task trigger and task action, respectively. Our HelloWorldEventHandler
listens for CREATE_HELLO_RECORD
and adds new :code:`HelloWorldRecord`instances to our Motech Data Services repository.
To verify that we implemented our feature correctly, load http://localhost:8080/motech-platform-server/module/helloworld/sayHello in your browser. The response sent to the browser remains the same. To check for the new record, click Modules -> Data Services in the Motech user interface. Select the Data Browser tab, then click on the HelloWorldRecord
under the heading for our Hello World module. In the list of record instances that appear, we should find a record with the name “HWEvent” and the message “Hello world!”
IVR Demos¶
First of all, just in case you didn’t know, IVR (or Interactive Voice Response) is a system that enables computers to interact with humans using a phone. The computer interacts with the human using pre-recorded or synthesized messages and the human either speaks back or uses her phone keypad (also called DTMF) to interact with the computer.
Initial Setup¶
In addition to the Motech platform, and the IVR module, you’ll also need to build and/or install the SMS Module.
Server Settings¶
Also be sure that the
server.url
property is properly set to your server’s URL and that your server is publicly reachable from the internet. If your server’s config source is file based, locate themotech-settings.properties
file and make sure theserver.url
is set. If your server’s config is done through the UI, the navigate to Admin / Settings and set theserver.url
property there.So, for example, if your server’s public address was
zebra.motechcloud.org
and it was accessible on port 8080, then you should see:server.url=http://zebra.motechcloud.org:8080/motech-platform-serverConfirm the setting (or set it [#]) by clicking Admin / Settings:
SMS Module Config¶
For the demos that have you send or receive SMS, you need a valid SMS config. You’ll need to establish an account with an SMS provider and then configure the SMS Module accordingly. In these demos we’re using Plivo. To confirm your SMS Settings, click Modules / SMS / Settings:
![]()
If, in addition to sending, you’re going to be receiving SMS, you must also tell your SMS provider what to do when they receive an SMS. There typically will be some way of setting that up on their website. They probably need a URL to send an HTTP request to. This is where you give them the address of your Motech server. So if your server is accessible on the web at
http://zebra.motechcloud.org:8080
the complete URL you would provide your SMS provider would behttp://zebra.motechcloud.org:8080/motech-platform-server/module/sms/incoming/plivo
whereplivo
is the name of the SMS Config you created for that SMS provider.
The Demos, Finally...¶
There are three IVR demos:
Generic VXML IVR Provider Demo: Receiving Calls¶
You accept phone calls, prompt for and record a code, and then send the code in an SMS to the caller.
In more details:
- You call the IVR provider [1].
- The IVR provider calls Motech [2] to request the
hello
VXML template which will tell it what to do. This demo uses VXML but, depending on the provider, it could also be CCXML or some proprietary language.- Motech returns the requested
hello
VXML template.- The IVR provider executes the instructions in
hello
which prompt the caller to type in a number.- The caller (that’s you!) types in a number.
- The IVR provider sends the number to Motech along with a request for the
thankyou
template.- Motech receives the number you typed, sends a Motech Event, and returns the requested
thankyou
template.- The IVR provider executes the instructions in
thankyou
: say ‘Thank you’ and hang up.- Meanwhile, on the Motech side, the Tasks module was waiting for a [we received a template request and the value of the
callStatus
parameter is ANSWERED] [3] Motech Event. When it finally receives it, it extracts the number you typed, creates a ‘You chose x‘ message and sends an SMS [4] to the number that originated the call, which it also receives as a standard parameter from the IVR provider.- You receive ‘You picked x‘ SMS. Nifty, eh?
[1] IVR providers will typically give you a phone number you can use to call your application on their system. They also will require that you give them a publicly accessible URL so they cal request the VXML that you want to be executed when a call is received at this number.
[2] More precisely makes a REST call to the IVR module at the /template
HTTP endpoint.
[3] To differentiate it from other template requests.
[4] From the SMS provider you configured. IVR Settings¶
We need to create an IVR Config so the IVR module knows what to do when it receives HTTP requests from IVR providers. Click on Modules / IVR / Settings:
![]()
Note
Because we’re using the Voxeo IVR provider we named our config voxeo. The name isn’t important, but it’s a good idea to use a simple one as it’ll be part of the URL you’ll provide your IVR provider so it knows where to get the VXML.
A little VXML¶
Here’s the
hello
VXML template:<?xml version="1.0" encoding="UTF-8"?> <vxml version = "2.1"> <form id="enterCode"> <field name="code" type="digits?minlength=1;maxlength=1"> <prompt> Hello! Please pick a number between 0 and 9. </prompt> </field> <filled> <prompt> You picked <value expr="code" />. </prompt> <assign name="from" expr="session.callerid" /> <assign name="providerCallId" expr="session.sessionid" /> <assign name="callStatus" expr="'ANSWERED'" /> <submit name="sendCode" next="http://zebra.motechproject.org:8080/motech-platform-server/module/ivr/template/voxeo/thankyou" namelist="code from providerCallId callStatus" method="get" /> </filled> </form> </vxml>Note
The selected number is passed as one of query parameters (
code
) the IVR provider sends along with its request for thethankyou
template.And the
thankyou
VXML template, which simply says ‘Thank you’ and hangs up:<?xml version="1.0" encoding="UTF-8"?> <vxml version = "2.1" > <form> <block> <prompt> Thank you </prompt> </block> </form> </vxml>Creating the Templates¶
Creating the Task¶
We need to create a task where the trigger is an IVR template request where the call status is
ANSWERED
and the action is to send an SMS to the original caller with the code she entered in the message:![]()
Note
code is extracted from the Motech event payload with
{{trigger.provider_extra_data.code}}
Note
A +1 is added to the SMS recipient because our sample SMS provider, Plivo, needs it.
Et Voila!¶
Now call your application at the phone number that your IVR provider gave you, then listen to the “Hello! Please pick a number between 0 and 9.” prompt, type in a number (say 8). The IVR system will say “You picked 8. Thank you”, then the call will disconnect and soon enough you should receive an SMS:
![]()
Did it work?¶
In addition to the obvious sign that you’re receiving an SMS from your SMS provider, there are other ways you can check your application works.
You can look at the Tasks module’s Recent task activity list to see if your task was executed:
Or you can look at your task’s history:
You can also browse the IVR CallDetailRecord entity in the database using the MDS Data Browser:
Yet another way to see how your application would be to be to look at the SMS log or, for even more details, the Server Log.
Generic VXML IVR Provider Demo: Making Calls¶
Upon receiving an SMS, call the sender back and speak the content of the SMS.
The details:
- You send an SMS to the number provided to you by your SMS provider [1].
- The SMS module receives a
/incoming
HTTP request from the SMS provider and sends a correspondinginbound_sms
Motech Event.- The Tasks module listens to the
inbound_sms
Motech event and triggers [2] an outbound IVR call, passing the text of the SMS as a parameter namedmessage
.- Your IVR provider receives the outbound call request.
- Your IVR provider then asks Motech for the VXML template [3], executes the VXML.
- You receive a phone call, pick up, hear the IVR computer voice speak the content of your SMS.
[1] You must also tell your SMS provider what to do when they receive an SMS, remember?
[2] By issuing an HTTP request to an URL provided by your IVR provider.
[3] At the URI you told your provider to find the VXML for outgoing calls from your number. Creating a Config¶
In order for the IVR provider to initiate a call, we need to create a Config, click Modules / IVR / Settings:
![]()
Note
We named ours voxeo. Note that it’s a bit different than the one we created in the incoming-calls demo, we need to tell the IVR module how to reach the IVR provider by settings the
outgoingCallUriTemplate
andoutgoingCallMethod
properties.The VXML¶
We need a simple VXML script that will say something that was passed to the IVR provider via the outgoing call initiation HTTP request:
<?xml version="1.0" encoding="UTF-8"?> <vxml version = "2.1" > <form> <block> <prompt> <value expr="session.connection.ccxml.values.message" /> </prompt> </block> </form> </vxml>Note
session.connection.ccxml.values.message
implies Motech will have to add a parameter namedmessage
to the HTTP request querystring to the IVR provider.We’ll name this template
say
:![]()
Gluing things together with the Tasks module¶
Drum roll...¶
Notes¶
As in the previous example, you can check the Recent tasks activity pane on the Tasks module, or check the SMS or the IVR log to see what happened.
It’s important to note that this very crude & simple demo does not deal with call status, so the IVR CallDetailRecord log will not be very useful.
Proprietary IVR Provider Demo: KooKoo¶
Introduction¶
KooKoo is a popular IVR provider from India. They are not a standard CCXML/VXML provider, but instead offer a language that’s somewhat similar to a very simplified version of VXML, named KooKoo Tunes.
This demo is similar to the Incoming SMS Demo but uses KooKoo’s simplified XML language instead of standard VXML. We’ll only explain the IVR specific parts here, to create the full demo that sends you an SMS, please see the demo.
Initial Setup¶
You’ll need to setup a KooKoo account.IVR Config¶
In this demo we’re only receiving calls (to the phone number provided to us by KooKoo) so we only need create a minimal config, click Modules / IVR:
![]()
Note
We’re mapping three of the parameters sent back to Motech by KooKoo:
sid
will be mapped toprovider_call_id
,cid
will be mapped tofrom
(the number of the phone placing the call) andcalled_number
will be mapped toto
(the number of the phone receiving the phone, in this case the number assigned to you by KooKoo)Two KooKoo Tunes¶
The funny people at KooKoo call an XML file a “Tune”. We’re creating two by going to Modules / IVR and clicking on + Add Template. The first one says “Hello from KooKoo, please type a number from 0 to 9” and then sends the response back in a
data
parameter and requests the next thing to do fromgoodbye
template:<?xml version="1.0" encoding="UTF-8"?> <Response> <playtext>Hello from KooKoo</playtext> <collectdtmf l="1"> <playtext>Please type a number from 0 to 9</playtext> </collectdtmf> <gotourl>http://yourserver.com/motech-platform-server/module/ivr/template/kookoo/goodbye</gotourl> </Response>Name it helloworld and copy/paste the XML above in the value text area:
![]()
The
goodbye
template simply says “Thank you” and hangs up:<?xml version="1.0" encoding="UTF-8"?> <response> <playtext>Thank you</playtext> <hangup></hangup> </response>The first script sends an additional query parameter named
data
containing the key pressed during the call to Motech. Sincedata
is not a standard property, it will be added to theCallDetailRecord
‘sproviderExtraData
map property. Actually KooKoo sends yet another query parameter namedevent
with the valueGotDTMF
, we’ll useevent
to filter the callback from KooKoo such that we pick the one which contains thedata
parameter.Let’s Create a Task¶
We need to create a task where the trigger is an IVR template request and where the event key in the
providerExtraData
map field is equal toGotDTMF
. We also want the action to send an SMS to the original caller with the code she entered in the message:![]()
Note
The filter source is partially obscured, here it is in full:
{{trigger.provider_extra_data.event}}
Note
data (the parameter containing the key pressed, remember?) is extracted from the Motech event payload with
{{trigger.provider_extra_data.data}}
Et Voila!¶
Now call your application at the phone number that KooKoo gave you, then listen to the lady [1] say ‘Hello from KooKoo, please type a number from 0 to 9’, type in a number (say 4). She’ll say ‘Thank you’ and will hang up. Soon enough you should receive an SMS with the following message: ‘You chose 4’.
[1] The default might not be a lady’s voice on your IVR provider, it was on mine.
Demo: Modeling a New System with MOTECH Data Services¶
MOTECH Data Services (MDS) is a user-configurable data store, that allows a MOTECH admin or developer to define the objects that are relevant for her application. To illustrate the use of MDS, we’ll build out the data model for a simple electronic medical records (EMR) system stored in MOTECH. This tutorial will describe two different methods for defining the data model:
Both demos will define a simple EMR with the following entities:
- Person - contains basic demographic information (name, gender, DOB) about a person in the EMR.
- Patient - represents a patient; has a 1:1 relationship to a Person object.
- Provider - represents a health care provider (nurse, physician, community health worker); has a 1:1 relationship to a Person object.
- Facility - represents a clinic or other health care facility.
- Observation - represents an observation made by a provider about a specific patient; consists of a concept (question) and a value
- Concept - an individual data point or question collected from patients (e.g. blood type or eye color). OpenMRS provides detailed documentation for their concept dictionary; we’ll develop only a very limited version of it for this demo.
- Encounter - represents a provider’s encounter with a patient, and has a 1:n relationship with the Observation entity.
These entities are inspired by (but represent only a small subset of) the domain model of OpenMRS. MOTECH’s OpenMRS module implements a similar domain model. In our simplified model, the relationships among these entities can be represented by the following diagram:
Demo: MOTECH Data Services Bulk Import¶
As of MOTECH 0.25, it is now possible to bulk import MDS entity instances in CSV format. This short tutorial describes the process. For this tutorial, we’ll use the CMS Lite module, which has a simple data model and represents a real-world use case where bulk upload is useful.
First let’s take a look at CMS Lite in the data browser, in particular the StringContent entity. StringContent has four user-supplied fields: value, language, name, and metadata (a key-value map). The former three fields are required.
Now let’s create a CSV file that defines a few entities for bulk import. You may use your text editor of choice, although for large data sets it’s going to be easiest to use a spreadsheet tool like LibreOffice or MS Excel. Here’s a sample with a header row and four entities:
value,language,name,metadata
Ciao,Italian,hello,A:1
Bonjour,French,hello,B:2
Hola,Spanish,hello,D:4
Goodbye,English,goodbye,E:5
Note that it’s not necessary to set many of the entity’s fields in your CSV file (e.g. owner, creationDate, createdBy, modifiedBy, etc.); these will be set by the system. If you include the id field and it matches an existing entity’s ID, the import will be handled as an update to the existing row.
Save the file in .csv format, and you’re ready to go. Now let’s upload the file. In the MDS Data Browser, navigate once again to StringContent, and click on Import CSV:
Browse to the location of your saved CSV file and select it. Et voila, your new entities will appear in the data browser:
Running MOTECH with different database names¶
Table of Contents
Background¶
One of our partners requested a tutorial on running MOTECH with different database names so they can run multiple MOTECH instances in Docker containers pointing to a single SQL database. MOTECH is not setup to run as a multi-tenant SaaS system. That is, we assume one MOTECH instance maps to one information owner. This architecture was chosen to retain a separation of information and access to serve multiple customers.
We created the capability to modify database names in MOTECH v0.28. This tutorial identifies the files and steps involved in changing the database names on Ubuntu 14.04. To be clear, MOTECH doesn’t have the capability to create the database names before bootstrap, so we will proceed in the following three parts:
- Part 1: Setup and run a MOTECH default instance, configure it as you see fit
- Part 2: Copy the databases and .motech/config folder to create your default system backup
- Part 3: Modify the database names and deploy the new configuration
Part 1¶
The first step is to follow the :doc: implementer’s setup guide to create your default instance. You don’t need to install any modules, but you’ll need to make sure you complete the following steps: - When you complete the bootstrap form make sure to choose Configuration Mode: File - After you click the verify button, you’ll get an error about the web security activator not being able to start. That’s because we need to modify some of the properties for file based configuration. Follow these steps to get everything configured correctly:
#Stop the tomcat7 server
sudo service tomcat7 stop
#Create a file called motech-settings.properties that has the configuration variables
echo -e "system.language=en\nlogin.mode=repository" | sudo tee --append /usr/share/tomcat7/.motech/config/motech-settings.properties
#Change the file permissions to tomcat7:tomcat7
sudo chown tomcat7:tomcat7 /usr/share/tomcat7/.motech/config/motech-settings.properties
#Start tomcat7
sudo service tomcat7 start
Next, login to the website, create a user and login to MOTECH.
Now, you have the following items that we’re interested in working with: - a .motech folder in the /usr/share/tomcat7/ directory - 3 SQL databases named motechquartz, motechschema and motechdata
The .motech directory contains all of the configuration files in the .motech/config directory. We will modify files in this directory. We will also export these SQL databases, change the names and import them to the SQL server in the next parts.
Part 2¶
We now have a running instance of MOTECH on our machine. During this part, we will stop the Tomcat server, copy the appropriate files and create our default configuration folder.
#Stop the tomcat7 server
sudo service tomcat7 stop
#Make a directory to hold the default config files and SQL dumps
mkdir default_config
cd default_config
#Copy the .motech directory to the default_config folder
cp -R /usr/share/tomcat7/.motech .
#Remove the mds_entities.jar bundle (this is created each time MOTECH is run by MDS)
rm /usr/share/tomcat7/.motech/bundles/mds-entities.jar
#Perform the SQL Dump
#MySQL Commands
mysqldump -u {ENTER YOUR MYSQL USERNAME HERE} -p motechdata > motechdata.sql
mysqldump -u {ENTER YOUR MYSQL USERNAME HERE} -p motechquartz > motechquartz.sql
mysqldump -u {ENTER YOUR MYSQL USERNAME HERE} -p motechschema > motechschema.sql
#PostgreSQL Commands (note that this assumes the present user has access)
sudo -u postgres pg_dump motechdata > motechdata.sql
sudo -u postgres pg_dump motechquartz > motechquartz.sql
sudo -u postgres pg_dump motechschema > motechschema.sql
Now, we have copy of the default .motech directory and a copy of all three databases. Proceed to the next part to change the configuration files and setup the databases.
Part 3¶
Now it’s time to change the configuration files, upload the SQL databases and start MOTECH with the new database names. The first step is to copy the default configuration .motech folder to the appropriate location /usr/share/tomcat7/.motech. This could be in a docker container or in another user.
Here’s a basic structure of the .motech/config folder:
- bootstrap.properties - This file contains all of the bootstrap properties
- datanucleus_data.properties - need to change - This file contains the database settings for the ‘data’ database
- datanucleus_schema.properties - need to change - This file contains the database settings for the ‘schema’ database
- flyway_data.properties - This file contains flyway migration settings for the ‘data’ database
- flyway_schema.properties - This file contains flyway migration settings for the ‘schema’ database
- log4j.properties - This file contains logger settings
- motech-settings.properties - You created this file and it contains MOTECH system settings
- org.motechproject.motech-platform-email/ - This directory contains email settings
- org.motechproject.motech-platform-web-security/ - This directory contains web-security settings
- org.motechproject.motech-scheduler/ - need to change - This directory contains settings for the quartz scheduler
As you can see, we need to change three files. As we change these files, we’re going to change the word motech to ‘node1’ in each database for easy identification. So, motechdata will become node1data, motechquartz will become node1quartz and motechschema will become node1schema.
File 1: datanucleus_data.properties¶
#Open the file
nano /usr/share/tomcat7/.motech/config/datanucleus_data.properties
#Look for the following line:
#javax.jdo.option.ConnectionURL=${sql.url}motechdata
#Change the 'motechdata' to 'node1data' and save the file
File 2: datanucleus_schema.properties¶
#Open the file
nano /usr/share/tomcat7/.motech/config/datanucleus_schema.properties
#Look for the following line:
#javax.jdo.option.ConnectionURL=${sql.url}motechschema
#Change the 'motechschema' to 'node1schema' and save the file
File 3: org.motechproject.motech-scheduler/quartz.properties¶
#Open the file
nano /usr/share/tomcat7/.motech/config/org.motechproject.motech-scheduler/quartz.properties
#Look for the following line:
#org.quartz.dataSource.motechDS.URL=${sql.url}motechquartz
#Change the 'motechquartz' to 'node1quartz' and save the file
Now, we need to create the databases:
#MySQL Command
mysql -u {ENTER YOUR MYSQL USERNAME HERE} -p -e "CREATE DATABASE node1data; CREATE DATABASE node1schema; CREATE DATABASE node1quartz;"
#Or PostgreSQL Command (assuming the postgres user)
sudo -u postgres psql --command 'CREATE DATABASE node1data WITH OWNER = postgres;CREATE DATABASE node1schema WITH OWNER = postgres;CREATE DATABASE node1quartz WITH OWNER = postgres;'
Then, import the files into each database:
#MySQL Command
mysql -u {ENTER YOUR MYSQL USERNAME HERE} -p node1data < motechdata.sql
mysql -u {ENTER YOUR MYSQL USERNAME HERE} -p node1schema < motechschema.sql
mysql -u {ENTER YOUR MYSQL USERNAME HERE} -p node1quartz < motechquartz.sql
#Or PostgreSQL Command (assuming the postgres user)
sudo -u postgres psql node1data < motechdata.sql
sudo -u postgres psql node1schema < motechschema.sql
sudo -u postgres psql node1quartz < motechquartz.sql
Finally, we need to start the tomcat7 server and everything should be up and running.
sudo service tomcat7 start
At this point, everything should startup successfully pointing to the new databases.
Demo: OpenMRS Schedule Tracking¶
Table of Contents
Getting started¶
The source code for the demo is available on our GitHub repository (branch v1.0).
- You will need to set up the following external systems for the demo implementation:
- CommCareHQ
- OpenMRS 1.9 (with Rest Web Services module, version 2.4)
You may check our documentation, for complete guide on Connecting MOTECH to OpenMRS.
Before starting to work with the demo implementation, you must prepare your CommCareHQ and OpenMRS instance. First, access the CommCareHQ and upload the forms schema, present in the commcare.schema folder. Then access MOTECH Commcare module and connect it with your CommCareHQ instance, by providing necessary data. Finally, enable data forwarding for forms, either via MOTECH Commcare module or via CommCareHQ instance. For OpenMRS, you are supposed to prepare some sample data. Access your OpenMRS instance and under Administration tab, click “View Concept Dictionary” and add four new concepts named: Demo Concept Question #1, Demo Concept Question #2, Demo Concept Question #3, Demo Concept Question #4. Make sure to set the datatype in all of them to “Date”. Get back to Administration and click on locations. Add at least one location of any name. Get back to Administration and click “Manage providers”. Click “Add Provider” and add provider for person linked with the initial admin user (by default the person name is “Super User”). Get back to Administration and click on “Manage Encounter Types”. Click “Add Encounter Type” and add type of name “ADULTRETURN”, with any description.
You can build the demo project invoking the following command from the demo project directory:
$ mvn clean install
The demo module exposes its options via a very simple UI, available under: <motech-platform-url>/module/scheduletracking-demo/enroll/scheduleTracking
Demo specification¶
In this demo, a milestone corresponds to an observation of a particular concept having been made on or after the initial date of enrollment into the Demo Schedule. The four milestones are the Demo concepts, defined in the previous step.
Milestones have “windows” which represent a period of time. For example, today through five days from now represents a five day window. In the demo, each milestone has the same window periods. 0-1 minutes is the “early” window and no messages or alerts are raised.
At 1 minute in, a due message is raised and a phone call as well as text message are placed to the patient indicating that they are due for that particular Concept Question.
At 3 minutes, they enter the late window, and a late message is dispatched in the same manner. They receive a second late message one minute later at the 4 minute mark. The late window lasts until the 6th minute.
After this, no more late messages are sent and they enter the “max” window. They may still complete the milestone during this period. If they go beyond 15 minutes from the start of a milestone without fulfilling it, they are defaulted and their enrollment in the schedule is no longer active.
If a patient fulfills a milestone before they have defaulted, they will move on to the next milestone (unless there are no more, then the enrollment is completed) with new messages scheduled following the same format outlined above.
A patient may only have one active enrollment in the schedule at any given time, but may unenroll and start a new enrollment, or enroll again after their enrollment is completed or defaulted.
- The three Commcare forms, that you have uploaded in the previous step are:
- Patient Registration - This form will create an OpenMRS patient, create a MOTECH patient, and optionally enroll the patient into the Demo Schedule.
- Patient Enrollment - This form will enroll the MOTECH patient into the Demo Schedule (A corresponding OpenMRS patient with the same MOTECH Id must exist to use this form.)
- Patient Encounter - This form will create an encounter for an OpenMRS patient. You must provide the MOTECH Id of the patient in OpenMRS, an observation date, and an observed concept.
Demo workflow¶
In order to use the demo, you must register a patient into MOTECH with a phone number. The same patient ID must also be registered into OpenMRS. This can be achieved by registering the patient directly in OpenMRS or by sending a Commcare “Registration form”.
You may then enroll that patient in the schedule. You may view the definition of a schedule in the simple-schedule.json file, located in the resources directory of the scheduletracking demo module. This schedule will be automatically created during demo startup. A patient can be enrolled to the schedule from the scheduleTracking page or by sending the Commcare Enrollment form. If an enrolled patient is not found in both the demo MOTECH phone number database and in OpenMRS, they will not be enrolled in the schedule. Once a patient is enrolled, SMS messages and phone calls will be placed, indicating that the patient is due for a particular concept.
To complete a concept, a Patient Encounter form should be submitted via CommCareHQ. You must provide the MOTECH Id of the patient in OpenMRS, an observation date, and an observed concept id. After you have completed all 4 concepts, you will be removed from the Demo Schedule. You are also free to complete concepts (e.g. Demo Concept Question #1), before you enroll. In this case, when you do enroll, you will be enrolled at the next required concept milestone. For example, if you complete Demo Concept Question #1 and #2, then enroll in the Demo Schedule, you will be scheduled for the third milestone (Demo Concept Question #3).
Possible failures¶
- Each form received by the scheduletracking demo is validated before processing. A few of the reasons a form may fail include:
- Bad phone number format (must be in form XXX-XXX-XXXX)
- Out of sequence Concept, e.g. you can’t complete “Demo Concept Question #3” before completing “Demo Concept Question #2”
If a validation of a form fails, an information will be printed in the logs and no further action (eg. enrollment, encounter) will be executed.
Demo: SMS-Based Pregnancy Message Campaign¶
This demo will illustrate how to create an outgoing SMS-based Message Campaign with MOTECH. In order to follow along, you’ll need to have a MOTECH server with the following modules installed:
Further, to send campaign messages via SMS, you need to configure an SMS provider as described in the SMS module documentation.
Defining the Campaign¶
Our informational message campaign will be aimed at pregnant mothers, and will provide timely information to help women engage in healthy behaviors. The campaign will consist of one message per week, tailored to the specific week of pregnancy. Participants can subscribe to the service at any point in their pregnancies, and when they do, they will start with the message corresponding to current gestational age (i.e. if someone joins the program 20 weeks into her pregnancy, she can start with the message for week 20).
To meet the above requirements, we can use an Offset Campaign (refer to the Message Campaign documentation for a discussion of the different campaign types and how to configure each). The JSON definition of our Offset Campaign will contain 40 messages, one for each week of pregnancy. A snippet of the definition, for the first five weeks, is shown below. You may view the contents of the entire 40-week definition here.
[{
"name" : "Pregnancy Campaign",
"type" : "OFFSET",
"messages" : [
{
"name" : "Week 1",
"formats" : ["SMS"],
"languages" : ["en"],
"messageKey": "pregnancy-week-1",
"timeOffset" : "1 Week",
"startTime" : "10:30"
},
{
"name" : "Week 2",
"formats" : ["SMS"],
"languages" : ["en"],
"messageKey": "pregnancy-week-2",
"timeOffset" : "2 Weeks",
"startTime" : "10:30"
},
{
"name" : "Week 3",
"formats" : ["SMS"],
"languages" : ["en"],
"messageKey": "pregnancy-week-3",
"timeOffset" : "3 Weeks",
"startTime" : "10:30"
},
{
"name" : "Week 4",
"formats" : ["SMS"],
"languages" : ["en"],
"messageKey": "pregnancy-week-4",
"timeOffset" : "4 Weeks",
"startTime" : "10:30"
},
{
"name" : "Week 5",
"formats" : ["SMS"],
"languages" : ["en"],
"messageKey": "pregnancy-week-5",
"timeOffset" : "5 Weeks",
"startTime" : "10:30"
}
]
}]
The campaign JSON may be uploaded using the file upload UI or by placing the message-campaigns.json file in the message-campaign directory. Both methods are described in the Message Campaign documentation.
Creating Campaign Messages¶
The text content for our SMS messages may be conveniently managed within MOTECH using the CMS Lite module. We’ll define one message for each week of pregnancy, using the “messageKey” specified in our campaign definition as the identifier for each message.
To create a string resource in the CMS, we’ll navigate to the CMS Lite module within the MOTECH UI, and click on the “New Resource” button. A popup will appear, and we can enter our content. Here’s what we might enter for Week 5:
Keep in mind that SMS messages are limited to 140 characters, so we need to keep our prose concise.
Wiring Up Events¶
Now that we have a campaign schedule and message content defined, we need to configure MOTECH to send out the appropriate messages according to the schedule. This can be accomplished using the Tasks module.
To get started, we navigate to the Tasks module, and click on “New Task”. For the Trigger, we select Message Campaign’s Send Message event.
Next, we want to ensure that this Task is only executed for our specific message campaign. We can do this by adding a simple Filter to our Task:
In order to access messages in the CMS, we need to add a Data Source to our Task. We can do this by clicking on “Add Data Source” and selecting “CMS Lite” as the source. Notice that when configuring the data source, the fields contained in the Message Campaign Send Message event are available to be used for lookups in the CMS. These appear as blue ovals and can be dragged/dropped to the input fields below. We want to drag the “Message Key” field and drop it in the CMS Lite “Name” field. Once we’ve configured this data source lookup, the data retrieved from the CMS will be available to the downstream steps in our Task.
The last step is adding an Action for our Task – this will be where we send the SMS, of course. To construct the Action, first we select the Channel and Action (SMS and Send SMS), and then we can drag/drop the blue and orange ovals (the fields from the Trigger event and our Data Source, respectively) to configure the Action. We drop “External ID” in the recipient field (we haven’t discussed campaign enrollment yet, but this field will hold the recipient’s phone number). Then we can drop the CMS Lite content “value” in the “Message” field. For “Configuration”, we enter the name of the SMS configuration that we want to use to send the message (see the SMS module documentation for instructions on configuring a provider).
And now our Task is complete! Once we click “Save and Enable” it will be active and ready to handle events.
User Enrollment Via SMS¶
There’s just one more piece of the puzzle – enrolling actual people in the campaign. The Message Campaign documentation describes two standard methods for enrolling subscribers in campaigns: manually using the enrollment UI, or with code. For our campaign, however, it would be nice to allow recipients to self-enroll by sending an SMS. For this, we can use the Tasks module again.
Let’s create a new Task that is triggered by an Incoming SMS, that will create a Message Campaign enrollment corresponding to the information contained in the body of the SMS. For this example, we’ll assume the SMS body is very simple – that it contains the date of the potential enrollee’s last menstrual period (LMP). We’ll use the LMP as the Reference Date for the enrollment in the Message Campaign.
The Trigger part is quite simple:
For the Action, we drag the Recipient and Message ovals into the appropriate fields to configure the enrollment:
If desired, we could support additional Message Campaign enrollment actions in response to an inbound SMS – e.g. unsubscribing from a campaign or allowing the user to specify which campaign to subscribe for if our system defines more than one. These variations can also be defined using Tasks, with more sophistication possible if we use filters and/or apply string manipulation functions to the message text in order to parse multi-word messages.
Demo: Create a Care Schedule¶
Text to come
Contribute¶
Thank you for your interest in contributing to MOTECH. There are many different ways to get involved - regardless of your area of expertise and time commitment, there is likely a useful way for you to contribute. Please peruse the sections below for some instructions on how to get started contributing in specific areas. If there is another way you’d like to help that isn’t listed, just let us know what your interests are and we can help find a project for you.
Development¶
Want to help us develop MOTECH? The step-by-step guide below will help you get started. Please let us know if you see something is missing or incorrect in these instructions. Our mailing list is populated with helpful people who will help you get going - and will get this documentation up to date with any issues you encounter.
Here is how to get started:
Mailing Lists and Accounts¶
- Sign up for the MOTECH Developer mailing list - this is the best place to get help with any questions about MOTECH development.
- Create an account on GitHub, our code repository and review system.
- Get a Jira account if you’ll be working on documentation tickets - there is no self-serve way to request a Jira account yet, so please just email the MOTECH Developer list and we’ll get you set up.
Dev Environment & Tools¶
- Configure your dev machine.
- Fork one of our GitHub repositories.
- Clone your repository locally and enter the motech directory.
- Familiarize yourself with our CI.
Finding Something to Work On¶
- We recommend that you find a community issue from our issue tracker These are bugs and user stories that we think are good introductory items for new MOTECH community members.
- If you’re already building your own system on top of MOTECH and you’d like us to incorporate your changes for an issue you’ve found and fixed, please first check whether the issue already exists in our issue tracker. If you are not sure, please email the mailing list and we’ll help you determine whether the issue is already known. Please track your work with a new issue so that we can evaluate it for inclusion in the platform.
Developing and Submitting Your Code¶
- If your fix will be nontrivial, please leverage the mailing list for feedback on your design before you get too far - we are a friendly bunch and can help ensure you are headed in the right direction.
- When you’re ready to push your changes, please squash your commits to keep the change history concise, and write a commit message that conforms to our guidelines.
- Generate a pull request from your forked repository and our team will review it.
- Please incorporate code review feedback and update your pull request as needed. Once your change has passed code review, one of the project maintainers will merge your change to the repo.
- Resolve the relevant issue(s) in Jira.
Developing and Contributing Your Module¶
- If you have your own module that you would like to contribute, let us know by sending email on motech-dev@googlegroups.com (or post on our mailing list). It should contain basic information about your module, such as description, what the module does, if it needs any external configuration and how to test it properly.
- We will create a Jira issue with high priority for reviewing the module. It will be reviewed and discussed on our weekly call.
- The Jira issue will be assigned to someone, who will work with the contributor to fix any possible issues. At this time only major bugs or blocking issues will be addressed. Minor issues will get their own Jira tickets and will be resolved in later time, depending on the priority we assign them.
- When the module is ready, we will fork it to the Community Modules Repository and we will give the contributor rights to administer his module.
- Note that we can reject a module contribution if we deem it improper to maintain it on our side. In case of any further questions feel free to ask on our mailing list.
Documentation¶
We could really use some help telling our story, and we’d love your help.
First, a bit about how our docs are stored and managed. Each MOTECH code repository contains a docs directory populated with reStructured Text (reST) files. These files are built by Sphinx and hosted at http://readthedocs.org. This page contains more information about reStructuredText and how to build the docs on your local machine. Once you’ve written and built your docs locally, you can just check them in and they’ll automatically appear on our docs site after the next doc build.
The instructions below will let you know how to get started with adding/editing MOTECH documentation.
Note
If you are a writer (not a software developer!) and you find that committing documentation to GitHub is a bit daunting, drop us a line. We can provide extra support through the process (or even check in your docs for you).
Mailing Lists and Accounts¶
- Sign up for the MOTECH Developer mailing list - this is the best place to get help with any questions about MOTECH documentation or code.
- Create an account on GitHub, our code repository and review system.
- Get a Jira account if you’ll be working on documentation tickets - there is no self-serve way to request a Jira account yet, so please just email the MOTECH Developer list and we’ll get you set up.
Doc Environment & Tools¶
- Fork our GitHub repository.
- Clone your repository locally and enter the motech/docs directory.
- Install an editor for reStructuredText. Any editor will work, but we find that Sublime works pretty well.
- Install Sphinx and Javasphinx, and test out building the docs locally. Full instructions here.
Finding Something to Work On¶
- All planned documentation topics for MOTECH are tracked in Jira – you are welcome to pick any unassigned ticket from this query. Note that many of the tickets have sub-tickets as well, so you can drill down to find additional unassigned topics.
- If the topic you want to write about doesn’t appear to be tracked in Jira, email the list and let us know. We’ll help you determine where the topic fits in our ToC and create a Jira ticket for it.
- Assign the Jira ticket to yourself and click “Start Progress” when you’re ready to start writing.
Writing and Submitting Your Doc¶
- As you are writing your doc, we recommend building periodically to ensure that the doc looks the way you expect. It can take some trial and error to get the hang of reStructuredText markup.
- When you’re ready to push your changes, please squash your commits to keep the change history concise, and write a commit message that conforms to our guidelines.
- Submit your doc using git push origin - this sends your changes to the MOTECH fork on your GitHub repository.
- Now, you have to create a pull request from your GitHub fork to our repository for review. This is easily done through the GitHub user interface.
- Please incorporate review feedback and update your pull request as needed - once your change has passed code review, one of the project maintainers will merge your change to the repo.
- Resolve the relevant issue(s) in Jira.
Translation¶
Bonjour!
We are using Transifex to manage MOTECH translations, which makes it easy for non-geeks to help. If you speak multiple languages and would like to help us make MOTECH multilingual, please start by checking out our translation page to determine whether your language(s) are on our list. Do we have a translation in progress for your language? Great! We’d love your help translating additional strings. Do we not have a translation started for your language? Also great! We’d love your help getting one started.
Either way, please sign up for Transifex (free), and then contact us. Let us know your Transifex user ID and which language(s) you’d like to work on, and we’ll help you get started.
Release Notes¶
Current Version¶
Older Versions¶
Version 0.24 Release Notes¶
Release Date: September 3, 2014
Release Summary¶
The 0.24 release is primarily dedicated to removing MOTECH’s dependency on CouchDB, as well as enhancing MOTECH Data Services (MDS) to make it usable as the data layer for most MOTECH applications. All modules have now been migrated to MDS, with a few exceptions noted below. One notable enhancement to MDS in this release is the support for relationships between entities (1:1, 1:many, master-detail), in order to enable a number of the module migrations.
This release also features some consolidation of our code repositories (details below) and deprecation of a few modules. The Platform modules were also refactored to reduce their public surface area. Three new modules have been developed: mTraining, Batch, and Hub.
Major Changes¶
Modules Migrated from CouchDB to MDS¶
All MOTECH modules (with the exception of the IVR modules mentioned later) are now using MOTECH Data Services for data storage and retrieval. Any modules that are used in MOTECH implementations should likewise be migrated from CouchDB to MDS. The best reference for using MDS at this time is the source code for the existing modules; soon we will provide developer-focused documentation for MDS
.
New MDS Features¶
A number of new features were added to MDS in order to support migration of the existing modules. These features include:
- Support for relationships among MDS entities. This includes 1:1, 1:many, and master-detail relationships (bi-directional and many:many relationships are expected in a future release)
- UI support for browsing and restoring items from Trash
- UI support for Filters
- Support for additional types: Locale, Date, File, Map
- Various UI changes to improve the schema editor and data browser
Repository Consolidation¶
In order to simplify development, some of the MOTECH source code repositories have been merged. Rather than maintaining four separate repositories for MOTECH source code (motech, platform-campaigns, platform-communcations, and platform-medical-records), there are now two repositories: motech and modules. Please see the MOTECH Code Repositories topic for more information.
Modules Moved to motech-contrib¶
As part of the repository cleanup effort, a few modules were moved out to the motech-contrib repository. The specific modules that were chosen are those that have very few (or in some cases no) consumers. These modules will no longer be maintained by Grameen Foundation, but MOTECH implementers are welcome to continue using them and either fork the code or submit pull requests to the repo as needed. The list of migrated modules is as follows:
- Event Aggregation
- Mobile Forms
- OpenMRS OMOD
- Outbox
New Modules¶
Several new modules were developed as part of this release:
- mTraining - The mTraining module provides data containers and APIs for defining training courses and tracking user enrollment and progress. A typical use case might be an IVR-based training course for a health worker.
- Batch - The Batch module is an implementation of Spring batch (version:3.0.0.M3). It essentially deals with scheduling triggering of jobs.
- Hub - The Hub module is the implementation of Google’s PubSubHubbub Hub 0.4 Specifications. It exposes an API so other modules can act as publisher and make contents available to it for distribution whenever there is an update in a topic.
Legacy IVR Modules Deprecated - Replacements Coming¶
The following modules have been deprecated:
- Call Flow
- Decision Tree
- IVR (including API, Asterisk, Kookoo, Verboice, and Voxeo)
These modules are still present in the source code repository, but they were not built as part of the release. If you need to use one or more of these modules, you can build each module that you require by executing mvn install from the module’s base directory. Note that these modules depend on CouchDB.
These legacy modules will be replaced in 0.25 by new generic modules for handling VXML and CCXML. There will also be a re-worked version of the Verboice module in a coming release that removes the dependencies on call-flow and decision-tree.
Known Issues¶
MOTECH-818 - Able to remove a field from a lookup even if the lookup is being used in a Task
Summary: User should not be able to remove a field from an MDS Lookup if the Lookup is used as a data source in a Task. Currently this is not prevented.
Workaround: When modifying a Lookup, the user will need to verify manually that it is not being used as a data source in a Task (this can be checked via the Tasks UI).
MOTECH-1084 - MDS ComboBox UI Bugs
Summary: There are some problems with combobox fields when we add two or more of them to an MDS entity:
- After opening instance view in Data Browser we can see error message “This field is required” under dropboxes of all comboboxes (except for the first one) even though they aren’t.
- After clicking “Add option” button and filling text field with any value on more than one combobox, when we click “Save” for any of them, save buttons for all others will just gray out and turn off. They’ll become active again when we enter anything in text fields in any combobox.
Workaround:
- A number of workarounds may exist depending on the nature of your application. For example, one could create a dummy default option for the ComboBox with a name like “Empty” or “No Value” when defining the ComboBox field.
- Enter anything in the text fields of any combobox, and the “Save” buttons will become active again.
MOTECH-1125 - Getters starting with “is” are not recognized by the MDS annotation processor
Summary: The MDS annotation processor should recognize boolean getters, starting with “is”, eg. for field “completed”, the getter method “isCompleted()” should be recognized. Currently, it seems to only recognize getters starting with “get”.
Workaround: This issue may be temporarily avoided by prefixing getters on MDS entity classes with “get”.
MOTECH-1147 - Default value for Date type fields doesn’t work
Summary: Create an entity and add a Date type field. Set a default value to any date and save changes. Notice that the default value field is clear and when you add an instance of that entity, there’s no default value inserted.
Workaround: When using an MDS Entity with a field of type Date, the values for all Date fields will need to be set explicitly.
MOTECH-1153 - Creating an MDS entity with an enum field fails if the enum has many values
Summary: Attempting to create an entity that has an enum field (allow user supplied option disabled), that has got many values causes failures. This does not happen when user supplied option is enabled (as it creates a list, instead of enum).
Workaround: Some possible workarounds for this issue (depending on the nature of the application) include: - Enabling user supplied values on enum fields, if appropriate for the application - If possible, splitting the enum into multiple enums
MOTECH-1156 - Error when adding MDS Entity with space in name
Summary: If a user adds an Entity with spaces in the name then there is an error. After that it is impossible to add other Entities. Entity name should be validated against spaces in the name or they should be deleted.
Workaround: Avoid spaces in Entity names.
Tickets¶
You can browse the list of tickets resolved for this release on our issue tracker.
Version 0.24.1 Release Notes¶
Release Date: October 8, 2014
Release Summary¶
0.24.1 contains a few bug fixes, and two notable new MOTECH Data Services features: bi-directional relationships and many-to-many relationships.
Tickets¶
The following tickets were resolved for this release:
MOTECH-1108 - Support two-way relationships
MA-471 - Expose retriveAll() by both properties list and query params
MOTECH-1047 - Support many-to-many relationships - DDE only
MOTECH-1255 - MDS doesn’t recognize an array of byte primitives
NO BUG - Fix job id type of reminder event in PillReminder
Version 0.25 Release Notes¶
Release Date: March 31, 2015
Release Summary¶
The 0.25 release is primarily dedicated to MOTECH Data Services improvements, including MDS REST APIs and the ability to import entities to MDS via CSV file.
This release also features a new, simplified IVR module to replace the assorted IVR modules that were deprecated in 0.24.
Major Changes¶
CSV Import of MDS Entities¶
It is now possible to bulk import MDS entity data in CSV format. See the bulk upload tutorial for more information.
MDS REST API Generation¶
MDS CRUD Events¶
Other MDS Improvements¶
- Two-way relationships
New IVR Module¶
WAR File Changes¶
CouchDB Removal¶
Support for CouchDB, which was deprecated in version 0.24, has been completely removed in version 0.25. As part of the removal process, the development team extensively tested MDS performance to ensure that the migration to MDS had not introduced performance regressions in MOTECH modules.
Tickets¶
You can browse the list of tickets resolved for this release on our issue tracker.
Version 0.26 Release Notes¶
Release Date: September 3, 2015
Release Summary¶
The 0.26 release introduces two new modules: the CSD module, which implements the Care Services Discovery API; and the DHIS2 module, which may be used to forward data to DHIS2. It also features enhancements to MOTECH Data Services, including UI support for entity relationships and import/export support for schemas.
This release also adds a significant amount of documentation aimed at MOTECH developers and implementers, including documentation for most existing modules.
Where to Get it¶
Note
The links below point to the 0.26.6 release, which is the current dot release from the 0.26.X code branch.
Source Code: Platform | Modules
Binary Distribution
Modules:
Major Changes¶
DHIS2 Module¶
The newly added DHIS2 module enables MOTECH to forward data to a DHIS2 server. Individual-level (DHIS “tracker”) data may be forwarded in addition to aggregate-level data. One interesting use case that this module enables is forwarding data collected with handsets (e.g. CommCare) to DHIS2 by way of MOTECH. This use case may be configured entirely using UI utilizing the Tasks module to define the mapping between systems.
CSD Module¶
The newly added CSD module supports connecting MOTECH to a health worker/facility registry that supports the Care Services Discovery standard.
UI for MDS Object Relationships¶
This version also adds support for creating relationships among Data Services entities using the user interface. Relationships may now be defined either via code annotations or via UI using the schema editor. Several types of relationships are supported: one-to-one, one-to-many, many-to-many, and master-detail. You can read more about entity relationships here.
MDS Schema Import/Export¶
MOTECH adds the ability to import/export MDS entities in version 0.26. This feature allows an implementer to export his/her end-user-defined entities (EUDEs) to a file so they may be imported into another MOTECH server. You can read more about this feature here.
REST API Documentation¶
MOTECH added the ability to auto-generate REST APIs for Data Services entities in version 0.25. Now documentation for these APIs is also auto-generated. To learn more about this, see the Automatic REST API documentation UI in MOTECH documentation. [1]
Tickets¶
You can browse the list of tickets resolved for this release on our issue tracker.
Footnotes
[1] | And yes, we did just invite you to view documentation describing the auto-generated documentation that describes the auto-generated APIs for manipulating database entities that are auto-generated based on code annotations. Simple, right? |
Version 0.27 Release Notes¶
Release Date: October 15, 2015
Release Summary¶
The 0.27 release was primarily a bug fix release. Numerous MOTECH Data Services bugs were fixed, and some of MOTECH’s dependent libraries were upgraded. A few small new MDS and CommCare features were added, listed below.
Where to Get it¶
Note
The links below point to the 0.27.4 release, which is the current dot release from the 0.27.X code branch.
Source Code: Platform | Modules
Binary Distribution
Modules:
Major Changes¶
While this release was mostly comprised of bug fixes and other small changes, a few notable new features are listed below.
- CommCare - retroactive form import, support API v.0.5
- MOTECH Data Services - Upsert method, hidden and read-only fields, numerous bug fixes
- User interface - login page performance improvements
Tickets¶
You can browse the list of tickets resolved for this release on our issue tracker.
Packaging the MOTECH Platform¶
This section of the documentation is created to help with building the packages and install Motech from them
Roadmap¶
This page describes the high-level roadmap for the MOTECH system as we move toward the release of version 1.0. For more granular and up-to-date information about release plans, click on the issue tracker links for each of the releases below.
Version 0.28 - Release date: April 2016¶
Version 0.28 will represent a breaking change between 0.27. We plan to upgrade a number of core components that will require changes in deployment.
Key Technical Changes¶
- The following is a list of key technical changes planned to be implemented in version 0.28:
- Upgrade to Java 8
- Upgrade Data Nucleus to version 4.0.1
- Improve UI build process with Node, Bower, Gulp and SCSS
- Split database from motech_data_services to motech_data and motech_schema
Module Enhancements¶
- New IHE Interop Module supports the creation of HL7 CDA documents in MOTECH
- Improved OpenMRS module with tasks integration
- New Atom-Client module allows MOTECH to query atom feeds and act on changes in the feed. It will primarily be used in OpenMRS integration to detect when a new patient, encounter or provider has been created. However, this module can work with any atom feed.
Version 0.29 - Release date: June 2016¶
Version 0.29 focuses on enhancing OpenMRS workflows for an implementation in Nepal and Mozambique as well as adding new interoperability with iHRIS and OpenLMIS.
Key Technical Changes¶
- The following is a list of key technical changes planned to be implemented in version 0.28:
- Upgrade Spring from version 3.1 to 3.2
Module Enhancements¶
- OpenMRS module
- Supporting multiple OpenMRS systems connecting to a single MOTECH server
- Ensuring MOTECH can communicate with OpenMRS REST Web Services API versions 1.9 through 1.12.
New Metrics module that integrates MOTECH with a Graphite Server allowing for server monitoring and the development of Key Performance Indicators.
New iHRIS integration that allows MOTECH to send data to iHRIS.
New OpenLMIS module provides basic interaction with OpenLMIS.
Version 1.0 - Release date: Q3 2016¶
Stable Semantic Versioning¶
We will apply the open semantic version scheme to the MOTECH Platform and all modules thus making it easier to determine backward compatibility. We will stabilize our core system and API providing implementers with a level of confidence that their system will be compatible with future releases of MOTECH. (MOTECH-585)
Platform and Module API Standardization and Documentation¶
Every public API will be standardized and documented with standard javadoc that is published with each release. (MOTECH-1466)
Consistent User Interface Elements¶
Developers across the globe have contributed UI code to MOTECH. We will make UI elements consistent across the platform to ease implementation and prepare for UI improvements after the MOTECH 1.0 release. (MOTECH-2008)
Standardized Interoperability¶
We are working to expand the IHE interop module to better support standardized interoperability workflows. This includes integrating MOTECH with the Open eHealth Integration platform and will ultimately open up new standardized workflows that support the majority of IHE profiles and, therefore, OpenHIE workflows.(MOTECH-1242)
Post 1.0 - Release date: TBD¶
We are currently focusing on our MOTECH 1.0 release and will reevaluate the post 1.0 issues at a later time. Below are our issue trackers for Post 1.0
MOTECH Mailing Lists¶
The mailing lists below are the best way to keep in touch with us. Please join the discussion!
MOTECH Developers¶
Mailing list for regular contributors to the MOTECH Platform source repository - used for design discussions and other issues impacting the developer community.
motech-dev@googlegroups.com | Join Dev List |
MOTECH Implementers¶
Mailing list for implementers and other users of MOTECH - used mostly for communication related to releases. Traffic is moderated and very low volume.
motech-implementers@googlegroups.com | Join Implementers List |
Javadoc¶
org.motechproject.admin.domain¶
NotificationRule¶
-
public class
NotificationRule
¶ A notification rule persisted in the database. Represents a rule for sending out a single notification after a matching
org.motechproject.admin.domain.StatusMessage
is registered in the system. The message is matched against its level and the module to which it is tied to. This class also contains information about this notification’s recipient and theActionType
representing a method used for notifying the recipient.
Constructors¶
NotificationRule¶
-
public
NotificationRule
(String recipient, ActionType actionType, Level level, String moduleName)¶ Constructor.
Parameters: - recipient – the recipient of the notification
- actionType – the type of action which will be performed
- level – the minimal level for which the notification will trigger
- moduleName – the module name for which this rule will trigger, leave null or blank for every module
Methods¶
getActionType¶
-
public ActionType
getActionType
()¶ Returns: the action that should be performed for this notification rule
getLevel¶
getModuleName¶
matches¶
-
public boolean
matches
(StatusMessage message)¶ Checks if the message matches this rule.
Parameters: - message – the message which will be checked against this rule
Returns: true if message matches this notification rule, false otherwise
setActionType¶
-
public void
setActionType
(ActionType actionType)¶ Parameters: - actionType – the action that should be performed for this notification rule
setLevel¶
setModuleName¶
QueueMBean¶
-
public class
QueueMBean
¶ Represents a JMS queue. Holds information about the queue statistics. This information is retrieved using JMX.
Constructors¶
Methods¶
getConsumerCount¶
-
public long
getConsumerCount
()¶ Returns: number of consumers for this queue (most likely MOTECH instances)
getDequeueCount¶
-
public long
getDequeueCount
()¶ Returns: the total number of messages removed from the queue (ack’d by consumer) since last restart
getEnqueueCount¶
-
public long
getEnqueueCount
()¶ Returns: the total number of messages sent to the queue since the last restart
getExpiredCount¶
-
public long
getExpiredCount
()¶ Returns: the number of messages that were not delivered because they were expired
getQueueSize¶
-
public long
getQueueSize
()¶ Returns the total number of messages in the queue/store that have not been ack’d by a consumer. This can become confusing at times when compared to the Enqueue Count because the Enqueue Count is a count over a period of time (since the last broker restart) while the Queue Size is not dependent on a period of time but instead on the actual number of messages in the store.
Returns: the total number of messages in the queue/store that have not been ack’d by a consumer, not dependent on a period of time
setConsumerCount¶
-
public void
setConsumerCount
(long consumerCount)¶ Parameters: - consumerCount – number of consumers for this queue (most likely MOTECH instances)
setDequeueCount¶
-
public void
setDequeueCount
(long dequeueCount)¶ Parameters: - dequeueCount – the total number of messages removed from the queue (ack’d by consumer) since last restart
setDestination¶
setEnqueueCount¶
-
public void
setEnqueueCount
(long enqueueCount)¶ Parameters: - enqueueCount – the total number of messages sent to the queue since the last restart
setExpiredCount¶
-
public void
setExpiredCount
(long expiredCount)¶ Parameters: - expiredCount – the number of messages that were not delivered because they were expired
setQueueSize¶
-
public void
setQueueSize
(long queueSize)¶ Sets the total number of messages in the queue/store that have not been ack’d by a consumer. This can become confusing at times when compared to the Enqueue Count because the Enqueue Count is a count over a period of time (since the last broker restart) while the Queue Size is not dependent on a period of time but instead on the actual number of messages in the store.
Parameters: - queueSize – the total number of messages in the queue/store that have not been ack’d by a consumer, not dependent on a period of time
StatusMessage¶
-
public class
StatusMessage
¶ Represents a message displayed in the ‘messages’ section of the Admin UI. Persisted by MDS. Apart from the message and its
Level
, it contains also information about the module that sent the message. The timeout field represents theDateTime
of the message expiration. Status messages are matched against notification rules.
Constructors¶
StatusMessage¶
-
public
StatusMessage
()¶ Constructor. Defaults the level of this message to INFO and the expiration date to 60 minutes from now.
StatusMessage¶
TopicMBean¶
-
public class
TopicMBean
¶ Represents a JMS topic. Holds information about the topic statistics. This information is retrieved using JMX.
Constructors¶
Methods¶
getConsumerCount¶
-
public long
getConsumerCount
()¶ Returns: number of consumers for this topic (most likely MOTECH instances)
getDequeueCount¶
-
public long
getDequeueCount
()¶ Returns: the total number of messages removed from the topic since last restart
getEnqueueCount¶
-
public long
getEnqueueCount
()¶ Returns: the total number of messages sent to the topic since the last restart
getExpiredCount¶
-
public long
getExpiredCount
()¶ Returns: the number of messages that were not delivered because they were expired
setConsumerCount¶
-
public void
setConsumerCount
(long consumerCount)¶ Parameters: - consumerCount – number of consumers for this topic (most likely MOTECH instances)
setDequeueCount¶
-
public void
setDequeueCount
(long dequeueCount)¶ Parameters: - dequeueCount – the total number of messages removed from the topic since last restart
setDestination¶
org.motechproject.admin.mds¶
NotificationRulesDataService¶
-
public interface
NotificationRulesDataService
extends MotechDataService<NotificationRule>¶ MDS data service for
NotificationRule
s.
StatusMessagesDataService¶
-
public interface
StatusMessagesDataService
extends MotechDataService<StatusMessage>¶ MDS data service for
StatusMessage
s.
Methods¶
findByTimeout¶
-
List<StatusMessage>
findByTimeout
(Range<DateTime> timeout)¶ Returns status messages with their timeout value in a given range. Leaving the min value empty will result in retrieving all messages timing out before the max value. Leaving the max value empty will result in retrieving all messages timing out after the min value.
Parameters: - timeout – the range in which the timeout date-time must fall
Returns: a list of messages matching the timeout criteria
org.motechproject.admin.messages¶
ActionType¶
-
public enum
ActionType
¶ Represents an action which should be taken for a notification, in particular which message channel should be used to communicate the notification. Currently the two channels supported are sms and email.
Enum Constants¶
EMAIL¶
-
public static final ActionType
EMAIL
¶
SMS¶
-
public static final ActionType
SMS
¶
Level¶
-
public enum
Level
¶ Represents the level of a
org.motechproject.admin.domain.StatusMessage
, which is reflected on the UI. Message levels are taken into consideration when processing notification rules.See also:
org.motechproject.admin.domain.StatusMessage
,org.motechproject.admin.domain.NotificationRule
org.motechproject.admin.service¶
StatusMessageService¶
-
public interface
StatusMessageService
¶ Message service used to send status messages and manage notification rules.
See also:
org.motechproject.admin.domain.StatusMessage
,org.motechproject.admin.domain.NotificationRule
Methods¶
critical¶
-
void
critical
(String text, String moduleName)¶ Creates a status message with CRITICAL level and posts it in the system. If the message matches any notification rules, appropriate notifications will be triggered. The message will be visible in the message UI until it expires. The value of timeout is set to the default.
Parameters: - text – the message content
- moduleName – the name of the module this message is related with
critical¶
-
void
critical
(String text, String moduleName, DateTime timeout)¶ Creates a status message with CRITICAL level and posts it in the system. If the message matches any notification rules, appropriate notifications will be triggered. The message will be visible in the message UI until it expires.
Parameters: - text – the message content
- moduleName – the name of the module this message is related with
- timeout – the message expiry date
debug¶
-
void
debug
(String text, String moduleName)¶ Creates a status message with DEBUG level and posts it in the system. If the message matches any notification rules, appropriate notifications will be triggered. The message will be visible in the message UI until it expires. The value of timeout is set to the default.
Parameters: - text – the message content
- moduleName – the name of the module this message is related with
debug¶
-
void
debug
(String text, String moduleName, DateTime timeout)¶ Creates a status message with DEBUG level and posts it in the system. If the message matches any notification rules, appropriate notifications will be triggered. The message will be visible in the message UI until it expires.
Parameters: - text – the message content
- moduleName – the name of the module this message is related with
- timeout – the message expiry date
error¶
-
void
error
(String text, String moduleName)¶ Creates a status message with ERROR level and posts it in the system. If the message matches any notification rules, appropriate notifications will be triggered. The message will be visible in the message UI until it expires. The value of timeout is set to the default.
Parameters: - text – the message content
- moduleName – the name of the module this message is related with
error¶
-
void
error
(String text, String moduleName, DateTime timeout)¶ Creates a status message with ERROR level and posts it in the system. If the message matches any notification rules, appropriate notifications will be triggered. The message will be visible in the message UI until it expires.
Parameters: - text – the message content
- moduleName – the name of the module this message is related with
- timeout – the message expiry date
getActiveMessages¶
-
List<StatusMessage>
getActiveMessages
()¶ Retrieves status messages that have not expired.
Returns: list of active status messages
getAllMessages¶
-
List<StatusMessage>
getAllMessages
()¶ Retrieves all status messages, including those that expired.
Returns: list of all status messages
getNotificationRules¶
-
List<NotificationRule>
getNotificationRules
()¶ Retrieves all notification rules.
Returns: list of all notification rules
info¶
-
void
info
(String text, String moduleName)¶ Creates a status message and posts it in the system. If the message matches any notification rules, appropriate notifications will be triggered. The message will be visible in the message UI until it expires. The value of timeout is set to the default.
Parameters: - text – the message content
- moduleName – the name of the module this message is related with
info¶
-
void
info
(String text, String moduleName, DateTime timeout)¶ Creates a status message with INFO level and posts it in the system. If the message matches any notification rules, appropriate notifications will be triggered. The message will be visible in the message UI until it expires.
Parameters: - text – the message content
- moduleName – the name of the module this message is related with
- timeout – the message expiry date
postMessage¶
-
void
postMessage
(StatusMessage message)¶ Creates a status message and posts it in the system. If the message matches any notification rules, appropriate notifications will be triggered. The message will be visible in the message UI until it expires.
Parameters: - message – the message to send
postMessage¶
-
void
postMessage
(String text, String moduleName, Level level)¶ Creates a status message and posts it in the system. If the message matches any notification rules, appropriate notifications will be triggered. The message will be visible in the message UI until it expires. The value of timeout is set to the default.
Parameters: - text – the message content
- moduleName – the name of the module this message is related with
- level – the message level
postMessage¶
-
void
postMessage
(String text, String moduleName, Level level, DateTime timeout)¶ Creates a status message and posts it in the system. If the message matches any notification rules, appropriate notifications will be triggered. The message will be visible in the message UI until it expires.
Parameters: - text – the message content
- moduleName – the name of the module this message is related with
- level – the message level
- timeout – the message expiry date
postMessage¶
-
void
postMessage
(String text, String moduleName, String level, DateTime timeout)¶ Creates a status message and posts it in the system. If the message matches any notification rules, appropriate notifications will be triggered. The message will be visible in the message UI until it expires.
Parameters: - text – the message content
- moduleName – the name of the module this message is related with
- level – the message level as a string value
- timeout – the message expiry date
removeMessage¶
-
void
removeMessage
(StatusMessage message)¶ Removes the given message.
Parameters: - message – the message to remove
removeNotificationRule¶
removeNotificationRule¶
saveNotificationRules¶
-
void
saveNotificationRules
(List<NotificationRule> notificationRules)¶ Creates or updates notification rules. Rule is updated when it has the id field set.
Parameters: - notificationRules – the list of notification rules to create/update
saveRule¶
-
void
saveRule
(NotificationRule notificationRule)¶ Creates or updates a notification rule. Rule is updated when it has the id field set.
Parameters: - notificationRule – the rule to create/update
warn¶
-
void
warn
(String text, String moduleName)¶ Creates a status message with WARN level and posts it in the system. If the message matches any notification rules, appropriate notifications will be triggered. The message will be visible in the message UI until it expires. The value of timeout is set to the default.
Parameters: - text – the message content
- moduleName – the name of the module this message is related with
warn¶
-
void
warn
(String text, String moduleName, DateTime timeout)¶ Creates a status message with WARN level and posts it in the system. If the message matches any notification rules, appropriate notifications will be triggered. The message will be visible in the message UI until it expires.
Parameters: - text – the message content
- moduleName – the name of the module this message is related with
- timeout – the message expiry date
org.motechproject.bundle.extender¶
MotechExtenderConfigFactory¶
-
public class
MotechExtenderConfigFactory
implements FactoryBean<Properties>¶ Creates the extender configuration for MOTECH, currently blueprint dependency wait time is the only option supported. In order to change the blueprint extender dependency wait time used during platform runtime,
org.motechproject.blueprint.dependencies.waittime
should be set with the wait time in milliseconds. The default blueprint timeout is 5 minutes.
Fields¶
MotechOsgiApplicationContextCreator¶
-
public class
MotechOsgiApplicationContextCreator
implements OsgiApplicationContextCreator¶ This is the class responsible for creating Spring application contexts for Spring enabled bundles. Scans bundles and creates a
org.motechproject.bundle.extender.MotechOsgiConfigurableApplicationContext
for Spring enabled bundles. In most cases such bundles have their Spring configuration in their META-INF/spring directory. The context created is then managed by the Blueprint extender.
Methods¶
createApplicationContext¶
-
public DelegatedExecutionOsgiBundleApplicationContext
createApplicationContext
(BundleContext bundleContext)¶
MotechOsgiConfigurableApplicationContext¶
-
public class
MotechOsgiConfigurableApplicationContext
extends OsgiBundleXmlApplicationContext implements ConfigurableWebApplicationContext¶ This is the context class, which will be used by the extender for creating application contexts.
Constructors¶
Methods¶
getServletConfig¶
-
public ServletConfig
getServletConfig
()¶
getServletContext¶
-
public ServletContext
getServletContext
()¶
setServletConfig¶
-
public void
setServletConfig
(ServletConfig servletConfig)¶
setServletContext¶
-
public void
setServletContext
(ServletContext servletContext)¶
waitForContext¶
-
public void
waitForContext
(int waitTimeInMillis)¶ Utility for waiting until the context is ready, which is signalled by firing the
org.springframework.context.event.ContextRefreshedEvent
.Parameters: - waitTimeInMillis – the max wait in milliseconds
org.motechproject.commons.api¶
AbstractDataProvider¶
-
public abstract class
AbstractDataProvider
implements DataProvider¶ Base class for every data provider.
ApplicationContextServiceReferenceUtils¶
-
public final class
ApplicationContextServiceReferenceUtils
¶ Utility class for
ServiceReference
class.
Methods¶
isNotValid¶
-
public static boolean
isNotValid
(ServiceReference serviceReference)¶ Checks if given
ServiceReference
is not valid.Parameters: - serviceReference – the
ServiceReference
to be validated
Returns: true if given
ServiceReference
is not valid, false otherwise- serviceReference – the
isValid¶
-
public static boolean
isValid
(ServiceReference serviceReference)¶ Checks whether given
ServiceReference
is valid or not.Parameters: - serviceReference – the
ServiceReference
to be validated
Returns: true if given
ServiceReference
is valid, false otherwise- serviceReference – the
ClassUtils¶
-
public final class
ClassUtils
¶ Utility class responsible for casting classes.
Methods¶
filterByClass¶
-
public static <T> List<T>
filterByClass
(Class<T> clazz, Enumeration enumeration)¶ Filters the given
Enumeration
searching for instances of the given class.Parameters: - clazz – the class used for filtering
- enumeration – the filtered elements
- <T> – the class used for filtering and returning properly cast objects
Returns: the list of instances of given class found in the enumeration
DataProvider¶
-
public interface
DataProvider
¶ Interface for classes that act as data providers for Tasks.
Methods¶
lookup¶
-
Object
lookup
(String type, String lookupName, Map<String, String> lookupFields)¶ Returns single object matching given conditions.
Parameters: - type – the type of searched object
- lookupName – the name of used lookup
- lookupFields – the map of fields names and expected values
Returns: single object matching conditions
supports¶
MotechEnumUtils¶
-
public final class
MotechEnumUtils
¶ Misc enum-related helper functions
Methods¶
toEnumSet¶
toEnumSet¶
-
public static <T extends Enum> Set<T>
toEnumSet
(Class<T> enumClass, String csv)¶ Returns a set of enums given a comma separated string and an enum class
Parameters: - enumClass – the enum class
- csv – a comma separated string representing a set of enum values
Returns: the enum set constructed from the given string
toString¶
MotechException¶
-
public class
MotechException
extends RuntimeException¶ A generic Runtime Exception used in MOTECH.
MotechMapUtils¶
-
public final class
MotechMapUtils
¶ The
MotechMapUtils
class contains methods that allow modifications and operations on maps
Methods¶
asProperties¶
-
public static Properties
asProperties
(Map<Object, Object> map)¶ Converts java.util.Map into java.util.Properties
Parameters: - map – Map to convert
Returns: Properties, created from given map
mergeMaps¶
-
public static Map<Object, Object>
mergeMaps
(Map<Object, Object> overridingMap, Map<Object, Object> baseMap)¶ Null-safe merge of two maps. If both parameters are null it returns empty map. If one of the maps is null, it returns the other one. If a key is present in two maps, the value in the merged map will be taken from the overriding map.
Parameters: - overridingMap – The map overriding values in the base map
- baseMap – The base map
Returns: merged map
Range¶
-
public class
Range
<T>¶ Class representing range between two objects of same type.
Parameters: - <T> –
Constructors¶
StopWatchHelper¶
-
public final class
StopWatchHelper
¶ A helper that allows to easily restart the Apache commons stop watch.
Methods¶
restart¶
-
public static void
restart
(StopWatch stopWatch)¶ Restarts the provided
StopWatch
by callingStopWatch.reset()
andStopWatch.start()
on it.Parameters: - stopWatch – the stop watch to restart
TasksEventParser¶
-
public interface
TasksEventParser
¶ The
TasksEventParser
interface provides a way for modules to define a custom way to handle trigger events. Before event parameters or subject are parsed, the Tasks module will first check if received event contains parameter with key custom_tasks_event_parser and if so, it will look for custom parser that matches the name exposed viagetName()
method. If any module wants to use a custom event parser, they should simply implement this interface and expose it as OSGi service.
Methods¶
getName¶
-
String
getName
()¶ Returns the name of the module that registers custom parser. Tasks module will look for all registered event parsers and try to match the name passed in the event parameter
org.motechproject.tasks.custom_event_parser
with the name returned by this method. If there’s a match, a custom parser with matched name will be used.Returns: Module name that registers custom event parser
parseEventParameters¶
-
Map<String, Object>
parseEventParameters
(String eventSubject, Map<String, Object> eventParameters)¶ Given a map of event parameters, parses them in a user-defined way to receive a custom map of event parameters
Parameters: - eventSubject – The original event subject
- eventParameters – Initial event parameters
Returns: Custom, parsed event parameters, that will be used instead of initial params
parseEventSubject¶
-
String
parseEventSubject
(String eventSubject, Map<String, Object> eventParameters)¶ Adjusts event subject of the event. Thanks to this, we are able to map events of the same event subject to different triggers. If there’s no need to modify the subject of an event (eg. one event should map only one trigger), simply return the original subject, that is passed as an argument.
Parameters: - eventSubject – The original event subject
- eventParameters – Initial event parameters
Returns: Custom event subject
ThreadSuspender¶
-
public final class
ThreadSuspender
¶ Util class, that allows to put current thread to sleep.
Methods¶
sleep¶
-
public static void
sleep
(int millis, String interruptedMessage)¶ Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers.
Parameters: - millis – the length of time to sleep in milliseconds
- interruptedMessage – the message to put in logs, in case the waiting gets interrupted
org.motechproject.commons.api.json¶
MotechJsonMessage¶
-
public class
MotechJsonMessage
¶ Handles the creation of Json messages for the MotechMessage class
MotechJsonReader¶
-
public class
MotechJsonReader
¶ Class responsible for creating objects from json. It can use
InputStream
,String
or file classpath. This class uses Gson underneath.See also: Google Gson
Constructors¶
Methods¶
readFromFile¶
readFromStream¶
-
public Object
readFromStream
(InputStream stream, Type ofType)¶ Creates object of type
ofType
from input stream.Parameters: - stream – the stream to deserialize
- ofType – the type of created object
Returns: object of type
ofType
readFromStreamOnlyExposeAnnotations¶
-
public Object
readFromStreamOnlyExposeAnnotations
(InputStream stream, Type ofType)¶ Creates object of type
ofType
from input stream. Will only deserialize fields withExpose
annotation.Parameters: - stream – the stream to deserialize
- ofType – the type of created object
Returns: object of type
ofType
readFromString¶
readFromString¶
-
public Object
readFromString
(String text, Type ofType, Map<Type, Object> typeAdapters)¶ Creates object of type
ofType
from givenString
using user-specified adapters.Parameters: - text – the
String
to deserialize - ofType – the type of created object
- typeAdapters – custom adapters to use for deserialization
Returns: object of type
ofType
- text – the
readFromStringOnlyExposeAnnotations¶
org.motechproject.commons.api.model¶
org.motechproject.commons.date.exception¶
org.motechproject.commons.date.model¶
Time¶
-
public class
Time
implements Comparable<Time>, Serializable¶ Represents time as number of hours and minutes.
Constructors¶
Time¶
-
public
Time
(int hour, int minute)¶ Constructor.
Parameters: - hour – the hour to be stored, not null
- minute – the minute to be stored, not null
Time¶
Methods¶
getHour¶
getMinute¶
isAfter¶
isAfterOrEqual¶
isBefore¶
isBeforeOrEqual¶
isBetween¶
parseTime¶
-
public static Time
parseTime
(String time, String separator)¶ Parses given
String
using the separator.Parameters: - time – the
String
to be parsed, null returns null - separator – the separator used to distinguish minute from hour, not null
Throws: - IllegalArgumentException – if
time
doesn’t match “HHMM” pattern
Returns: the instance of
Time
- time – the
setHour¶
setMinute¶
timeStr¶
toDateTime¶
toDateTime¶
org.motechproject.commons.date.util¶
DateTimeSourceUtil¶
-
public final class
DateTimeSourceUtil
¶ Utility class for
DateTimeSource
.
Methods¶
now¶
setSourceInstance¶
-
public static void
setSourceInstance
(DateTimeSource sourceInstance)¶
timeZone¶
-
public static DateTimeZone
timeZone
()¶ Returns time zone used by class.
Returns: time zone used by class
DateUtil¶
-
public final class
DateUtil
¶ Utility class for various classes from
org.joda.time
package. Using this class for retrieving the current date and time will allow mocking time, so should be always used throughout the platform instead of calling the underlying date-time API directly.
Methods¶
datesToDateTimes¶
daysPast¶
-
public static int
daysPast
(LocalDate localDate, DayOfWeek dayOfWeek)¶ Counts the days passed between given date and given day of week.
Parameters: - localDate – the given date
- dayOfWeek – the given day of week
Returns: the number of days passed between
localDate
and aorg.motechproject.commons.date.model.DayOfWeek
daysStarting¶
daysToCalendarWeekEnd¶
endOfDay¶
getDifferenceOfDatesInYears¶
greaterThanOrEqualTo¶
-
public static List<DateTime>
greaterThanOrEqualTo
(DateTime date, List<DateTime> dates)¶ Filters given dates and returns only those that are past or at the given date.
Parameters: - date – the date to be used as filter
- dates – dates to be filtered
Returns: list of date that are equal or greater than given date
inRange¶
-
public static boolean
inRange
(DateTime reference, DateTime start, DateTime end)¶ Checks if first date is in period between second and third.
Parameters: - reference – the date to be checked
- start – the start of the period
- end – the end of the period
Returns: true if first date is in range, false otherwise
isOnOrAfter¶
isOnOrBefore¶
lessThan¶
newDate¶
-
public static LocalDate
newDate
(int year, int month, int day)¶ Creates new instance of
LocalDate
.Parameters: - year – the year to be stored in created instance
- month – the month to be stored in created instance
- day – the day to be stored in created instance
Returns: the instance of
LocalDate
with given year, month and day
newDate¶
newDate¶
newDateTime¶
-
public static DateTime
newDateTime
(LocalDate localDate, int hour, int minute, int second)¶ Creates new instance of
DateTime
.Parameters: - localDate – the date to be stored in created instance
- hour – the hour to be stored in created instance
- minute – the minute to be stored in created instance
- second – the second to be stored in created instance
Returns: the instance of
DateTime
with given date and time
newDateTime¶
newDateTime¶
newDateTime¶
newDateTime¶
newDateTime¶
newDateTime¶
-
public static DateTime
newDateTime
(int year, int month, int day, int hour, int minute, int second)¶ Creates new
DateTime
from given information.Parameters: - year – the year to be stored
- month – the month to be stored
- day – the day to be stored
- hour – the hour to be stored
- minute – the minute to be stored
- second – the second to be stored
Returns: the new
DateTime
instance
nextApplicableWeekDay¶
nextApplicableWeekDayIncludingFromDate¶
-
public static DateTime
nextApplicableWeekDayIncludingFromDate
(DateTime fromDate, List<DayOfWeek> applicableDays)¶ Returns first next applicable week day(including current day).
Parameters: - fromDate – the date from which next day should be searched
- applicableDays – list of applicable days
Returns: next applicable week day
now¶
nowUTC¶
setTimeZone¶
setTimeZoneUTC¶
time¶
toDate¶
-
public static Date
toDate
(DateTime dateTime)¶ Converts the provided
DateTime
to aDate
using theDateTime.toDate()
method. This method is null safe and will return null for a null datetime.Parameters: - dateTime – the datetime to convert
Returns: the datetime converted to a date, or null if null was passed
toDateTimeAtStartOfDay¶
-
public static DateTime
toDateTimeAtStartOfDay
(LocalDate localDate)¶ Converts the provided
LocalDate
to aDateTime
using theLocalDate.toDateTimeAtStartOfDay()
method. This method is null safe and will return null for a null datetime.Parameters: - localDate – the local date to convert
Returns: the local date converted to a datetime, or null if null was passed
today¶
JodaFormatter¶
-
public class
JodaFormatter
¶ Class responsible for parsing and formatting several classes from
org.joda.time
package.
Methods¶
formatDateTime¶
formatPeriod¶
parse¶
-
public Period
parse
(String intervalString, Locale locale)¶ Parses time interval in different units, eg: “1 year”
Parameters: - intervalString – time interval format number: integer unit : year, month, week, day, hour, minute, second (can use plural forms also) currently compound units like 1 year and 2 months are not supported
- locale – the locale to be used when parsing given
String
Returns: the given
String
parsed toimport org.joda.time.Period
parseDateTime¶
parsePeriod¶
-
public Period
parsePeriod
(String intervalString)¶ Parses time interval in different units, eg: “1 year”
Parameters: - intervalString – time interval format number: integer unit : year, month, week, day, hour, minute, second (can use plural forms also) currently compound units like 1 year and 2 months are not supported
Returns: the given
String
parsed toimport org.joda.time.Period
org.motechproject.commons.date.util.datetime¶
DateTimeSource¶
-
public interface
DateTimeSource
¶ A datetime source for the application. Allows mocking of time.
Methods¶
now¶
-
DateTime
now
()¶ Used for retrieving the current date and time.
Returns: org.joda.time.DateTime
representing the current date and time
timeZone¶
-
DateTimeZone
timeZone
()¶ Returns the timezone we are in.
Returns: the timezone
today¶
-
LocalDate
today
()¶ Used for retrieving the current date.
Returns: org.joda.time.DateTime
representing the current date
DefaultDateTimeSource¶
-
public class
DefaultDateTimeSource
implements DateTimeSource¶ Default implementation of
DateTimeSource
.
org.motechproject.commons.sql.service¶
SqlDBManager¶
-
public interface
SqlDBManager
¶ Classes implementing this interface are responsible for retrieving sql properties from the bootstrap configuration, updating sql-related properties for modules and creating databases for given properties.
Methods¶
checkForDatabase¶
createDatabase¶
getChosenSQLDriver¶
getSqlProperties¶
-
Properties
getSqlProperties
(Properties propertiesToUpdate)¶ Being passed raw properties, inserts correct SQL configuration in the correct places. Current replacement codes are:
- ${sql.driver}
- ${sql.user}
- ${sql.password}
- ${sql.url}
- ${sql.quartz.delegateClass}
As a result of calling this method, all occurrences of the above keys get replaced with actual sql properties, retrieved from the provided bootstrap configuration.
Parameters: - propertiesToUpdate – Raw properties, containing replacement codes
Throws: - IOException – In case an I/O exception occurs when loading / merging properties
Returns: Actual properties, with sql configuration from bootstrap
hasColumn¶
-
boolean
hasColumn
(String database, String table, String column)¶ Checks whether table with the given name has a column with the given name.
Parameters: - table – the name of the table
- column – the name of the column
Throws: - SQLException – when incorrect data was given
Returns: true if the table has that column, false otherwise
org.motechproject.commons.sql.util¶
org.motechproject.config¶
SettingsFacade¶
-
public class
SettingsFacade
¶ SettingsFacade provides an interface to access application configuration present in files or database.
Methods¶
areConfigurationSettingsRegistered¶
-
public boolean
areConfigurationSettingsRegistered
()¶ Checks if configuration settings have been registered.
Returns: true if setting have been registered, false otherwise
asProperties¶
-
public Properties
asProperties
()¶ Converts stored configuration to
Properties
.Returns: the configuration as Properties
findFilename¶
getPlatformSettings¶
-
public MotechSettings
getPlatformSettings
()¶
getProperties¶
-
public Properties
getProperties
(String filename)¶ Returns properties from a resource with given filename.
Parameters: - filename – the resource filename
Returns: properties stored in the file
getProperty¶
getRawConfig¶
-
public InputStream
getRawConfig
(String filename)¶ Allows to retrieve raw JSON data either from the database or file.
Parameters: - filename – Resource filename
Throws: - org.motechproject.commons.api.MotechException – when I/O error occurs
Returns: Raw JSON data as InputStream
getResourceFileName¶
registerAllProperties¶
-
protected void
registerAllProperties
()¶ Registers all the properties to the configuration service.
registerAllRawConfig¶
-
protected void
registerAllRawConfig
()¶ Registers all raw configurations to the configuration service.
registerProperties¶
-
protected void
registerProperties
(String filename, Properties properties)¶ Registers properties from file with given name to the configuration service.
Parameters: - filename – the name of the file with properties
- properties – properties to be registered
saveConfigProperties¶
-
public void
saveConfigProperties
(String filename, Properties properties)¶ Saves given properties and resource filename to the configuration. If configuration properties stored in this object were already registered to the configuration service, the given properties and resource filename will also be added there.
Parameters: - filename – the resource filename
- properties – the properties to be saved
Throws: - org.motechproject.commons.api.MotechException – when I/O error occurs
savePlatformSettings¶
-
public void
savePlatformSettings
(MotechSettings settings)¶ Saves given MOTECH settings to the configuration service.
Parameters: - settings – the
MotechSettings
to be saved
- settings – the
saveRawConfig¶
-
public void
saveRawConfig
(String filename, Resource resource)¶ Allows persisting of raw JSON properties either in the database or file.
Parameters: - filename – resource filename
- resource – resource data to persist
Throws: - org.motechproject.commons.api.MotechException – when I/O error occurs
saveRawConfig¶
-
public void
saveRawConfig
(String filename, String jsonText)¶ Allows persisting of raw JSON properties either in the database or file.
Parameters: - filename – json filename
- jsonText – json data to persist
Throws: - org.motechproject.commons.api.MotechException – when I/O error occurs
setBundleContext¶
-
public void
setBundleContext
(BundleContext bundleContext)¶
org.motechproject.config.core.constants¶
org.motechproject.config.core.domain¶
AbstractDBConfig¶
-
public abstract class
AbstractDBConfig
¶ This abstract class encapsulates the database configuration, composed of as db url, username and password.
Constructors¶
BootstrapConfig¶
-
public class
BootstrapConfig
¶ Represents the bootstrap configuration object. It is composed of:
- DBConfig - represents the database related bootstrap object.
- Configuration source - represents the source of configuration (FILE / UI).
- ActiveMq Config - represents the properties of ActiveMq.
Fields¶
Constructors¶
BootstrapConfig¶
-
public
BootstrapConfig
(SQLDBConfig sqlConfig, ConfigSource configSource, String osgiFrameworkStorage, String motechDir, String queueUrl)¶ Constructor.
Parameters: - sqlConfig – the configuration of a SQL database
- configSource – the source from which MOTECH configuration should be read
- osgiFrameworkStorage – the directory used as the bundle cache
- motechDir – the motech main directory
- queueUrl – the URL of the JMS broker
BootstrapConfig¶
-
public
BootstrapConfig
(SQLDBConfig sqlConfig, ConfigSource configSource, String osgiFrameworkStorage, String motechDir, String queueUrl, Properties activeMqProperties)¶ Constructor.
Parameters: - sqlConfig – the configuration of a SQL database
- configSource – the source from which MOTECH configuration should be read
- osgiFrameworkStorage – the directory used as the bundle cache
- motechDir – the motech main directory
- queueUrl – the URL of the JMS broker
- activeMqProperties – the ActiveMQ properties
Throws: - MotechConfigurationException – if sqlConfig is null.
Methods¶
getActiveMqProperties¶
-
public Properties
getActiveMqProperties
()¶
getConfigSource¶
-
public ConfigSource
getConfigSource
()¶
getSqlConfig¶
-
public SQLDBConfig
getSqlConfig
()¶
ConfigLocation¶
-
public class
ConfigLocation
¶ Defines a MOTECH configuration location. If the given location starts with a leading file separator character, the location is treated as a file system directory. Otherwise, it is treated as a classpath location.
Constructors¶
Methods¶
getFile¶
-
public File
getFile
(String fileName, FileAccessType accessType)¶ This method Returns the
java.io.File
object for the given file name relative to the config location. It also checks for the requested file accessibility. If the requested access type check isorg.motechproject.config.core.domain.ConfigLocation.FileAccessType.READABLE
, the file’s existence and readability will be checked. Similarly, if the requested access type check isConfigLocation.FileAccessType.WRITABLE
, then the write accessibility to the file will be checked. If the file does not exists, write accessibility of its ancestors will be checked.Parameters: - fileName – Name of the file to be added to the config location.
- accessType – One of
ConfigLocation.FileAccessType.READABLE
orConfigLocation.FileAccessType.WRITABLE
.
Throws: - MotechConfigurationException – if the file is not readable or writable depending on the given access type.
Returns: File relative to the config location.
getUrlResource¶
-
public UrlResource
getUrlResource
()¶ Throws: - MalformedURLException – if the location is not a valid url
Returns: UrlResource
instance representing this config location
toResource¶
ConfigLocation.FileAccessType¶
-
public enum
FileAccessType
¶ Defines the access check required.
Enum Constants¶
READABLE¶
-
public static final ConfigLocation.FileAccessType
READABLE
¶
WRITABLE¶
-
public static final ConfigLocation.FileAccessType
WRITABLE
¶
ConfigSource¶
-
public final class
ConfigSource
¶ Represents the source from which MOTECH configuration should be read.
Methods¶
isFile¶
-
public boolean
isFile
()¶ Checks whether this configuration source is FILE or not.
Returns: true if this configuration source is file, false otherwise
isValid¶
valueOf¶
-
public static ConfigSource
valueOf
(String name)¶ Creates proper object of
ConfigSource
class for given name. The correct values are “UI” and “FILE”. If name isn’t one of above MotechConfigurationException will be thrown.Parameters: - name – the name of the configuration source, null and blank String treated as “UI”
Throws: - MotechConfigurationException – when name is neither “FILE” nor “UI”
Returns: proper instance of
ConfigSource
DBConfig¶
-
public class
DBConfig
extends AbstractDBConfig¶ DBConfig encapsulates the database configuration, composed of as db url, username and password.
SQLDBConfig¶
-
public class
SQLDBConfig
extends AbstractDBConfig¶ This class encapsulates the SQL database configuration, composed of as db url, username and password.
Constructors¶
SQLDBConfig¶
-
public
SQLDBConfig
(String url, String driver, String username, String password)¶ Constructor.
Parameters: - url – the URL to the database
- driver – the driver class name for the database
- username – the username for the database
- password – the password for the database
Throws: - MotechConfigurationException – if given url is invalid.
org.motechproject.config.core.exception¶
MotechConfigurationException¶
-
public class
MotechConfigurationException
extends RuntimeException¶ The object of this class is thrown when there is a problem with reading the configuration from the predefined sources.
org.motechproject.config.core.filters¶
org.motechproject.config.core.service¶
CoreConfigurationService¶
-
public interface
CoreConfigurationService
¶ Loads and saves the core configuration required to start the Motech instance.
Methods¶
addConfigLocation¶
evictMotechCoreSettingsCache¶
-
void
evictMotechCoreSettingsCache
()¶ Removes all cached MOTECH settings.
getActiveMqConfig¶
-
Properties
getActiveMqConfig
()¶ Returns the ActiveMq properties.
Returns: activeMq properties.
getConfigLocation¶
-
ConfigLocation
getConfigLocation
()¶ Returns the config location where all the config files are present.
Returns: configLocation.
loadBootstrapConfig¶
-
BootstrapConfig
loadBootstrapConfig
()¶ Loads the bootstrap configuration.
Returns: bootstrap configuration.
loadDatanucleusDataConfig¶
-
Properties
loadDatanucleusDataConfig
()¶ Loads the datanucleus configuration for data database
Returns: datanucleus configuration for data database
loadDatanucleusSchemaConfig¶
-
Properties
loadDatanucleusSchemaConfig
()¶ Loads the datanucleus configuration for schema database
Returns: datanucleus configuration for schema database
loadFlywayDataConfig¶
-
Properties
loadFlywayDataConfig
()¶ Loads the Flyway configuration for the data database.
Returns: Flyway configuration for the data database
loadFlywaySchemaConfig¶
-
Properties
loadFlywaySchemaConfig
()¶ Loads the Flyway configuration for the schema database.
Returns: Flyway configuration for the schema database
saveBootstrapConfig¶
-
void
saveBootstrapConfig
(BootstrapConfig bootstrapConfig)¶ Saves the bootstrap configuration
Parameters: - bootstrapConfig – Bootstrap config
org.motechproject.config.core.utils¶
ConfigPropertiesUtils¶
-
public final class
ConfigPropertiesUtils
¶ A utility class for loading properties.
Methods¶
createPropertiesConfiguration¶
-
public static PropertiesConfiguration
createPropertiesConfiguration
(String basePath, String fileName)¶ Creates
PropertiesConfiguration
in the given path if it does not existParameters: - basePath – path to the file with config
- fileName – name of the file with config
Returns: PropertiesConfiguration
from the given path
getDefaultPropertiesFile¶
-
public static File
getDefaultPropertiesFile
(ConfigLocation.FileAccessType accessType, Iterable<ConfigLocation> configLocations, String fileName)¶ Returns default config file location.
Parameters: - accessType – the access required for returned File object
- configLocations – the config locations specified by MOTECH in config-locations.properties
- fileName – the file name
getPropertiesFromFile¶
-
public static Properties
getPropertiesFromFile
(File file)¶ Loads the properties from given
File
.Parameters: - file – the file with properties
Throws: - IOException – if I/O error occurred
Returns: the loaded properties
getPropertiesFromSystemVarString¶
-
public static Properties
getPropertiesFromSystemVarString
(String string)¶ Loads the properties from given
String
. The format of thisString
should be “key1=value1;key2=value2;key3=value3;...”.Parameters: - string – the string with properties
Returns: the loaded properties
saveConfig¶
-
public static void
saveConfig
(File file, Properties properties)¶ Saves properties to the given
File
.Parameters: - file – the file
- properties –
org.motechproject.config.core.validator¶
QueueURLValidator¶
-
public class
QueueURLValidator
¶ Validates presence of Queue URL and if present whether it is in expected format or not
Constructors¶
QueueURLValidator¶
-
public
QueueURLValidator
(UrlValidator urlValidator)¶
Methods¶
validate¶
-
public void
validate
(String queueUrl)¶ Checks whether given URL is valid.
Parameters: - queueUrl – the URL to be validated
Throws: - MotechConfigurationException – if queueUrl is null, empty or invalid
org.motechproject.config.domain¶
LoginMode¶
-
public final class
LoginMode
¶ Encapsulates the operations on login mode.
Fields¶
Methods¶
isOpenId¶
-
public boolean
isOpenId
()¶ Checks if this login mode is set to “Open ID”.
Returns: true if this login mode is set to “Open ID”, false otherwise
isRepository¶
-
public boolean
isRepository
()¶ Checks if this login mode is set to “Repository”.
Returns: true if this login mode is set to “Repository”, false otherwise
valueOf¶
-
public static LoginMode
valueOf
(String loginMode)¶ Creates proper login mode from given
String
, which can be either “repository” or “openId”.Parameters: - loginMode – the login mode to be created, must be either “repository” or “openId”, other values will return null
Returns: the proper object of
LoginMode
, null if given value was neither “repository” nor “openId”
ModulePropertiesRecord¶
-
public class
ModulePropertiesRecord
¶ Class representing a record of a certain module properties. This class is exposed as an
org.motechproject.mds.annotations.Entity
through Motech Data Services.See also:
org.motechproject.mds.annotations
Constructors¶
ModulePropertiesRecord¶
-
public
ModulePropertiesRecord
(Map<String, Object> properties, String bundle, String version, String filename, boolean raw)¶ Constructor.
Parameters: - properties – the module properties
- bundle – the modules bundle symbolic name
- version – the version of the module
- filename – the name of the file containing module properties
- raw – the flag defining whether the properties are raw or not
ModulePropertiesRecord¶
-
public
ModulePropertiesRecord
(Properties props, String bundle, String version, String filename, boolean raw)¶ Constructor.
Parameters: - props – the module properties
- bundle – the modules bundle symbolic name
- version – the version of the module
- filename – the name of the file containing modules properties
- raw – the flag defining whether the properties are raw or not
Methods¶
buildFrom¶
-
public static ModulePropertiesRecord
buildFrom
(File file)¶ Builds an instance of
ModulePropertiesRecord
from given file. Content of the file must match format specified inProperties.load(Reader)
. Properties files are treated as raw configuration files.Parameters: - file – the source file, null returns null
Returns: the instance of
ModulePropertiesRecord
, null if error occurred
sameAs¶
MotechSettings¶
-
public interface
MotechSettings
¶ Interface for main MOTECH settings management.
Methods¶
asProperties¶
-
Properties
asProperties
()¶ Converts this MOTECH setting to
Properties
.Returns: this object as Properties
getFailureLoginLimit¶
getMinPasswordLength¶
getNumberOfDaysForReminder¶
getNumberOfDaysToChangePassword¶
getPasswordValidator¶
getSessionTimeout¶
isPasswordResetReminderEnabled¶
-
boolean
isPasswordResetReminderEnabled
()¶ Checks whether the reminding about password reset is enabled.
Returns: true when the reminding is enabled
isPlatformInitialized¶
-
boolean
isPlatformInitialized
()¶ Checks whether platform is initialized.
Returns: true if platform is initialized, false otherwise
load¶
-
void
load
(DigestInputStream dis)¶ Loads the properties from given stream and stores them withing this object.
Parameters: - dis – the source stream
Throws: - IOException – when I/O error occurs
savePlatformSetting¶
setFailureLoginLimit¶
-
void
setFailureLoginLimit
(int limit)¶ Sets the failure login limit. After reaching this limit user will be blocked. If 0 then blocking will be disabled.
Parameters: - limit – the failure login limit
setMinPasswordLength¶
setNumberOfDaysForReminder¶
setNumberOfDaysToChangePassword¶
setPasswordResetReminder¶
setPasswordValidator¶
setSessionTimeout¶
-
void
setSessionTimeout
(Integer sessionTimeout)¶ Sets the http session timeout for Motech users. Users will be logged out after reaching this timeout. This value is specified in seconds. A negative value specifies that sessions should never time out.
Parameters: - sessionTimeout – the http session timeout, in seconds
updateFromProperties¶
-
void
updateFromProperties
(Properties props)¶ Updates this object with given properties.
Parameters: - props – properties to be applied
updateSettings¶
-
void
updateSettings
(String configFileChecksum, String filePath, Properties platformSettings)¶ Updates settings with given information.
Parameters: - configFileChecksum – the configuration file checksum to be set
- filePath – the file path to be set
- platformSettings – the platform settings to be add
SettingsRecord¶
-
public class
SettingsRecord
implements MotechSettings¶ Class for storing settings values.
Methods¶
asProperties¶
-
public Properties
asProperties
()¶
load¶
-
public synchronized void
load
(DigestInputStream dis)¶
mergeWithDefaults¶
-
public void
mergeWithDefaults
(Properties defaultConfig)¶ Merges given default configuration into existing platform settings. Keys that already exists won’t be overwritten.
Parameters: - defaultConfig – the default configuration to be merged.
removeDefaults¶
-
public void
removeDefaults
(Properties defaultConfig)¶ Removes settings specified in defaultConfig.
Parameters: - defaultConfig –
updateFromProperties¶
-
public void
updateFromProperties
(Properties props)¶
updateSettings¶
-
public void
updateSettings
(String configFileChecksum, String filePath, Properties platformSettings)¶
org.motechproject.config.mds¶
BundlePropertiesDataService¶
-
public interface
BundlePropertiesDataService
extends MotechDataService<ModulePropertiesRecord>¶ This service provides data access for
org.motechproject.config.domain.ModulePropertiesRecord
. The implementation is generated by Motech Data Services and published as an OSGi service.
Methods¶
findByBundle¶
-
List<ModulePropertiesRecord>
findByBundle
(String bundle)¶ Returns list of
ModulePropertiesRecord
s matching given bundle symbolic name.Parameters: - bundle – the bundle symbolic name
Returns: list of
ModulePropertiesRecord
s
findByBundleAndFileName¶
-
List<ModulePropertiesRecord>
findByBundleAndFileName
(String bundle, String filename)¶ Returns a list of
ModulePropertiesRecord
s matching given bundle symbolic name and file name.Parameters: - bundle – the bundle symbolic name
- filename – the name of the file
Returns: list of
ModulePropertiesRecord
s
SettingsDataService¶
-
public interface
SettingsDataService
extends MotechDataService<SettingsRecord>¶ Interface for settings service. Its implementation is injected by the MDS.
org.motechproject.config.service¶
ConfigurationService¶
-
public interface
ConfigurationService
¶ Central configuration service that monitors and manages configurations.
Methods¶
addOrUpdate¶
addOrUpdateBundleRecord¶
-
void
addOrUpdateBundleRecord
(ModulePropertiesRecord record)¶ A convenient method for adding or updating the properties, which determines on its own whether the record should be added or updated
Parameters: - record – a record to store
addOrUpdateBundleRecords¶
-
void
addOrUpdateBundleRecords
(List<ModulePropertiesRecord> records)¶ Bulk add or update method for the Bundle Properties records. Iterates through the passed records and either adds them, if they are not present, or updates otherwise.
Parameters: - records – a list of properties records
addOrUpdateProperties¶
-
void
addOrUpdateProperties
(String bundle, String version, String filename, Properties newProperties, Properties defaultProperties)¶ Depending on the config source, it will either store properties in the DB or file. Only properties that are different from the default ones are stored. If the properties database record or file doesn’t exist yet for the given bundle, it will be created.
Parameters: - bundle – Symbolic name of updated bundle
- version – Version of updated bundle
- filename – Resource filename
- newProperties – New properties to store
- defaultProperties – Default properties of the bundle
Throws: - IOException – if bundle properties cannot be retrieved from file
addOrUpdateSettings¶
-
void
addOrUpdateSettings
(SettingsRecord settingsRecord)¶ Adds or updates a MOTECH settings to the settings service.
Parameters: - settingsRecord – a settings record to store
createZipWithConfigFiles¶
-
FileInputStream
createZipWithConfigFiles
(String propertyFile, String fileName)¶ Uses current configuration and default one to find changed properties and then connects them with annotations. Moreover creates file with non default configurations and packs is into the zip file.
Parameters: - propertyFile – name of exported file
Throws: - IOException –
Returns: FileInputStream that contains zip file
deleteByBundle¶
deleteByBundleAndFileName¶
getAllBundleProperties¶
-
Map<String, Properties>
getAllBundleProperties
(String bundle, Map<String, Properties> defaultProperties)¶ Retrieves all the bundle properties and returns them as Map, where key is the filename.
Parameters: - bundle – The bundle we wish to retrieve properties for
- defaultProperties – Default properties of the bundle
Throws: - IOException – if any of the bundle properties file cannot be read
Returns: Properties mapped by filename
getBundleProperties¶
-
Properties
getBundleProperties
(String bundle, String filename, Properties defaultProperties)¶ Retrieves merged properties, given default set. Depending on the ConfigSource, it will either merge default properties with the properties from DB or get properties from file.
Parameters: - bundle – The bundle we wish to retrieve properties for
- filename – Resource filename
- defaultProperties – Default properties of the bundle
Throws: - IOException – if bundle properties cannot be read from file
Returns: Merged properties of the certain bundle
getConfigSource¶
-
ConfigSource
getConfigSource
()¶ This method allows to check whether MOTECH is currently running in the FILE or UI mode
Returns: Current Config Source
getPlatformSettings¶
-
MotechSettings
getPlatformSettings
()¶
getRawConfig¶
-
InputStream
getRawConfig
(String bundle, String filename, Resource resource)¶ Allows to retrieve raw JSON data either from the database or file, depending on the specified ConfigSource mode.
Parameters: - bundle – Bundle we wish to retrieve raw data for
- filename – Resource filename
- resource – Resource file containing default rawConfig, in case no other has been found
Throws: - IOException –
Returns: Raw JSON data as InputStream
listRawConfigNames¶
-
List<String>
listRawConfigNames
(String bundle)¶ Depending on the selected ConfigSource mode, this method looks for all registered raw data properties within the specified bundle.
Parameters: - bundle – Bundle we wish to perform look for
Returns: List of filenames that register raw config for specified bundle
loadBootstrapConfig¶
-
BootstrapConfig
loadBootstrapConfig
()¶ Loads bootstrap config that is used to start up the Motech server.
The bootstrap configuration is loaded in the following order:
Load the configuration from
bootstrap.properties
from the config directory specified by the environment variableMOTECH_CONFIG_DIR
.bootstrap.properties
contains the following properties:sql.url (Mandatory) sql.driver (Mandatory) sql.username (If required) sql.password (If required) config.source (Optional. Defaults to 'UI')
An example
bootstrap.properties
is given below:sql.url=jdbc:mysql://localhost:3306/ sql.driver=com.mysql.jdbc.Driver sql.username=motech sql.password=motech config.source=FILE
If
MOTECH_CONFIG_DIR
environment variable is not set, load the specific configuration values from the following environment variables:MOTECH_SQL_URL (Mandatory) MOTECH_SQL_DRIVER (Mandatory) MOTECH_SQL_USERNAME (If required) MOTECH_SQL_PASSWORD (If required) MOTECH_CONFIG_SOURCE (Optional. Defaults to 'UI')
If
MOTECH_DB_URL
environment is not set, load the configuration frombootstrap.properties
from the default MOTECH config directory specified in the fileconfig-locations.properties
.
Throws: - MotechConfigurationException – if bootstrap configuration cannot be loaded.
Returns: Bootstrap configuration
loadConfig¶
-
SettingsRecord
loadConfig
()¶ Loads current MOTECH configuration
Returns: current MOTECH settings
loadDefaultConfig¶
-
SettingsRecord
loadDefaultConfig
()¶ Loads the default config for MOTECH from the resource file.
Returns: default settings
processExistingConfigs¶
rawConfigExists¶
registersProperties¶
removeAllBundleProperties¶
removeBundleRecords¶
-
void
removeBundleRecords
(List<ModulePropertiesRecord> records)¶ Removes given bundle properties records
Parameters: - records – a list of properties records to remove
requiresConfigurationFiles¶
-
boolean
requiresConfigurationFiles
()¶ Checks whether set MOTECH configuration requires the configuraton files to be present
Returns: true if files are required, false otherwise
retrieveRegisteredBundleNames¶
save¶
-
void
save
(BootstrapConfig bootstrapConfig)¶ Saves the given
BootstrapConfig
in thebootstrap.properties
file located in default MOTECH config location. The default motech config location is specified in the fileconfig-locations.properties
.Parameters: - bootstrapConfig – Bootstrap configuration.
Throws: - MotechConfigurationException – if bootstrap configuration cannot be saved.
savePlatformSettings¶
-
void
savePlatformSettings
(Properties settings)¶ Saves given platform settings to the settings service. Available platform settings are language, login mode, provider name, provider URL, server URL, status message timeout, and upload size.
Parameters: - settings – the settings to be saved
savePlatformSettings¶
-
void
savePlatformSettings
(MotechSettings settings)¶ Saves given MOTECH settings to the settings service.
Parameters: - settings – the settings to be saved
saveRawConfig¶
-
void
saveRawConfig
(String bundle, String version, String filename, InputStream rawData)¶ Allows persisting of raw json properties either in the database or file, depending on the selected ConfigSource mode.
Parameters: - bundle – Bundle we wish to save properties for
- filename – Resource filename
- rawData – Raw JSON data to persist
Throws: - IOException –
setPlatformSetting¶
updateConfigLocation¶
updatePropertiesAfterReinstallation¶
-
void
updatePropertiesAfterReinstallation
(String bundle, String version, String filename, Properties defaultProperties, Properties newProperties)¶ Works similar to
addOrUpdateProperties
but instead of just adding / updating properties checks database for any deprecated properties and removes to ensure that only current ones are availableParameters: - bundle – Symbolic name of updated bundle
- version – Version of updated bundle
- filename – Resource filename
- newProperties – New properties to store
- defaultProperties – Default properties of the bundle
Throws: - IOException – if bundle properties cannot be retrieved from file
org.motechproject.email.builder¶
EmailRecordSearchCriteria¶
-
public class
EmailRecordSearchCriteria
¶ The
EmailRecordSearchCriteria
class represents search criteria that may be used for searchingorg.motechproject.email.domain.EmailRecord
entities in Motech Data Services. A consumer of this class may create search criteria to query on multiple fields by calling several of the with* methods. To perform the search, useorg.motechproject.email.service.EmailAuditService.findEmailRecords(EmailRecordSearchCriteria)
.
Methods¶
getDeliveryStatuses¶
-
public Set<DeliveryStatus>
getDeliveryStatuses
()¶ Gets the delivery statuses criterion.
Returns: the delivery statuses criterion for this search criteria
getDeliveryTimeRange¶
getFromAddress¶
getMessage¶
getQueryParams¶
-
public QueryParams
getQueryParams
()¶ Gets the query paramaters that are used for controlling order and size of the query results for this search criteria.
Returns: the query params for this search criteria
getSubject¶
getToAddress¶
withDeliveryStatuses¶
-
public EmailRecordSearchCriteria
withDeliveryStatuses
(Set<DeliveryStatus> deliveryStatuses)¶ Sets the delivery statuses criterion to the set specified
Parameters: - deliveryStatuses – the delivery statuses on which to search
Returns: this
EmailRecordSearchCriteria
with its deliveryStatuses criterion set to the provided statuses
withDeliveryStatuses¶
-
public EmailRecordSearchCriteria
withDeliveryStatuses
(DeliveryStatus... deliveryStatuses)¶ Sets the delivery statuses criterion to the set specified
Parameters: - deliveryStatuses – the delivery statuses on which to search
Returns: this
EmailRecordSearchCriteria
with its deliveryStatuses criterion set to the provided statuses
withFromAddress¶
-
public EmailRecordSearchCriteria
withFromAddress
(String fromAddress)¶ Sets the fromAddress criterion to the address specified
Parameters: - fromAddress – the sender email address on which to search
Returns: this
EmailRecordSearchCriteria
with its fromAddress criterion set to the provided address
withMessage¶
-
public EmailRecordSearchCriteria
withMessage
(String message)¶ Sets the message criterion to the message specified
Parameters: - message – the email message body on which to search
Returns: this
EmailRecordSearchCriteria
with its message criterion set to the provided message
withMessageTime¶
-
public EmailRecordSearchCriteria
withMessageTime
(DateTime deliveryTimeRange)¶ Sets the send time criterion to the time specified. Use this method to search on a specific date/time; if a range is needed, use
withMessageTimeRange
instead.Parameters: - deliveryTimeRange – the specific time on which to search
Returns: this
EmailRecordSearchCriteria
with its deliveryTimeRange criterion set to the specified date/time
withMessageTimeRange¶
-
public EmailRecordSearchCriteria
withMessageTimeRange
(Range<DateTime> deliveryTimeRange)¶ Sets the sent time criterion to the range specified. Use this method to search on a time range; if searching on a specific date/time is needed, use
withMessageTime
instead.Parameters: - deliveryTimeRange – the date/time range on which to search
Returns: this
EmailRecordSearchCriteria
with its deliveryTimeRange criterion set to the specified date/time range
withQueryParams¶
-
public EmailRecordSearchCriteria
withQueryParams
(QueryParams queryParams)¶ Sets the queryParams of the search criteria to the parameters specified. Use this method when it is necessary to specify order and size of query results. This is used mainly for paging/ordering queries from the UI.
Parameters: - queryParams – the query parameters to include with the search criteria
Returns: this
EmailRecordSearchCriteria
with its queryParams set to the provided parameters
withSubject¶
-
public EmailRecordSearchCriteria
withSubject
(String subject)¶ Sets the subject criterion to the subject specified
Parameters: - subject – the subject on which to search
Returns: this
EmailRecordSearchCriteria
with its subject criterion set to the provided subject
withToAddress¶
-
public EmailRecordSearchCriteria
withToAddress
(String toAddress)¶ Sets the toAddress criterion to the address specified
Parameters: - toAddress – the recipient email address on which to search
Returns: this
EmailRecordSearchCriteria
with its toAddress criterion set to the provided address
org.motechproject.email.domain¶
DeliveryStatus¶
-
public enum
DeliveryStatus
¶ The
DeliveryStatus
Enum contains the possible delivery states for an email message.
Enum Constants¶
ERROR¶
-
public static final DeliveryStatus
ERROR
¶ There was an error sending the message.
RECEIVED¶
-
public static final DeliveryStatus
RECEIVED
¶ The message was received.
SENT¶
-
public static final DeliveryStatus
SENT
¶ The message was sent.
EmailRecord¶
-
public class
EmailRecord
¶ The
EmailRecord
class represents a record of a sent Email. This class is exposed as anorg.motechproject.mds.annotations.Entity
through Motech Data Services.See also:
org.motechproject.mds.annotations
Constructors¶
EmailRecord¶
-
public
EmailRecord
()¶ Creates a new instance of
EmailRecord
, with all fields set to null.
EmailRecord¶
-
public
EmailRecord
(String fromAddress, String toAddress, String subject, String message, DateTime deliveryTime, DeliveryStatus deliveryStatus)¶ Creates a new instance of
EmailRecord
, with all fields set to the values specified in the parameters.Parameters: - fromAddress – the email address of the sender
- toAddress – the email address of the recipient
- subject – the subject of the email
- message – the body of the email
- deliveryTime – the date and time that the email was sent
- deliveryStatus – the delivery status of the email
Methods¶
equals¶
-
public boolean
equals
(Object obj)¶ Indicates whether some other object is “equal to” this one. Returns true if this EmailRecord and the object to compare have reference equality or their field values are all equal.
Parameters: - obj – The reference object with which to compare.
Returns: true if this object is the same as the obj argument; false otherwise.
getDeliveryStatus¶
-
public DeliveryStatus
getDeliveryStatus
()¶ Gets the delivery status.
Returns: the delivery status of the message
getDeliveryTime¶
getFromAddress¶
getSubject¶
getToAddress¶
hashCode¶
-
public int
hashCode
()¶ Returns a hash code value for this
EmailRecord
object.Returns: a hash code value for this EmailRecord
object
setFromAddress¶
setMessage¶
setSubject¶
setToAddress¶
EmailRecordComparator¶
-
public class
EmailRecordComparator
implements Comparator<EmailRecord>¶ The
EmailRecordComparator
class is an implementation of the Comparator interface, that allows callers to compareorg.motechproject.email.domain.EmailRecord
objects by a single field.
Constructors¶
EmailRecordComparator¶
-
public
EmailRecordComparator
(Boolean ascending, String compareField)¶ Creates a new
EmailRecordComparator
that supports comparison based on the specified field.Parameters: - ascending – boolean indicating whether comparisons should be ascending or descending
- compareField – the field for which comparisons should be performed
Methods¶
compare¶
-
public int
compare
(EmailRecord o1, EmailRecord o2)¶ Compares its two arguments for order. If ascending is
true
, returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. If ascending isfalse
, returns a positive integer, zero, or negative integer as the first argument is less than, equal to, or greater than the second.Parameters: - o1 – the first
EmailRecord
to be compared - o2 – the second
EmailRecord
to be compared
Returns: a positive integer, zero, or negative integer indicating the result of comparing the objects
- o1 – the first
EmailRecords¶
-
public class
EmailRecords
<T>¶ The
EmailRecords
class wraps theEmailRecord
list and stores the current item count.
Constructors¶
EmailRecords¶
-
public
EmailRecords
()¶ Creates a new instance of
EmailRecords
, which contains no records.
EmailRecords¶
-
public
EmailRecords
(Integer totalRecords, Integer page, Integer totalPages, List<T> allRecords)¶ Creates a new instance of
EmailRecords
, with all fields set to the values specified in the parameters. Thepage
andtotalPages
parameters are for the purposes of paginating the list of records in the UI.Parameters: - totalRecords – the total number of records
- page – the current page
- totalPages – the total number of pages
- allRecords – the list of records
Mail¶
-
public class
Mail
¶ The
Mail
class represents an email message.
Constructors¶
Mail¶
-
public
Mail
(String fromAddress, String toAddress, String subject, String message)¶ Creates a new instance of
Mail
, with all fields set to the values specified in the parameters.Parameters: - fromAddress – the email address of the sender
- toAddress – the email address of the recipient
- subject – the subject of the email
- message – the body of the email
Methods¶
equals¶
-
public boolean
equals
(Object obj)¶ Indicates whether some other object is “equal to” this one. Returns true if this Mail and the object to compare have reference equality or their field values are all equal.
Parameters: - obj – The reference object with which to compare
Returns: true if this object is the same as the obj argument; false otherwise.
getFromAddress¶
getSubject¶
getToAddress¶
org.motechproject.email.exception¶
org.motechproject.email.service¶
EmailAuditService¶
-
public interface
EmailAuditService
¶ The
EmailAuditService
interface provides methods for logging email activity, as well as searching and deleting the email logs.
Methods¶
countEmailRecords¶
-
long
countEmailRecords
(EmailRecordSearchCriteria criteria)¶ Returns the count of
EmailRecord
entries matching the specified search criteria.Returns: the count of email records matching the provided criteria
delete¶
-
void
delete
(EmailRecord emailRecord)¶ Deletes the specified
EmailRecord
entry from the email log.
findAllEmailRecords¶
-
List<EmailRecord>
findAllEmailRecords
()¶ Finds and returns all
EmailRecord
entries in the email log.Returns: all email records in the email log
findById¶
-
EmailRecord
findById
(long id)¶ Finds an
EmailRecord
in the log by ID.Parameters: - id – the identifier of the record to find
Returns: the email record that matches the provided identifier, or null if no matching record exists
findEmailRecords¶
-
List<EmailRecord>
findEmailRecords
(EmailRecordSearchCriteria criteria)¶ Finds and returns all
EmailRecord
entries matching the specified search criteria.Returns: all email records matching the provided criteria
EmailRecordService¶
-
public interface
EmailRecordService
extends MotechDataService<EmailRecord>¶ This service provides data access for
org.motechproject.email.domain.EmailRecord
. The implementation is generated by Motech Data Services and published as an OSGi service.
Methods¶
countFind¶
-
long
countFind
(String fromAddress, String toAddress, String subject, String message, Range<DateTime> deliveryTimeRange, Set<DeliveryStatus> deliveryStatuses)¶ Returns the count of all
EmailRecord
entries matching the specified search parameters.Parameters: - fromAddress – the sender address on which to search
- toAddress – the recipient address on which to search
- subject – the subject on which to search
- message – the message body on which to search
- deliveryTimeRange – the delivery time range on which to search
- deliveryStatuses – the delivery statuses on which to search
Returns: the count of
EmailRecord
entries that match the specified criteria
find¶
-
List<EmailRecord>
find
(String fromAddress, String toAddress, String subject, String message, Range<DateTime> deliveryTimeRange, Set<DeliveryStatus> deliveryStatuses, QueryParams queryParams)¶ Finds and returns all
EmailRecord
entries matching the specified search parameters. This method is exposed as aorg.motechproject.mds.annotations.Lookup
through Motech Data Services.Parameters: - fromAddress – the sender address on which to search
- toAddress – the recipient address on which to search
- subject – the subject on which to search
- message – the message body on which to search
- deliveryTimeRange – the delivery time range on which to search
- deliveryStatuses – the delivery statuses on which to search
- queryParams – the query parameters to include with the search criteria
Returns: the list of
EmailRecord
entries that match the specified criteriaSee also:
org.motechproject.mds.annotations
findByRecipientAddress¶
-
List<EmailRecord>
findByRecipientAddress
(String recipientAddress)¶ Finds and returns all
EmailRecord
entries for the specified recipient address. This method is exposed as aorg.motechproject.mds.annotations.Lookup
through Motech Data Services.Parameters: - recipientAddress – the recipient address on which to search
Returns: the list of
EmailRecord
entries that match the specified addressSee also:
org.motechproject.mds.annotations
EmailSenderService¶
-
public interface
EmailSenderService
¶ The
EmailSenderService
interface provides a method for sending email.
Methods¶
send¶
-
void
send
(String fromAddress, String toAddress, String subject, String message)¶ Attempts to send the supplied email message. Adds an
org.motechproject.email.domain.EmailRecord
entry to the log with the details of the activity.Parameters: - fromAddress – the email address of the sender
- toAddress – the email address of the recipient
- subject – the subject of the email
- message – the body of the email
org.motechproject.event¶
MotechEvent¶
-
public class
MotechEvent
implements Serializable¶ Motech Scheduled Event data carrier class. It contains a subject, to which listeners can subscribe and a payload in the form of a map of parameters. Instance of this class with event specific data will be sent by Motech Scheduler when a scheduled event is fired.
This class is immutable
Constructors¶
MotechEvent¶
MotechEvent¶
-
public
MotechEvent
(String subject, Map<String, Object> parameters)¶ Constructs a MotechEvent with the given subject and parameters.
Parameters: - subject – the subject of the event
- parameters – the map of additional parameters
Throws: - IllegalArgumentException – if the subject is null or contains
'*', '..'
MotechEvent¶
-
public
MotechEvent
(String subject, Map<String, Object> parameters, String callbackName)¶ Constructs a MotechEvent with the given subject, parameters and the callback name.
Parameters: - subject – the subject of the event
- parameters – the map of additional parameters
- callbackName – the name of the callback
Throws: - IllegalArgumentException – if the subject is null or contains
'*', '..'
MotechEvent¶
-
public
MotechEvent
(String subject, Map<String, Object> parameters, String callbackName, Map<String, Object> metadata)¶ Constructs a MotechEvent with the given subject, parameters and the callback name.
Parameters: - subject – the subject of the event
- parameters – the map of additional parameters
- callbackName – the name of the callback
- metadata – the map of event metadata
Throws: - IllegalArgumentException – if the subject is null or contains
'*', '..'
Methods¶
getCallbackName¶
getMessageDestination¶
getMessageRedeliveryCount¶
-
public int
getMessageRedeliveryCount
()¶ Returns the
redeliveryCount
. This is incremented by the event system if the delivery fails, so it is equal to the number of failed deliveries. Any exception from the handler is counted as failure in this context. It cannot be larger thanorg.motechproject.event.messaging.MotechEventConfig.messageMaxRedeliveryCount
Returns: the number of message redeliveries
getMetadata¶
getParameters¶
incrementMessageRedeliveryCount¶
-
public void
incrementMessageRedeliveryCount
()¶ Increments the
redeliveryCount
. It is invoked by the event system if the delivery fails. If it is null, sets the value to 0.
isBroadcast¶
-
public boolean
isBroadcast
()¶ Returns whether event is a broadcast event
Returns: broadcast
isDiscarded¶
-
public boolean
isDiscarded
()¶ Returns whether event is discarded
Returns: event discarded
setBroadcast¶
-
public void
setBroadcast
(boolean value)¶ Sets event as a broadcast event
Parameters: - value –
setCallbackName¶
setMessageDestination¶
setMetadata¶
org.motechproject.event.listener¶
EventCallbackService¶
-
public interface
EventCallbackService
¶ Implementing
EventCallbackService
and exposing it as OSGi service allows to receive callbacks, after the events have been handled by their respective listener. In order to invoke a callback, the name of the callback service must be set in theMotechEvent
and must match the name returned by thegetName()
method.
Methods¶
failureCallback¶
-
boolean
failureCallback
(MotechEvent event, Throwable throwable)¶ Callback method, invoked when the event handler method has thrown an exception.
Parameters: - event – the event that was being handled
- throwable – the throwable that has caused the failure
Returns: true, if the event system should proceed with retries; false otherwise
getName¶
successCallback¶
-
void
successCallback
(MotechEvent event)¶ Callback method, invoked when the event handler method has executed successfully.
Parameters: - event – the event that has been handled
EventConsumerInfo¶
-
public interface
EventConsumerInfo
¶ The
EventConsumerInfo
interface provides methods for getting information about ActiveMQ Event Consumers.
EventListener¶
-
public interface
EventListener
¶ Provides the base model interface for event listeners. In case of listeners using annotations, proxies implementing this interface are created, so there is no actual need to implement this interface when creating listeners.
Methods¶
getIdentifier¶
handle¶
-
void
handle
(MotechEvent event)¶ Handles the particular event that has been received
Parameters: - event – the event that occurred.
EventListenerRegistryService¶
-
public interface
EventListenerRegistryService
¶ Gives access to the registry of listeners for Motech events. This interface is necessary for OSGi service publication. One can register themselves to listen for a specific set of event’s subject.
Methods¶
clearListenersForBean¶
getListenerCount¶
getListeners¶
-
Set<EventListener>
getListeners
(String subject)¶ Returns all the event listeners registered for the event with the given subject. If there are no listeners, an empty list is returned.
Parameters: - subject – the subject of the event
Returns: the matching event listeners
hasListener¶
registerListener¶
-
void
registerListener
(EventListener listener, List<String> subjects)¶ Registers the event listener to be notified when events with the matching subject are received via the Server JMS Event Queue.
Parameters: - listener – the listener to be registered
- subjects – the list of subjects the listener subscribes to, wildcards are allowed
registerListener¶
-
void
registerListener
(EventListener listener, String subject)¶ Registers the event listener to be notified when the event’s subjects are received via the Server JMS Event Queue.
Parameters: - listener – the listener to be registered
- subject – the subject the listener subscribes to, wildcards are allowed
EventRelay¶
-
public interface
EventRelay
¶ The
EventRelay
interface provides methods that allow sendingorg.motechproject.event.MotechEvent
via ActiveMQ, either to the queue (ActiveMQ selects the subscriber that will handle the event) or to the topic (event is sent to every registered subscriber).
Methods¶
broadcastEventMessage¶
-
void
broadcastEventMessage
(MotechEvent motechEvent)¶ Publishes the event message in a topic. The message goes to a JMS topic, so if you have multiple Motech instances, they will all receive the event. This allows broadcasting administration-type events that should be handled by each node separately. This method should be only used if you are absolutely sure that the event should get processed by all your nodes in the cluster simultaneously. The message is then handled by all Motech instances, by calling
org.motechproject.event.listener.impl.ServerEventRelay.relayTopicEvent(MotechEvent)
service method. The message will only go to ActiveMQ if there are listeners registered for the subject (in this instance), meaning if you have clustered Motech instances, you must ensure they all have the listeners registered.Parameters: - motechEvent – the event to be broadcast
sendEventMessage¶
-
void
sendEventMessage
(MotechEvent motechEvent)¶ Publishes the event message in a queue. The message goes a JMS queue, so if you have multiple Motech instances, only one of them will be chosen by ActiveMQ as the recipient of the event. This mechanism allows achieving scalability in a cluster. This is the method to use for sending your event, unless you are absolutely sure you want the event being processed by all your nodes in the cluster simultaneously. The message is then handled by exactly one Motech instance, by calling
org.motechproject.event.listener.impl.ServerEventRelay.relayQueueEvent(MotechEvent)
service method. The message will only go to ActiveMQ if there are listeners registered for the subject (in this instance), meaning if you have clustered Motech instances, you must ensure they all have the listeners registered.Parameters: - motechEvent – the event to be sent
org.motechproject.event.listener.annotations¶
MotechListener¶
-
public @interface
MotechListener
¶ The
MotechListener
annotation is used by developers to specify which method should be invoked when an event with a particular subject will be fired.This annotation is processed by
org.motechproject.event.listener.proxy.EventAnnotationBeanPostProcessor
Author: yyonkov See also:
org.motechproject.event.listener.proxy.EventAnnotationBeanPostProcessor
MotechListenerAbstractProxy¶
-
public abstract class
MotechListenerAbstractProxy
implements EventListener¶ Represents a
MotechListener
proxy, providing access to the listener’s name, bean, method. Constructed for listeners defined using annotations.Author: yyonkov
Constructors¶
Methods¶
callHandler¶
-
public abstract void
callHandler
(MotechEvent event)¶ Calls handler for the concrete proxy.
Parameters: - event – the event which will be handled
getBean¶
getMethod¶
handle¶
-
public void
handle
(MotechEvent event)¶
MotechListenerEventProxy¶
-
public class
MotechListenerEventProxy
extends MotechListenerAbstractProxy¶ Represents the type of
MotechListener
proxy where handler is a method with theMotechEvent
parameter.Author: yyonkov
Constructors¶
Methods¶
callHandler¶
-
public void
callHandler
(MotechEvent event)¶
MotechListenerNamedParametersProxy¶
-
public class
MotechListenerNamedParametersProxy
extends MotechListenerAbstractProxy¶ Represents the type of
MotechListener
proxy where handler is a method with parameters defined by theorg.motechproject.event.listener.annotations.MotechParam
annotation.Author: yyonkov
Constructors¶
Methods¶
callHandler¶
-
public void
callHandler
(MotechEvent event)¶
MotechListenerType¶
-
public enum
MotechListenerType
¶ The enum defining types of
MotechListener
proxies.Author: yyonkov
Enum Constants¶
MOTECH_EVENT¶
-
public static final MotechListenerType
MOTECH_EVENT
¶
NAMED_PARAMETERS¶
-
public static final MotechListenerType
NAMED_PARAMETERS
¶
MotechParam¶
-
public @interface
MotechParam
¶ The
MotechParam
annotation is used by developers to specify parameters in a method which handles event. The parameters are used only in theorg.motechproject.event.listener.annotations.MotechListenerNamedParametersProxy
type of listener.This annotation is processed by
org.motechproject.event.listener.annotations.MotechListenerNamedParametersProxy.callHandler(org.motechproject.event.MotechEvent)
Author: yyonkov See also:
org.motechproject.event.listener.annotations.MotechListenerNamedParametersProxy
org.motechproject.event.messaging¶
MotechCachingConnectionFactory¶
-
public class
MotechCachingConnectionFactory
extends CachingConnectionFactory¶ Represents an extension of the CachingConnectionFactory that adds username and password support, in case the JMS broker is secured.
MotechEventConfig¶
-
public class
MotechEventConfig
¶ Accesses the
MotechEventConfig
variables.
Methods¶
getMessageMaxRedeliveryCount¶
-
public int
getMessageMaxRedeliveryCount
()¶ Returns maximum number of times a message would be re-delivered in case of any exception.
Returns: the maximum number of message redelivery
getMessageRedeliveryDelay¶
-
public long
getMessageRedeliveryDelay
()¶ Returns delay (in seconds) between successive re-deliveries of messages in case of any exception. If delay=d and first exception was raised at time=t, then successive redelivery times are t+d, t+(d*2), t+(d*4), t+(d*8), t+(d*16), t+(d*32), and so on, till maximum redelivery count is reached.
Returns: the message redelivery delay
OutboundEventGateway¶
-
public interface
OutboundEventGateway
¶ Sends
MotechEvent
to the ActiveMQ broker, the implementation is generated by Spring Integration.
Methods¶
broadcastEventMessage¶
-
void
broadcastEventMessage
(MotechEvent motechEvent)¶ Broadcast the motechEvent’s message as a payload to the message channel defined in the Spring Integration configuration file. The channel is connected with a message topic, meaning all Motech instances will receive this event.
Parameters: - motechEvent – the event to be broadcast
sendEventMessage¶
-
void
sendEventMessage
(MotechEvent motechEvent)¶ Sends the motechEvent’s message as a payload to the message channel defined in the Spring Integration configuration file. The channel is connected with a message queue, meaning only one Motech instance will receive this event.
Parameters: - motechEvent – the event to be sent
org.motechproject.mds.annotations¶
Access¶
-
public @interface
Access
¶ The
Access
annotation is used to specify security options of an entity. The discovery logic for this annotation is done inorg.motechproject.mds.annotations.internal.EntityProcessor
See also:
org.motechproject.mds.annotations.internal.EntityProcessor
Cascade¶
-
public @interface
Cascade
¶ The
Cascade
annotation is used to set correct cascade properties for the given field that is a relationship.See also:
org.motechproject.mds.annotations.internal.FieldProcessor
CrudEvents¶
-
public @interface
CrudEvents
¶ The
CrudEvents
annotation is used to specify which CRUD operations should send Motech events. CrudEvents value is an array of one or more values specified inCrudEventType
enum, that is: CREATE, UPDATE, DELETE. There are also two special values - ALL, NONE. When provided, all CRUD operations are enabled/disabled for entity, regardless of presence of other values.This annotation is processed by
org.motechproject.mds.annotations.internal.CrudEventsProcessor
and can be applied only to class which is also annotated withEntity
. It has no effect otherwise.See also:
CrudEventType
,org.motechproject.mds.annotations.internal.CrudEventsProcessor
Entity¶
-
public @interface
Entity
¶ The
Entity
annotation is used to point classes, that should be mapped as Motech Dataservices Entities. The discovery logic for this annotation is done inorg.motechproject.mds.annotations.internal.EntityProcessor
See also:
org.motechproject.mds.annotations.internal.EntityProcessor
EnumDisplayName¶
-
public @interface
EnumDisplayName
¶ The
EnumDisplayName
annotation is used to point a field in enum variable that contains value which should be displayed instead of its raw name. This annotation can be applied on single enum values and enum sets. For proper use of this annotation it should be applied to enums with provided constructor, field containing display value and this fields correspondent ‘getter’ method. The discovery logic for this annotation is done inorg.motechproject.mds.annotations.internal.FieldProcessor
.See also:
org.motechproject.mds.annotations.internal.FieldProcessor
Field¶
-
public @interface
Field
¶ The
Field
annotation is used to point fields, that should be mapped as entity fields. The discovery logic for this annotation is done inorg.motechproject.mds.annotations.internal.FieldProcessor
.Only fields, ‘getter’ or ‘setter’ methods can have this annotation for other methods this annotation is omitted.
See also:
org.motechproject.mds.annotations.internal.FieldProcessor
Ignore¶
-
public @interface
Ignore
¶ Thanks to this annotation, developers can point class fields that should not be included in entity schema definition. To work properly, it is required that either a field or a getter is marked with this annotation. By default, all public fields of an object are included. The discovery logic for this annotation is done in the FieldProcessor and partially in MdsIgnoreAnnotationHandler.
See also:
org.motechproject.mds.annotations.internal.FieldProcessor
,org.motechproject.mds.jdo.MdsIgnoreAnnotationHandler
InSet¶
-
public @interface
InSet
¶ The annotated element must have value that will be in defined set.
Supported types are:
- Integer
- Double
int
,double
IndexedManyToMany¶
-
public @interface
IndexedManyToMany
¶ The
IndexedManyToMany
annotation is used to point ManyToMany indexed relation fields and to avoid using of @Persistent(mappedBy = “relatedField”). Only fields can have this annotation.See also:
org.motechproject.mds.annotations.internal.FieldProcessor
InstanceLifecycleListener¶
-
public @interface
InstanceLifecycleListener
¶ The
InstanceLifecycleListener
annotation is used to point methods from the services exposed by OSGi that should listen to persistence events. The InstanceLifecycleListenerType value is an array of one or more values specified inInstanceLifecycleListenerType
enum, that is: POST_CREATE, PRE_DELETE, POST_DELETE, POST_LOAD, PRE_STORE, POST_STORE. The annotated methods must have only one parameter. If no package is specified, the parameter type is a persistable class. Otherwise it has to be of type Object.This annotation is processed by
org.motechproject.mds.annotations.internal.InstanceLifecycleListenerProcessor
.See also:
org.motechproject.mds.annotations.internal.InstanceLifecycleListenerProcessor
,InstanceLifecycleListenerType
InstanceLifecycleListenerType¶
-
public enum
InstanceLifecycleListenerType
¶ The
InstanceLifecycleListenerType
enum represents persistence event types.See also:
org.motechproject.mds.annotations.InstanceLifecycleListener
Enum Constants¶
POST_CREATE¶
-
public static final InstanceLifecycleListenerType
POST_CREATE
¶ Represents a point in time, right after an instance is made persistent.
POST_DELETE¶
-
public static final InstanceLifecycleListenerType
POST_DELETE
¶ Represents a point in time, right after an instance is deleted.
POST_LOAD¶
-
public static final InstanceLifecycleListenerType
POST_LOAD
¶ Represents a point in time, right after loading instance from datastore.
POST_STORE¶
-
public static final InstanceLifecycleListenerType
POST_STORE
¶ Represents a point in time, right after an instance is stored (eg. due to commit or flush)
PRE_DELETE¶
-
public static final InstanceLifecycleListenerType
PRE_DELETE
¶ Represents a point in time, right before an instance is deleted.
PRE_STORE¶
-
public static final InstanceLifecycleListenerType
PRE_STORE
¶ Represents a point in time, right before an instance is stored (eg. due to commit or flush)
InstanceLifecycleListeners¶
-
public @interface
InstanceLifecycleListeners
¶ The
InstanceLifecycleListeners
annotation is used to point entities for which there may exist instance lifecycle listeners. The only valid case for using this option is when listeners are registered programmatically using theorg.motechproject.mds.service.JdoListenerRegistryService.registerListener(org.motechproject.mds.listener.MotechLifecycleListener)
service method. There is no need to bother with this annotation when listeners are registered withInstanceLifecycleListener
.See also:
org.motechproject.mds.annotations.internal.InstanceLifecycleListenersProcessor
Lookup¶
-
public @interface
Lookup
¶ The
Lookup
annotation is used to point methods, in classes that implementsorg.motechproject.mds.service.MotechDataService
, that should be mapped as MDS lookups. The discovery logic for this annotation is done in theorg.motechproject.mds.annotations.internal.LookupProcessor
See also:
org.motechproject.mds.annotations.internal.LookupProcessor
LookupField¶
-
public @interface
LookupField
¶ The
LookupField
annotation allows to point fields in Lookup method, that should be mapped as lookup fields for Developer Defined Lookup. The discovery logic for this annotation is done in theorg.motechproject.mds.annotations.internal.LookupProcessor
See also:
org.motechproject.mds.annotations.internal.LookupProcessor
NonEditable¶
-
public @interface
NonEditable
¶ The
NonEditable
annotation is used to mark a field non-editable via UI. The discovery logic for this annotation is done inorg.motechproject.mds.annotations.internal.NonEditableProcessor
. Only fields, ‘getter’ or ‘setter’ methods can have this annotation for other methods this annotation is omitted.See also:
org.motechproject.mds.annotations.internal.NonEditableProcessor
NotInSet¶
-
public @interface
NotInSet
¶ The annotated element must not have value that will be in defined set.
Supported types are:
- Integer
- Double
int
,double
ReadAccess¶
-
public @interface
ReadAccess
¶ The
ReadAccess
annotation is used to specify security options for readonly access to an entity. The discovery logic for this annotation is done inorg.motechproject.mds.annotations.internal.EntityProcessor
See also:
org.motechproject.mds.annotations.internal.EntityProcessor
RestExposed¶
-
public @interface
RestExposed
¶ The
RestExposed
annotation is used by developers to mark lookups that should be exposed via REST. It is being processed byorg.motechproject.mds.annotations.internal.LookupProcessor
.See also:
org.motechproject.mds.annotations.internal.LookupProcessor
RestIgnore¶
-
public @interface
RestIgnore
¶ The
RestIgnore
annotation is used to mark a field of entity as not exposed via REST. By default all fields (including auto-generated ones) are exposed. To ignore one of the auto-generated fields, it have to be declared in child entity and marked with this annotation.This annotation is processed by
org.motechproject.mds.annotations.internal.RestIgnoreProcessor
See also:
org.motechproject.mds.annotations.internal.RestIgnoreProcessor
RestOperation¶
-
public enum
RestOperation
¶ The
RestOperation
enum represents CRUD operations that can be enabled for entities.
Enum Constants¶
ALL¶
-
public static final RestOperation
ALL
¶
CREATE¶
-
public static final RestOperation
CREATE
¶
DELETE¶
-
public static final RestOperation
DELETE
¶
READ¶
-
public static final RestOperation
READ
¶
UPDATE¶
-
public static final RestOperation
UPDATE
¶
RestOperations¶
-
public @interface
RestOperations
¶ The
RestOperations
annotation is used to specify which CRUD operations should be enabled for entity. RestOperations value is an array of one or more values specified inRestOperation
enum, that is: CREATE, READ, UPDATE, DELETE. There is also one special value - ALL. When provided, all CRUD operations are enabled for entity, regardless of presence of other values.This annotation is processed by
org.motechproject.mds.annotations.internal.RestOperationsProcessor
and can be applied only to class which is also annotated withorg.motechproject.mds.annotations.Entity
. It has no effect otherwise.See also:
RestOperation
,org.motechproject.mds.annotations.internal.RestOperationsProcessor
UIDisplayable¶
-
public @interface
UIDisplayable
¶ The
UIDisplayable
annotation is used to mark a field as being in the default display for a listing of objects. If no field is marked with this annotation, all of them will be treated as displayable. The discovery logic for this annotation is done inorg.motechproject.mds.annotations.internal.UIDisplayableProcessor
.Only fields, ‘getter’ or ‘setter’ methods can have this annotation for other methods this annotation is omitted.
See also:
org.motechproject.mds.annotations.internal.UIDisplayableProcessor
UIFilterable¶
-
public @interface
UIFilterable
¶ The
UIFilterable
annotation is used to mark a field that allows users to filter a list of objects by the values in the field. The discovery logic for this annotation is done inorg.motechproject.mds.annotations.internal.UIFilterableProcessor
.Only fields, ‘getter’ or ‘setter’ methods can have this annotation for other methods this annotation is omitted. Also this annotation is permitted on fields of type: Date, DateTime, LocalDate, Boolean or List.
See also:
org.motechproject.mds.annotations.internal.UIFilterableProcessor
UIRepresentation¶
-
public @interface
UIRepresentation
¶ The
UIRepresentation
annotation is used to mark a method to provide a UIRepresentation for an entity. Method marked with this annotation should have return typeString
and should not take any argument. If multiple methods are marked with this annotation no method would be invoked for UIRepresentation.
org.motechproject.mds.config¶
DeleteMode¶
-
public enum
DeleteMode
¶ The
DeleteMode
presents what should happen with objects when they are deleted. They can be deleted permanentlyDELETE
or moved to the trashTRASH
. This enum is related with the propertyorg.motechproject.mds.util.Constants.Config.MDS_DELETE_MODE
.The
UNKNOWN
value should not be used in code as appropriate value. It was added to ensure that thefromString(String)
method will not return null value.
Enum Constants¶
DELETE¶
-
public static final DeleteMode
DELETE
¶
TRASH¶
-
public static final DeleteMode
TRASH
¶
UNKNOWN¶
-
public static final DeleteMode
UNKNOWN
¶
MdsConfig¶
-
public class
MdsConfig
¶ Class responsible for handling MDS configuration. Since MDS does not use Server Config, everything connected to the MDS configuration needs to be handled by the module itself.
Methods¶
asProperties¶
-
public Properties
asProperties
()¶
getDataNucleusProperties¶
-
public Properties
getDataNucleusProperties
()¶
getDataNucleusPropertiesForInternalInfrastructure¶
-
public Properties
getDataNucleusPropertiesForInternalInfrastructure
()¶
getFlywayDataProperties¶
-
public Properties
getFlywayDataProperties
()¶
getFlywaySchemaProperties¶
-
public Properties
getFlywaySchemaProperties
()¶
getProperties¶
-
public Properties
getProperties
(String filename)¶
setCoreConfigurationService¶
-
public void
setCoreConfigurationService
(CoreConfigurationService coreConfigurationService)¶
setSqlDBManager¶
-
public void
setSqlDBManager
(SqlDBManager sqlDBManager)¶
ModuleSettings¶
-
public class
ModuleSettings
¶ The
ModuleSettings
contains the base module settings which are inside theorg.motechproject.mds.util.Constants.Config.MODULE_FILE
. The getters and setters inside this class always checks the given property and if it is incorrect then the default value of the given property will be returned.
Fields¶
DEFAULT_DELETE_MODE¶
-
public static final DeleteMode
DEFAULT_DELETE_MODE
¶
Methods¶
getDeleteMode¶
-
public DeleteMode
getDeleteMode
()¶
setDeleteMode¶
-
public void
setDeleteMode
(DeleteMode deleteMode)¶
setRestartModuleAfterTimeout¶
SettingsService¶
-
public interface
SettingsService
¶ The
SettingsService
is a generic class, allowing access to all MDS settings, as well as providing an ability to easily change these settings.
Methods¶
getDeleteMode¶
-
DeleteMode
getDeleteMode
()¶ Returns current setting of the Delete mode. Depending on its setting, deleting an MDS instance either moves it to trash, or removes it permanently.
Returns: current delete mode setting
getGridSize¶
getModuleSettings¶
-
ModuleSettings
getModuleSettings
()¶ Retrieves all MDS settings.
Returns: MDS settings
getTimeUnit¶
-
TimeUnit
getTimeUnit
()¶ Together with
getTimeValue()
specifies frequency of the automatic removal of the instances.Returns: selected unit of time
getTimeValue¶
-
Integer
getTimeValue
()¶ Together with
getTimeUnit()
specifies frequency of the automatic removal of the instances.Returns: value as an integer
isEmptyTrash¶
isRefreshModuleAfterTimeout¶
saveModuleSettings¶
-
void
saveModuleSettings
(ModuleSettings settings)¶ Updates all MDS settings and performs necessary actions if required (eg. scheduling jobs, that remove instances from trash).
Parameters: - settings – settings to save
TimeUnit¶
-
public enum
TimeUnit
¶ The
TimeUnit
specifies what time unit should be used to specify time when the module trash should be cleaned. This enum is related with the propertyorg.motechproject.mds.util.Constants.Config.MDS_TIME_UNIT
.Each value from this enum can be converted to long value that presents time interval in milliseconds. For example the
HOURS
value is equal to 3.6E6.The
UNKNOWN
value should not be used in code as appropriate value. It was added to ensure that thefromString(String)
method will not return null value.
org.motechproject.mds.display¶
DisplayHelper¶
-
public final class
DisplayHelper
¶ This helper class is responsible for the parsing of relationship and combobox values to display-friendly formats.
Fields¶
DTF¶
-
public static final DateTimeFormatter
DTF
¶
Methods¶
getDisplayValueForField¶
-
public static Object
getDisplayValueForField
(FieldDto field, Object value)¶ Parses provided relationship or combobox value to display-friendly format. The type of the value is determined by the
field
parameter. Depending on the type of the field, a different representation will be returned.Parameters: - field – field definition, that contains the type of the field
- value – the value to be parsed
Returns: depending on the field type, it returns
String
representation for one-to-one relationshipMap
representation for the one-to-many and many-to-many relationshipsString
orCollection
representation for comboboxes, depending on their settings
getDisplayValueForField¶
-
public static Object
getDisplayValueForField
(FieldDto field, Object value, Integer maxLength)¶ Parses provided relationship or combobox value to display-friendly format. The type of the value is determined by the
field
parameter. Depending on the type of the field, a different representation will be returned. Moreover, it limits the length of the parsed values, in case they exceed the provided limit.Parameters: - field – field definition, that contains the type of the field
- value – the value to be parsed
- maxLength – the number of characters, after which the values will be trimmed; for map representation this is a maximum number of characters for each value in the map
Returns: depending on the field type, it returns
String
representation for one-to-one relationshipMap
representation for the one-to-many and many-to-many relationshipsString
orCollection
representation for comboboxes, depending on their settings
UIRepresentationUtil¶
-
public final class
UIRepresentationUtil
¶ The
UiRepresentationUtil
class provides a mechanism for finding methods with theorg.motechproject.mds.annotations.UIRepresentation
and invoke the method with the annotation to provide a UIRepresentation string for an entity instance.
Methods¶
uiRepresentationString¶
-
public static String
uiRepresentationString
(Object instance)¶ Looks for a method annotated
UIRepresentation
in the provided instance and invokes it in order to fetch the String representation, provided by the annotated method. This method is null-safe and will return empty string for null inputs. This method will return null if the contract for this method is not fulfilled. This method expects that:- There’s exactly one method annotated
UIRepresentation
in the provided instance object - The annotated method returns
String
- The annotated method does not take any parameters
If the contract is fulfilled, the annotated method of the instance is invoked and the result of the annotated method is returned by this method.
Parameters: - instance – an instance for which we wish to get UI String representation
Returns: UI representation of the provided instance, as returned by the method annotated
UIRepresentation
, null if provided instance does not fulfill this method’s contract or empty string if the instance passed to this method is null- There’s exactly one method annotated
org.motechproject.mds.domain¶
BrowsingSettings¶
-
public class
BrowsingSettings
¶ The
BrowsingSettings
contains information about fields that will be visible on UI and could be used as filter on UI.This class is read only (the data are not saved to database) and its main purpose is to provide methods that help developer to get displayed and filterable fields.
BundleFailureReport¶
-
public class
BundleFailureReport
¶ The
BundleFailureReport
class contains information about a bundle failure caused by a timeout after MDS schema regeneration.
Constructors¶
Methods¶
getBundleRestartStatus¶
-
public BundleRestartStatus
getBundleRestartStatus
()¶
setBundleRestartStatus¶
-
public void
setBundleRestartStatus
(BundleRestartStatus bundleRestartStatus)¶
BundleRestartStatus¶
-
public enum
BundleRestartStatus
¶ Represents the status of the restart during after bundle fails.
See also:
BundleFailureReport
Enum Constants¶
ERROR¶
-
public static final BundleRestartStatus
ERROR
¶
IN_PROGRESS¶
-
public static final BundleRestartStatus
IN_PROGRESS
¶
SUCCESS¶
-
public static final BundleRestartStatus
SUCCESS
¶
ClassData¶
-
public class
ClassData
¶ Represents a class name and its byte code.
Constructors¶
ClassData¶
-
public
ClassData
(String className, String module, String namespace, byte[] bytecode, EntityType type)¶
ClassData¶
Methods¶
getType¶
-
public EntityType
getType
()¶
ComboboxHolder¶
-
public class
ComboboxHolder
extends FieldHolder¶ The main purpose of this class is to make it easier to find out what kind of type should be used when the field is added to the class definition.
Constructors¶
Methods¶
getEnumName¶
getTypeClassName¶
getUnderlyingType¶
isAllowMultipleSelections¶
-
public boolean
isAllowMultipleSelections
()¶ Returns: true, if this combobox allows selecting multiple values; false otherwise
isAllowUserSupplied¶
-
public boolean
isAllowUserSupplied
()¶ Returns: true, if this combobox allows user supplied values; false otherwise
isCollection¶
-
public boolean
isCollection
()¶ Returns: true, if this combobox is handled by a collection type in the backend; false otherwise
isEnum¶
-
public boolean
isEnum
()¶ Returns: true, if this combobox does not allow user supplied values and allows selecting only single value; false otherwise
isEnumCollection¶
-
public boolean
isEnumCollection
()¶ Returns: true, if this combobox does not allow user supplied values and allows selecting multiple values; false otherwise
ConfigSettings¶
-
public class
ConfigSettings
¶ The
ConfigSettings
class represents Data Services settings, that can be adjusted by users via UI.
Constructors¶
ConfigSettings¶
-
public
ConfigSettings
(DeleteMode deleteMode, boolean emptyTrash, int afterTimeValue, TimeUnit afterTimeUnit, int defaultGridSize, boolean refreshModuleAfterTimeout)¶
Methods¶
getDeleteMode¶
-
public DeleteMode
getDeleteMode
()¶
setDeleteMode¶
-
public void
setDeleteMode
(DeleteMode deleteMode)¶
Entity¶
-
public class
Entity
¶ The
Entity
class contains information about an entity. It also contains information about advanced settings related with the entity.
Constructors¶
Entity¶
-
public
Entity
(String className, String module, String namespace, SecurityMode securityMode)¶
Entity¶
Methods¶
advancedSettingsDto¶
-
public AdvancedSettingsDto
advancedSettingsDto
()¶
getBrowsingSettings¶
-
public BrowsingSettings
getBrowsingSettings
()¶
getDrafts¶
-
public List<EntityDraft>
getDrafts
()¶
getReadOnlySecurityMode¶
-
public SecurityMode
getReadOnlySecurityMode
()¶
getRestOptions¶
-
public RestOptions
getRestOptions
()¶
getSecurityMode¶
-
public SecurityMode
getSecurityMode
()¶
setDrafts¶
-
public void
setDrafts
(List<EntityDraft> drafts)¶
setReadOnlySecurity¶
-
public void
setReadOnlySecurity
(SecurityMode readOnlySecurityMode, List<String> readOnlySecurityMembersList)¶
setReadOnlySecurityMembers¶
setReadOnlySecurityMode¶
-
public void
setReadOnlySecurityMode
(SecurityMode readOnlySecurityMode)¶
setRestOptions¶
-
public void
setRestOptions
(RestOptions restOptions)¶
setSecurity¶
-
public void
setSecurity
(SecurityMode securityMode, List<String> securityMembersList)¶
setSecurityMode¶
-
public void
setSecurityMode
(SecurityMode securityMode)¶
setSecurityOptionsModified¶
-
public void
setSecurityOptionsModified
(boolean securityOptionsModified)¶
updateAdvancedSetting¶
-
public void
updateAdvancedSetting
(AdvancedSettingsDto advancedSettings)¶
updateBrowsingSettings¶
-
protected void
updateBrowsingSettings
(AdvancedSettingsDto advancedSettings, boolean shouldSetUiChanged)¶
updateFromDraft¶
-
public void
updateFromDraft
(EntityDraft draft)¶
updateRestOptions¶
-
protected void
updateRestOptions
(AdvancedSettingsDto advancedSettings)¶
updateRestOptions¶
-
public void
updateRestOptions
(RestOptionsDto restOptionsDto)¶
updateTracking¶
-
protected void
updateTracking
(AdvancedSettingsDto advancedSettings)¶
updateTracking¶
-
public void
updateTracking
(TrackingDto trackingDto)¶
EntityAudit¶
-
public class
EntityAudit
extends Entity¶ This class represents a single historical commit of an Entity.
Methods¶
EntityDefinitionType¶
-
public enum
EntityDefinitionType
¶ Represents entity origin.
Enum Constants¶
DDE¶
-
public static final EntityDefinitionType
DDE
¶ Developer Defined Entity. Entity, that has been created by developer, using MDS annotations.
EUDE¶
-
public static final EntityDefinitionType
EUDE
¶ End User Defined Entity. Entity, that has been created by user, using MDS User Interface.
EntityDraft¶
-
public class
EntityDraft
extends Entity¶ This class represents user drafts of an Entity. A draft is user’s work in progress from the UI. This shares the table with its superclass,
Entity
.
Methods¶
updateAdvancedSetting¶
-
public void
updateAdvancedSetting
(AdvancedSettingsDto advancedSettings)¶
EntityType¶
-
public enum
EntityType
¶ Represents the type of an entity and their associated class names.
Enum Constants¶
HISTORY¶
-
public static final EntityType
HISTORY
¶ Entity representing a historical revision.
STANDARD¶
-
public static final EntityType
STANDARD
¶ Regular entity.
TRASH¶
-
public static final EntityType
TRASH
¶ Entity representing an instance in trash.
Field¶
-
public class
Field
¶ The
Field
class contains information about a single field. Remember to update FieldWriter/FieldReader after making changes
Methods¶
addMetadata¶
-
public void
addMetadata
(FieldMetadata metadata)¶
addSetting¶
-
public void
addSetting
(FieldSetting setting)¶
addValidation¶
-
public void
addValidation
(FieldValidation validation)¶
getMetadata¶
-
public List<FieldMetadata>
getMetadata
()¶
getMetadata¶
-
public FieldMetadata
getMetadata
(String key)¶
getSettingByName¶
-
public FieldSetting
getSettingByName
(String name)¶
getSettings¶
-
public List<FieldSetting>
getSettings
()¶
getValidationByName¶
-
public FieldValidation
getValidationByName
(String name)¶
getValidations¶
-
public List<FieldValidation>
getValidations
()¶
setMetadata¶
-
public void
setMetadata
(List<FieldMetadata> metadata)¶
setSettings¶
-
public void
setSettings
(List<FieldSetting> settings)¶
setValidations¶
-
public void
setValidations
(List<FieldValidation> validations)¶
settingsToDto¶
-
public List<SettingDto>
settingsToDto
()¶
FieldHolder¶
-
public class
FieldHolder
¶ The main purpose of this class is to provide an easy way to access values inside metadata and settings related with the given field.
Constructors¶
Methods¶
getMetadata¶
getMetadata¶
-
public String
getMetadata
(String name, String defaultValue)¶ Retrieves metadata value of the given name from this field. If there’s no metadata entry of the given name, a default value is returned.
Parameters: - name – metadata key
- defaultValue – default value to use, in case metadata entry is not present
Returns: value of the metadata entry, or default value
getSetting¶
getSetting¶
-
public String
getSetting
(String name, String defaultValue)¶ Retrieves value of the setting, with the given name. If there’s no setting with the given name, a default value is returned.
Parameters: - name – setting name
- defaultValue – default value to use, in case given setting is not present
Returns: value of the setting
getSettingAsArray¶
-
public String[]
getSettingAsArray
(String name)¶ Retrieves value of the setting, with the given name and parses the result into an array of Strings. Comma mark (,) will be treated as a separator of the elements in the setting value.
Parameters: - name – setting name
Returns: value of the setting, in form of an array of Strings
FieldMetadata¶
-
public class
FieldMetadata
implements Pair<String, String>¶ The
FieldMetadata
class contains information about a single metadata added into a field.
Constructors¶
FieldMetadata¶
-
public
FieldMetadata
(MetadataDto metadata)¶
Methods¶
copy¶
-
public FieldMetadata
copy
()¶
toDto¶
-
public MetadataDto
toDto
()¶
update¶
-
public final void
update
(MetadataDto metadata)¶
FieldSetting¶
Constructors¶
FieldSetting¶
-
public
FieldSetting
(Field field, TypeSetting details)¶
FieldSetting¶
-
public
FieldSetting
(Field field, TypeSetting details, String value)¶
Methods¶
copy¶
-
public FieldSetting
copy
()¶
getDetails¶
-
public TypeSetting
getDetails
()¶
setDetails¶
-
public void
setDetails
(TypeSetting details)¶
toDto¶
-
public SettingDto
toDto
()¶
FieldValidation¶
-
public class
FieldValidation
¶ The
FieldValidation
class contains the value that is related with the correct type validation and information about that whether the given validation is enabled or not.
Constructors¶
FieldValidation¶
-
public
FieldValidation
(Field field, TypeValidation details)¶
FieldValidation¶
-
public
FieldValidation
(Field field, TypeValidation details, String value, boolean enabled)¶
Methods¶
copy¶
-
public FieldValidation
copy
()¶
getDetails¶
-
public TypeValidation
getDetails
()¶
setDetails¶
-
public void
setDetails
(TypeValidation details)¶
toDto¶
-
public ValidationCriterionDto
toDto
()¶
ImportExportBlueprint¶
-
public class
ImportExportBlueprint
extends ArrayList<ImportExportBlueprint.Record>¶ The
ImportExportBlueprint
represents MDS import or export plan, specifying which entities and which parts of those entities should be included in either import or export.
Methods¶
ImportManifest¶
-
public class
ImportManifest
¶ The
ImportManifest
holds components available for import that are contained in a single MDS import file.
Lookup¶
-
public class
Lookup
¶ The
Lookup
class contains information about single lookup
Constructors¶
Lookup¶
Lookup¶
Lookup¶
Lookup¶
-
public
Lookup
(String lookupName, boolean singleObjectReturn, boolean exposedViaRest, List<Field> fields, boolean readOnly, String methodName, List<String> rangeLookupFields, List<String> setLookupFields, Map<String, String> customOperators, Map<String, Boolean> useGenericParams, List<String> fieldsOrder)¶
Lookup¶
-
public
Lookup
(String lookupName, boolean singleObjectReturn, boolean exposedViaRest, List<Field> fields, boolean readOnly, String methodName, List<String> rangeLookupFields, List<String> setLookupFields, Map<String, String> customOperators, Map<String, Boolean> useGenericParams, List<String> fieldsOrder, boolean indexRequired)¶
Lookup¶
Methods¶
getLookupFieldType¶
-
public LookupFieldType
getLookupFieldType
(String fieldName)¶
ManyToManyRelationship¶
-
public class
ManyToManyRelationship
extends Relationship¶ A specialization of the
Relationship
class. Represents a many-to-many relationship.
ManyToOneRelationship¶
-
public class
ManyToOneRelationship
extends Relationship¶ A specialization of the
org.motechproject.mds.domain.Relationship
class. Represents a many-to-one relationship.
MdsEntity¶
-
public abstract class
MdsEntity
¶ The
MdsEntity
is an optional class for all domain classes acting as Motech data services Entities. This class stores and allows access to all default fields like id, creator or modification date. All classes annotatedorg.motechproject.mds.annotations.Entity
can extend this base class.
Methods¶
MdsVersionedEntity¶
MigrationMapping¶
-
public class
MigrationMapping
¶ The
MigrationMapping
class contains information about flyway migrations from modules(It maps module migration version to the flyway migration version).
Constructors¶
Methods¶
OneToManyRelationship¶
-
public class
OneToManyRelationship
extends Relationship¶ A specialization of the
Relationship
class. Represents a one-to-many relationship.
OneToOneRelationship¶
-
public class
OneToOneRelationship
extends Relationship¶ A specialization of the
Relationship
class. Represents a one-to-one relationship.
Relationship¶
-
public class
Relationship
¶ A class representing a relationship type. This class is inherited by different types of relationships. This class only represents the field type and provides some utility methods. It is not used in entities themselves.
RelationshipHolder¶
-
public class
RelationshipHolder
extends FieldHolder¶ The main purpose of this class is to find out how cascade should be used for the given field with relationship type.
Constructors¶
Methods¶
hasUnresolvedRelation¶
-
public boolean
hasUnresolvedRelation
()¶ If this returns true, it means that either: the relation is uni-directional or the relation is bi-directional, and we should expect related class to define which fields are related
Returns: true if relation is uni-directional or bi-directional without defined related field; false otherwise
RestOptions¶
-
public class
RestOptions
¶ The
RestOptions
class represents rest options of an entity. This class is related with table in database with the same name.
Methods¶
copy¶
-
public RestOptions
copy
()¶
toDto¶
-
public RestOptionsDto
toDto
()¶
update¶
-
public final void
update
(RestOptionsDto restOptionsDto)¶
SchemaChangeLock¶
-
public class
SchemaChangeLock
¶ The object used for locking schema change access.
Methods¶
Tracking¶
-
public class
Tracking
¶ The
Tracking
contains properties that describe the audit settings of an Entity, such as whether to record history or publish CRUD events for a given Entity. This class is related with table in database with the same name.
Type¶
-
public class
Type
¶ The
Type
class contains information about a single type in MDS. The MDS type can have settings and validations that can be assigned to field with the same type.
Constructors¶
Methods¶
getSettings¶
-
public List<TypeSetting>
getSettings
()¶
getTypeValidationDtos¶
-
public List<TypeValidationDto>
getTypeValidationDtos
()¶
getValidations¶
-
public List<TypeValidation>
getValidations
()¶
setSettings¶
-
public void
setSettings
(List<TypeSetting> settings)¶
setValidations¶
-
public void
setValidations
(List<TypeValidation> validations)¶
TypeSetting¶
-
public class
TypeSetting
¶ The
TypeSetting
contains settings for the given MDS type. This class is related with table in database with the same name.
Methods¶
getTypeSettingOptions¶
-
public List<TypeSettingOption>
getTypeSettingOptions
()¶
setTypeSettingOptions¶
-
public void
setTypeSettingOptions
(List<TypeSettingOption> typeSettingOptions)¶
TypeSettingOption¶
-
public class
TypeSettingOption
¶ The
TypeSettingOption
contains a single setting option for the given type setting. This class is related with table in database with the same name.
TypeValidation¶
-
public class
TypeValidation
¶ The
TypeValidation
contains a single validation option for the given type. This class is related with table in database with the same name.
Constructors¶
Methods¶
getAnnotations¶
-
public List<Class<? extends Annotation>>
getAnnotations
()¶
setAnnotations¶
-
public void
setAnnotations
(List<Class<? extends Annotation>> annotations)¶
toDto¶
-
public TypeValidationDto
toDto
()¶
UIDisplayFieldComparator¶
-
public class
UIDisplayFieldComparator
implements Comparator<Field>¶ UIDisplayFieldComparator
compares positions added in UIDisplayable annotation. Fields without annotation are placed at the end.
org.motechproject.mds.dto¶
AdvancedSettingsDto¶
-
public class
AdvancedSettingsDto
¶ The
AdvancedSettingsDto
contains information about advanced settings of an entity.
Methods¶
getBrowsing¶
-
public BrowsingSettingsDto
getBrowsing
()¶
getRestOptions¶
-
public RestOptionsDto
getRestOptions
()¶
getTracking¶
-
public TrackingDto
getTracking
()¶
getUserPreferences¶
-
public UserPreferencesDto
getUserPreferences
()¶
setBrowsing¶
-
public void
setBrowsing
(BrowsingSettingsDto browsing)¶
setRestOptions¶
-
public void
setRestOptions
(RestOptionsDto restOptions)¶
setTracking¶
-
public void
setTracking
(TrackingDto tracking)¶
setUserPreferences¶
-
public void
setUserPreferences
(UserPreferencesDto userPreferences)¶
BrowsingSettingsDto¶
-
public class
BrowsingSettingsDto
¶ The
BrowsingSettingsDto
contains information about filled browsing settings
CsvImportResults¶
-
public class
CsvImportResults
implements Serializable¶ This class holds results from a CSV import - IDs of updated and created instances.
Constructors¶
CsvImportResults¶
-
public
CsvImportResults
(EntityDto entity, List<Long> newInstanceIDs, List<Long> updatedInstanceIDs, Map<Integer, String> rowErrors)¶ Parameters: - entity – entity for which this import was performed
- newInstanceIDs – a list of IDs for instances that were newly created during import
- updatedInstanceIDs – a list of IDs for instances that were updated during import
- rowErrors – a list of errors thrown during import
Methods¶
getEntityClassName¶
getEntityModule¶
getEntityName¶
getEntityNamespace¶
getNewInstanceIDs¶
getRowErrors¶
getUpdatedInstanceIDs¶
newInstanceCount¶
-
public int
newInstanceCount
()¶ Returns: the total number of instances that were newly created during import
totalNumberOfImportedInstances¶
-
public int
totalNumberOfImportedInstances
()¶ Returns the total number of imported instances. The total number of imported instances is the sum of the number of updated instances and the total number of newly created instances. In other words this is the number of affected instances.
Returns: total number of imported instances
DraftData¶
-
public class
DraftData
¶ The
DraftData
contains information that are used for creating temporary changes in a field.
Fields¶
Methods¶
DraftResult¶
-
public class
DraftResult
implements Serializable¶ After users do draft changes an instance of this class is returned. It contains information about the draft state.
DtoHelper¶
-
public final class
DtoHelper
¶ Utility class for managing dto collections.
Methods¶
asFieldMapById¶
asFieldMapByName¶
findById¶
-
public static FieldDto
findById
(Collection<FieldDto> fields, Long id)¶ Looks through a collection of fields, in order to find a field of given id.
Parameters: - fields – the field collection
- id – id of the field to find
Returns: field of the given id or null, if field of given id was not found
findByName¶
-
public static FieldDto
findByName
(Collection<FieldDto> fields, String name)¶ Looks through a collection of fields, in order to find a field of given name.
Parameters: - fields – the field collection
- name – name of the field to find
Returns: field of the given name or null, if field of given name was not found
EntityDto¶
-
public class
EntityDto
¶ The
EntityDto
class contains only basic information about an entity like id, name, module and namespace.
Constructors¶
EntityDto¶
-
public
EntityDto
(String className, SecurityMode securityMode, Set<String> securityMembers)¶
EntityDto¶
EntityDto¶
EntityDto¶
EntityDto¶
EntityDto¶
EntityDto¶
EntityDto¶
-
public
EntityDto
(Long id, String className, String name, String module, String namespace, String tableName, boolean recordHistory, SecurityMode securityMode, Set<String> securityMembers, SecurityMode readOnlySecurityMode, Set<String> readOnlySecurityMembers, String superClass, boolean abstractClass, boolean securityOptionsModified, String bundleSymbolicName)¶
Methods¶
checkIfUserHasOnlyReadAccessAuthorization¶
-
public boolean
checkIfUserHasOnlyReadAccessAuthorization
()¶
getReadOnlySecurityMode¶
-
public SecurityMode
getReadOnlySecurityMode
()¶
getSecurityMode¶
-
public SecurityMode
getSecurityMode
()¶
hasAccessToEntityFromSecurityMode¶
-
public boolean
hasAccessToEntityFromSecurityMode
(SecurityMode mode, Set<String> members)¶
setReadOnlySecurityMembers¶
setReadOnlySecurityMode¶
-
public void
setReadOnlySecurityMode
(SecurityMode readOnlySecurityMode)¶
setSecurityMode¶
-
public void
setSecurityMode
(SecurityMode securityMode)¶
setSecurityOptionsModified¶
-
public void
setSecurityOptionsModified
(boolean securityOptionsModified)¶
FieldBasicDto¶
-
public class
FieldBasicDto
¶ The
FieldBasicDto
contains basic information about a field.
FieldDto¶
-
public class
FieldDto
¶ The
FieldDto
class contains information about an existing field in an entity.
Constructors¶
FieldDto¶
FieldDto¶
FieldDto¶
FieldDto¶
-
public
FieldDto
(Long id, Long entityId, TypeDto type, FieldBasicDto basic, boolean readOnly, List<MetadataDto> metadata, FieldValidationDto validation, List<SettingDto> settings, List<LookupDto> lookups)¶
FieldDto¶
-
public
FieldDto
(Long id, Long entityId, TypeDto type, FieldBasicDto basic, boolean readOnly, boolean nonEditable, boolean nonDisplayable, List<MetadataDto> metadata, FieldValidationDto validation, List<SettingDto> settings, List<LookupDto> lookups)¶
FieldDto¶
-
public
FieldDto
(Long id, Long entityId, TypeDto type, FieldBasicDto basic, boolean readOnly, boolean nonEditable, boolean nonDisplayable, boolean uiChanged, List<MetadataDto> metadata, FieldValidationDto validation, List<SettingDto> settings, List<LookupDto> lookups)¶
FieldDto¶
-
public
FieldDto
(Long id, Long entityId, TypeDto type, FieldBasicDto basic, boolean readOnly, FieldValidationDto validation)¶
FieldDto¶
-
public
FieldDto
(Long id, Long entityId, TypeDto type, FieldBasicDto basic, boolean readOnly, boolean nonEditable, boolean nonDisplayable, boolean uiFilterable, boolean uiChanged, List<MetadataDto> metadata, FieldValidationDto validation, List<SettingDto> settings, List<LookupDto> lookups)¶
Methods¶
addMetadata¶
-
public void
addMetadata
(MetadataDto metadata)¶
addSetting¶
-
public void
addSetting
(SettingDto setting)¶
getBasic¶
-
public FieldBasicDto
getBasic
()¶
getMetadata¶
-
public List<MetadataDto>
getMetadata
()¶
getMetadata¶
-
public MetadataDto
getMetadata
(String key)¶
getSetting¶
-
public SettingDto
getSetting
(String name)¶
getSettings¶
-
public List<SettingDto>
getSettings
()¶
getValidation¶
-
public FieldValidationDto
getValidation
()¶
setBasic¶
-
public void
setBasic
(FieldBasicDto basic)¶
setMetadata¶
-
public void
setMetadata
(List<MetadataDto> metadata)¶
setSettings¶
-
public void
setSettings
(List<SettingDto> settings)¶
setValidation¶
-
public void
setValidation
(FieldValidationDto validation)¶
FieldInstanceDto¶
-
public class
FieldInstanceDto
¶ The
FieldInstanceDto
class contains information about an existing field in an instance.
Constructors¶
FieldInstanceDto¶
-
public
FieldInstanceDto
(Long id, Long instanceId, FieldBasicDto basic)¶
FieldValidationDto¶
-
public class
FieldValidationDto
¶ The
FieldValidationDto
class contains information about validation criteria for field.
Fields¶
DOUBLE¶
-
public static final FieldValidationDto
DOUBLE
¶ Constant
DOUBLE
contains validation criteria for double type.
FLOAT¶
-
public static final FieldValidationDto
FLOAT
¶ Constant
FLOAT
contains validation criteria for float type.
INTEGER¶
-
public static final FieldValidationDto
INTEGER
¶ Constant
INTEGER
contains validation criteria for integer type.
STRING¶
-
public static final FieldValidationDto
STRING
¶ Constant
STRING
contains validation criteria for string type.
Constructors¶
FieldValidationDto¶
-
public
FieldValidationDto
(ValidationCriterionDto... criteria)¶
Methods¶
addCriterion¶
-
public void
addCriterion
(ValidationCriterionDto criterion)¶
getCriteria¶
-
public List<ValidationCriterionDto>
getCriteria
()¶
getCriterion¶
-
public ValidationCriterionDto
getCriterion
(String displayName)¶
setCriteria¶
-
public void
setCriteria
(List<ValidationCriterionDto> criteria)¶
JsonLookupDto¶
-
public class
JsonLookupDto
¶ Contains information about single lookup added via JSON file.
LookupDto¶
-
public class
LookupDto
¶ The
LookupDto
class contains information about single lookup defined by user
Constructors¶
LookupDto¶
LookupDto¶
-
public
LookupDto
(String lookupName, boolean singleObjectReturn, boolean exposedViaRest, List<LookupFieldDto> lookupFields)¶
LookupDto¶
-
public
LookupDto
(String lookupName, boolean singleObjectReturn, boolean exposedViaRest, List<LookupFieldDto> lookupFields, boolean readOnly)¶
LookupDto¶
LookupDto¶
LookupDto¶
Methods¶
getLookupField¶
-
public LookupFieldDto
getLookupField
(String fieldName)¶
getLookupFields¶
-
public final List<LookupFieldDto>
getLookupFields
()¶
insertField¶
insertField¶
setLookupFields¶
-
public void
setLookupFields
(List<LookupFieldDto> lookupFields)¶
updateCustomOperatorForLookupField¶
LookupFieldDto¶
-
public class
LookupFieldDto
¶ Represents a field added to a lookup. The lookup using a given field can be done using multiple lookup types.
Constructors¶
LookupFieldDto¶
-
public
LookupFieldDto
(String name, LookupFieldType type)¶
LookupFieldDto¶
-
public
LookupFieldDto
(Long id, String name, LookupFieldType type)¶
LookupFieldDto¶
-
public
LookupFieldDto
(String name, LookupFieldType type, String customOperator)¶
Methods¶
getSettings¶
-
public List<SettingDto>
getSettings
()¶
getType¶
-
public LookupFieldType
getType
()¶
setSettings¶
-
public void
setSettings
(List<SettingDto> settings)¶
setType¶
-
public void
setType
(LookupFieldType type)¶
LookupFieldType¶
-
public enum
LookupFieldType
¶ The lookup type represents whether the lookup will be done by comparing to a single field, matching values to a range, or matching to a set of values.
Enum Constants¶
RANGE¶
-
public static final LookupFieldType
RANGE
¶ Lookup field that accepts a range of values, specified by a minimum and maximum values.
SET¶
-
public static final LookupFieldType
SET
¶ Lookup field that accepts a collection of values.
VALUE¶
-
public static final LookupFieldType
VALUE
¶ Single value lookup field.
MetadataDto¶
-
public class
MetadataDto
implements Pair<String, String>¶ The
MetadataDto
contains key and value of a single field metadata.
Constructors¶
RestOptionsDto¶
-
public class
RestOptionsDto
¶ Class representing rest options of given entity.
Constructors¶
SchemaHolder¶
-
public class
SchemaHolder
¶ A class that holds the MDS schema - entities, types, fields, lookups, advanced settings and so on. Used during MDS processing in order to avoid repeatedly querying the database.
Methods¶
addEntity¶
-
public void
addEntity
(EntityDto entity, AdvancedSettingsDto advancedSettings, List<FieldDto> fields)¶
addTypeValidation¶
-
public void
addTypeValidation
(TypeDto type, List<TypeValidationDto> validations)¶
findValidations¶
-
public List<TypeValidationDto>
findValidations
(String typeClass, Class<? extends Annotation> aClass)¶
getAdvancedSettings¶
-
public AdvancedSettingsDto
getAdvancedSettings
(EntityDto entity)¶
getAdvancedSettings¶
-
public AdvancedSettingsDto
getAdvancedSettings
(String className)¶
SettingDto¶
-
public class
SettingDto
implements Pair<String, Object>¶ The
SettingDto
contains information about a single setting inside a field.
Constructors¶
SettingOptions¶
-
public enum
SettingOptions
¶ The
SettingOptions
contains available options that can be added to field setting.
Enum Constants¶
POSITIVE¶
-
public static final SettingOptions
POSITIVE
¶ Ensure that a value in a given setting is a number and it has a positive value.
REQUIRE¶
-
public static final SettingOptions
REQUIRE
¶ Force setting a value for a given setting.
TrackingDto¶
-
public class
TrackingDto
¶ The
TrackingDto
contains properties that describe the audit settings of an Entity, such as whether to record history or publish CRUD events for a given Entity.
Constructors¶
TypeDto¶
-
public class
TypeDto
¶ The
TypeDto
class contains information about an available field in an entity.
Fields¶
BOOLEAN¶
CHARACTER¶
COLLECTION¶
DATE¶
DATETIME¶
DATETIME8¶
DOUBLE¶
FLOAT¶
INTEGER¶
LOCAL_DATE¶
-
public static final TypeDto
LOCAL_DATE
¶ Constant
LOCAL_DATE
is a representation of theorg.joda.time.LocalDate
type.
LOCAL_DATE8¶
PERIOD¶
SHORT¶
STRING¶
TypeValidationDto¶
-
public class
TypeValidationDto
¶ Dto class representing a validation for a given type.
Constructors¶
UIDisplayFieldComparator¶
-
public class
UIDisplayFieldComparator
implements Comparator<FieldDto>¶ UIDisplayFieldComparator
compares positions added in UIDisplayable annotation. Fields without annotation are placed at the end.
Constructors¶
UserPreferencesDto¶
-
public class
UserPreferencesDto
¶ The
UserPreferencesDto
contains information about user preferences of an entity.
Constructors¶
Methods¶
org.motechproject.mds.entityinfo¶
EntityInfo¶
-
public class
EntityInfo
¶ The
EntityInfo
class contains base information about the given entity, like its class name or infrastructure class names.
Methods¶
entitiesWithAnyCRUDAction¶
-
public static Collection<EntityInfo>
entitiesWithAnyCRUDAction
(Collection<EntityInfo> entityInfos)¶
getAdvancedSettings¶
-
public AdvancedSettingsDto
getAdvancedSettings
()¶
getSecurityMode¶
-
public SecurityMode
getSecurityMode
()¶
setAdvancedSettings¶
-
public void
setAdvancedSettings
(AdvancedSettingsDto advancedSettings)¶
EntityInfoReader¶
-
public interface
EntityInfoReader
¶ Responsible for reading entity schema info. Should be used instead of going to the database and creating needless transactions, which slows down startup.
Methods¶
getEntitiesClassNames¶
-
Collection<String>
getEntitiesClassNames
()¶ Returns entities class names list.
Returns: the list of class names
getEntityInfo¶
-
EntityInfo
getEntityInfo
(String entityClassName)¶ Reads entity info representing the MDS schema for a given entity.
Parameters: - entityClassName – the class name of the entity
Returns: the entity schema info
getEntityInfo¶
-
EntityInfo
getEntityInfo
(Long entityId)¶ Reads entity info representing the MDS schema for a given entity.
Parameters: - entityId – the id of the entity
Returns: the entity schema info
EntityInfoReaderImpl¶
-
public class
EntityInfoReaderImpl
implements EntityInfoReader¶ Implementation of the
EntityInfoReader
which reads entity information from json files from the META-INF/entity-info directory inside the classpath. Used by mds-entities bundle, which has all entity schema packed inside of it.
Methods¶
getEntitiesClassNames¶
-
public Collection<String>
getEntitiesClassNames
()¶
getEntityInfo¶
-
public EntityInfo
getEntityInfo
(String entityClassName)¶
getEntityInfo¶
-
public EntityInfo
getEntityInfo
(Long entityId)¶
FieldInfo¶
-
public class
FieldInfo
¶ The
FieldInfo
class contains base information about the given entity field like its name or type.
Methods¶
org.motechproject.mds.event¶
CrudEventBuilder¶
-
public final class
CrudEventBuilder
¶ The
MDSCrudEvents
class is responsible for creating MDS CRUD events.
Methods¶
buildEventParams¶
-
public static Map<String, Object>
buildEventParams
(String module, String namespace, String entity, String entityClassName, Long id)¶ Builds parameters for a Motech CRUD event.
Parameters: - module – module name of an entity
- namespace – namespace of an entity
- entity – entity name
- entityClassName – entity class name
- id – id of the affected instance
Returns: constructed parameters for the events
createSubject¶
-
public static String
createSubject
(EntityInfo entity, String action)¶ Creates subject for a Motech event, sent upon encounter of a CRUD event in MDS.
Parameters: - entity – entity information
- action – String representation of a CRUD event type
Returns: Constructed subject for the event
createSubject¶
-
public static String
createSubject
(String module, String namespace, String entity, CrudEventType action)¶ Creates subject for a Motech Event, sent upon encounter of a CRUD event in MDS.
Parameters: - module – module name of an entity
- namespace – namespace of an entity
- entity – entity name
- action – CRUD event type
Returns: Constructed subject for the Motech Event
createSubject¶
-
public static String
createSubject
(String module, String namespace, String entity, String action)¶ Creates subject for a Motech Event, sent upon encounter of a CRUD event in MDS.
Parameters: - module – module name of an entity
- namespace – namespace of an entity
- entity – entity name
- action – String representation of a CRUD event type
Returns: Constructed subject for the Motech Event
setEntityData¶
-
public static void
setEntityData
(Map<String, Object> params, String module, String namespace, String entityName, String entityClassName)¶ Sets properties in the given
java.util.Map
.Parameters: - params – a
java.util.Map
to write properties in - module – module name of an entity
- namespace – namespace of an entity
- entityName – entity name
- entityClassName – entity class name
- params – a
CrudEventType¶
-
public enum
CrudEventType
¶ The
MDSEventsAction
enum represents CRUD operations which send events, this option can be enabled only for entities.
Enum Constants¶
ALL¶
-
public static final CrudEventType
ALL
¶ Represents all CRUD event types.
CREATE¶
-
public static final CrudEventType
CREATE
¶ One of the CRUD event types, representing creating an instance.
DELETE¶
-
public static final CrudEventType
DELETE
¶ One of the CRUD event types, representing deleting an instance.
NONE¶
-
public static final CrudEventType
NONE
¶ Represents zero CRUD event types.
UPDATE¶
-
public static final CrudEventType
UPDATE
¶ One of the CRUD event types, representing updating an instance.
org.motechproject.mds.exception¶
MdsException¶
-
public class
MdsException
extends RuntimeException¶ The
MdsException
exception is a basic class for all other exceptions defined in the mds module. It contains information about a message key which will be used on UI to present a message in appropriate language.
Constructors¶
MdsException¶
MdsException¶
-
public
MdsException
(String message, Throwable cause, String messageKey)¶ Constructs a new mds exception with the specified message key and params.
Parameters: - message – the error message for the logs
- cause – the cause of the exception
- messageKey – the message key used later to display message in appropriate language on UI.
MdsException¶
-
public
MdsException
(String message, Throwable cause, String messageKey, String params)¶ Constructs a new mds exception with the specified message key and params.
Parameters: - message – the error message for the logs
- cause – the cause of the exception
- messageKey – the message key used later to display message in appropriate language on UI.
- params – the params used later to change placeholders in the message
MdsException¶
-
public
MdsException
(String message, Throwable cause, String messageKey, String... params) Constructs a new mds exception with the specified message key and params.
Parameters: - message – the error message for the logs
- cause – the cause of the exception
- messageKey – the message key used later to display message in appropriate language on UI.
- params – the params used later to change placeholders in the message
org.motechproject.mds.exception.action¶
ActionHandlerException¶
-
public class
ActionHandlerException
extends MdsException¶ The
ActionHandlerException
exception signals a situation in which there were some problems with executing action inorg.motechproject.mds.service.ActionHandlerService
.See also:
org.motechproject.mds.service.ActionHandlerService
org.motechproject.mds.exception.audit¶
HistoryInstanceNotFoundException¶
-
public class
HistoryInstanceNotFoundException
extends RuntimeException¶ Signals that a trash instance with the provided id was not found.
org.motechproject.mds.exception.csv¶
CsvImportException¶
-
public class
CsvImportException
extends MdsException¶ Signals that CSV import failed.
org.motechproject.mds.exception.dataprovider¶
DataProviderException¶
-
public class
DataProviderException
extends MdsException¶ The
DataProviderException
exception signals a situation in which there were some problems with executing lookup inorg.motechproject.mds.tasks.MDSDataProvider
.
org.motechproject.mds.exception.entity¶
DataMigrationFailedException¶
-
public class
DataMigrationFailedException
extends MdsException¶ Thrown when there were some error during combobox data migration.
EntityAlreadyExistException¶
-
public class
EntityAlreadyExistException
extends MdsException¶ The
EntityAlreadyExistException
exception signals a situation in which a user wants to create a new entity with a name that already exists in database.
EntityChangedException¶
-
public class
EntityChangedException
extends MdsException¶ This exception signals that an Entity was changed (presumably by another user).
EntityCreationException¶
-
public class
EntityCreationException
extends MdsException¶ The
EntityCreationException
exception signals a situation when there were problems with creating new entity class.
EntityInfrastructureException¶
-
public class
EntityInfrastructureException
extends MdsException¶ The
EntityInfrastructureException
exception signals a situation when there were problems with creating repository/service interface/service class for entity.
EntityInstancesNonEditableException¶
-
public class
EntityInstancesNonEditableException
extends MdsException¶ The
EntityInstancesNonEditableException
exception signals a situation in which an user try to edit an instance from nonEditable Entity.
EntityNotFoundException¶
-
public class
EntityNotFoundException
extends MdsException¶ The
EntityNotFoundException
exception signals a situation in which an entity with a given id does not exist in database.
EntityReadOnlyException¶
-
public class
EntityReadOnlyException
extends MdsException¶ The
EntityReadOnlyException
exception signals a situation in which a user wants to make changes on an entity which is read only (it was created by a module).
EntitySchemaMismatchException¶
-
public class
EntitySchemaMismatchException
extends MdsException¶ The
EntitySchemaMismatch
exception signals a situation in which a user wants to revert their instance to a version on a different schema version.
IncompatibleComboboxFieldException¶
-
public class
IncompatibleComboboxFieldException
extends MdsException¶ Throw when one of the combobox fields is not compatible (some instances are using multiple values for that field) with single-select.
Constructors¶
InvalidEntitySettingsException¶
-
public class
InvalidEntitySettingsException
extends MdsException¶ Signals that there were problems with the relation in the data model, due to incorrect entity settings.
InvalidJavaFieldNameException¶
-
public class
InvalidJavaFieldNameException
extends MdsException¶ The
InvalidJavaFieldNameException
exception signals a situation in which user tries to create the field with a name not being valid java identifier.
InvalidRelationshipException¶
-
public class
InvalidRelationshipException
extends MdsException¶ Signals that there were problems with the relations in the data model.
ReservedKeywordException¶
-
public class
ReservedKeywordException
extends MdsException¶ Signals that field/lookup name is invalid because it is a java keyword.
ServiceNotFoundException¶
-
public class
ServiceNotFoundException
extends MdsException¶ Signals that service for a corresponding entity was not found. This most likely signals an issue with entities bundle.
org.motechproject.mds.exception.field¶
EnumFieldAccessException¶
-
public class
EnumFieldAccessException
extends MdsException¶ Signals that getting value from an enum field failed.
FieldNotFoundException¶
-
public class
FieldNotFoundException
extends MdsException¶ This exception signals that a given field was not found for the Entity.
FieldReadOnlyException¶
-
public class
FieldReadOnlyException
extends MdsException¶ The
FieldReadOnlyException
exception signals an attempt to edit read only field.
FieldUsedInLookupException¶
-
public class
FieldUsedInLookupException
extends MdsException¶ Exception indicating that a field cannot be removed, since it is used in a lookup.
org.motechproject.mds.exception.importexport¶
org.motechproject.mds.exception.init¶
MdsEntityWireException¶
-
public class
MdsEntityWireException
extends MdsException¶ Exception, that informs about a problem when an entity is outside OSGi exported package. It contains message with problem description and possible solutions.
org.motechproject.mds.exception.jdo¶
JdoListenerInvocationException¶
-
public class
JdoListenerInvocationException
extends MdsException¶ Exception, that signalizes problems invoking method by the JDO lifecycle listener.
org.motechproject.mds.exception.lookup¶
CollectionResultFromLookupExpectedException¶
-
public class
CollectionResultFromLookupExpectedException
extends IllegalLookupReturnTypeException¶ Signals that a collection result was expected, but the lookup returned a single result.
IllegalLookupException¶
-
public class
IllegalLookupException
extends MdsException¶ Signals that the user defined an illegal lookup.
IllegalLookupReturnTypeException¶
-
public abstract class
IllegalLookupReturnTypeException
extends MdsException¶ Signals that the exception returns one object but we expected a list(or vice-versa).
LookupExecutionException¶
-
public class
LookupExecutionException
extends MdsException¶ Signals that it was not possible to execute a lookup for a given entity.
LookupExecutorException¶
-
public class
LookupExecutorException
extends MdsException¶ Signals that an error occurred during lookup execution.
LookupNotFoundException¶
-
public class
LookupNotFoundException
extends MdsException¶ The
LookupNotFoundException
exception signals a situation in which a lookup with given id does not exist in database.
LookupReadOnlyException¶
-
public class
LookupReadOnlyException
extends MdsException¶ The
LookupReadOnlyException
exception signals an attempt to edit read only lookup.
LookupReferencedException¶
-
public class
LookupReferencedException
extends MdsException¶ The
LookupReferencedException
exception signals a situation in which a lookup is used somewhere
LookupWrongFieldNameException¶
-
public class
LookupWrongFieldNameException
extends MdsException¶ Signals wrong field name in Lookup
LookupWrongParameterTypeException¶
-
public class
LookupWrongParameterTypeException
extends MdsException¶ Signals wrong type of lookup parameter
SingleResultFromLookupExpectedException¶
-
public class
SingleResultFromLookupExpectedException
extends IllegalLookupReturnTypeException¶ Signals that the lookup returned a Collection, while a single result was expected.
org.motechproject.mds.exception.object¶
ObjectCreateException¶
-
public class
ObjectCreateException
extends ObjectException¶ Signals that it was not possible to update object instance from the provided data.
ObjectException¶
-
public abstract class
ObjectException
extends MdsException¶ Signals that it was not possible to insert object data into database.
Constructors¶
ObjectNotFoundException¶
-
public class
ObjectNotFoundException
extends MdsException¶ Signals that the expected object was not found in the database.
ObjectReadException¶
-
public class
ObjectReadException
extends MdsException¶ Signals that it was not possible to parse the object coming from the database.
ObjectUpdateException¶
-
public class
ObjectUpdateException
extends ObjectException¶ Signals that it was not possible to update object instance from the provided data.
PropertyCopyException¶
-
public class
PropertyCopyException
extends MdsException¶ Thrown when there was a problem with property creation.
PropertyCreationException¶
-
public class
PropertyCreationException
extends MdsException¶ Thrown when there was a problem with property creation.
PropertyReadException¶
-
public class
PropertyReadException
extends MdsException¶ Thrown when there was a problem with property creation.
RevertFromTrashException¶
-
public class
RevertFromTrashException
extends MdsException¶ Signals an error when reverting an instance from trash.
SchemaVersionException¶
-
public class
SchemaVersionException
extends RuntimeException¶ Signals that a record has an outdated schema version.
SecurityException¶
-
public class
SecurityException
extends MdsException¶ The
SecurityException
exception signals a situation in which user wants to perform an operation on objects, they don’t have access to.
UserSuppliedComboboxValuesUsedException¶
-
public class
UserSuppliedComboboxValuesUsedException
extends MdsException¶ Exception indicating that user supplied value is used in an instance.
org.motechproject.mds.exception.rest¶
RestBadBodyFormatException¶
-
public class
RestBadBodyFormatException
extends MdsException¶ Signals that there were errors parsing the class from the provided body.
RestEntityNotFoundException¶
-
public class
RestEntityNotFoundException
extends MdsException¶ The
RestEntityNotFoundException
exception signals a situation in which an entity with a given id does not exist in database.
RestInternalException¶
-
public class
RestInternalException
extends MdsException¶ Signals an internal issue with the REST support.
RestLookupExecutionForbiddenException¶
-
public class
RestLookupExecutionForbiddenException
extends MdsException¶ Signals that the lookup can not be executed through REST since it is not exposed. Thrown only for existing lookups that are not exposed.
RestLookupNotFoundException¶
-
public class
RestLookupNotFoundException
extends MdsException¶ Signals that the lookup requested by REST does not exist.
RestNoLookupResultException¶
-
public class
RestNoLookupResultException
extends MdsException¶ Thrown when there was no result for a single-value lookup.
RestNotSupportedException¶
-
public class
RestNotSupportedException
extends MdsException¶ Signals that the entity does not support rest.
Constructors¶
org.motechproject.mds.exception.scheduler¶
org.motechproject.mds.exception.type¶
NoSuchTypeException¶
-
public class
NoSuchTypeException
extends MdsException¶ An exception which signals that a given type does not exist in the database.
TypeSettingNotFoundException¶
-
public class
TypeSettingNotFoundException
extends MdsException¶ The
TypeSettingNotFoundException
exception signals a situation in which a type setting for given type does not exists in database.
TypeValidationNotFoundException¶
-
public class
TypeValidationNotFoundException
extends MdsException¶ The
TypeValidationNotFoundException
exception signals a situation in which a type validation for given type does not exists in database.
org.motechproject.mds.filter¶
BooleanFilterValue¶
-
public class
BooleanFilterValue
extends FilterValue¶ Represents boolean values (YES/NO) for filtering data in MDS Data Browser. Provides proper value, param and operator for value.
ComboboxFilterValue¶
-
public class
ComboboxFilterValue
extends FilterValue¶ Represents Combobox values used for filtering in MDS Data Browser. Those values are defined by user when new entity is created. Provides proper value, param and operator for value.
DateFilterValue¶
-
public class
DateFilterValue
extends FilterValue¶ Represents Date values used for filtering data in MDS Data Browser. Provides proper value, param and operator for value.
Filter¶
-
public class
Filter
implements Serializable¶ Represents a filter on a field.
Constructors¶
Filter¶
-
public
Filter
(String field, FilterValue[] values)¶
Methods¶
getValues¶
-
public List<FilterValue>
getValues
()¶
setValues¶
-
public void
setValues
(FilterValue[] type)¶
FilterValue¶
-
public abstract class
FilterValue
¶ Represents a method of filtering.
Fields¶
org.motechproject.mds.helper¶
ActionParameterTypeResolver¶
-
public final class
ActionParameterTypeResolver
¶ The
ActionParameterTypeResolver
utility class provides a method that resolves tasks parameter type name based on entity field type.See also:
org.motechproject.mds.domain.Field
,org.motechproject.mds.domain.Type
ClassTableName¶
-
public final class
ClassTableName
¶ Util class, that provides methods connected to the table name generation.
Methods¶
getTableName¶
-
public static String
getTableName
(String table, String suffix)¶ Builds table name for the underlying database, based on the provided values. Replaces all occurences of hyphen (“-”) and space (” ”) with the underscore (“_”) and makes all characters uppercase.
Parameters: - table – the base table name
- suffix – suffix to use, after the base name
Returns: parsed table name
getTableName¶
-
public static String
getTableName
(Entity entity)¶ Builds table name for the underlying database, based on the given entity. Replaces all occurences of hyphen (“-”) and space (” ”) with the underscore (“_”) and makes all characters uppercase.
Parameters: - entity – entity to build table name for
Returns: parsed table name
getTableName¶
-
public static String
getTableName
(Entity entity, EntityType type)¶ Builds table name for the underlying database, based on the given entity. Replaces all occurences of hyphen (“-”) and space (” ”) with the underscore (“_”) and makes all characters uppercase.
Parameters: - entity – entity to build table name for
- type – the type of an entity; will be added to the end of the name, if other than “STANDARD”
Returns: parsed table name
getTableName¶
-
public static String
getTableName
(String className, String module, String namespace, String tableName, EntityType entityType)¶ Builds table name for the underlying database, based on the provided values. Replaces all occurences of hyphen (“-”) and space (” ”) with the underscore (“_”) and makes all characters uppercase.
Parameters: - className – fully qualified or simple name of the class
- module – entity module (defaults to “MDS”)
- namespace – namespace of the entity
- tableName – base table name; if not empty, this method will simply append the type of an entity to the base name
- entityType – the type of the entity; will be added to the end of the name, if other than “STANDARD”
Returns: parsed table name
ComboboxDataMigrationHelper¶
-
public class
ComboboxDataMigrationHelper
¶ Responsible for migrating data of Combobox fields between correct tables. Transfers data from entity table to Combobox table if selecting multiple values has been allowed. Also migrated data back to entity table if that option has been disallowed.
Methods¶
migrateComboboxDataIfNecessary¶
setPersistenceManagerFactory¶
-
public void
setPersistenceManagerFactory
(PersistenceManagerFactory persistenceManagerFactory)¶
setSettingsService¶
-
public void
setSettingsService
(SettingsService settingsService)¶
setSqlDBManager¶
-
public void
setSqlDBManager
(SqlDBManager sqlDBManager)¶
ComboboxHelper¶
-
public final class
ComboboxHelper
¶ Helper class for listing selection type changes.
Methods¶
comboboxesWithChangedSelectionType¶
-
public static Map<String, Boolean>
comboboxesWithChangedSelectionType
(List<Field> oldFields, List<Field> newFields)¶ Returns map of fields with changed selection type. Key is fields name and value defines whether field will be using multi-select or not.
Parameters: - oldFields – the definitions of the fields before change
- newFields – the definitions of the fields after change
Returns: the map of fields with changed selection type
DataServiceHelper¶
-
public final class
DataServiceHelper
¶ The
DataServiceHelper
is a helper class that simplifies retrieving Data Service for a given entity.See also:
org.motechproject.mds.service.MotechDataService
,org.motechproject.mds.domain.Entity
Methods¶
getDataService¶
-
public static MotechDataService
getDataService
(BundleContext bundleContext, String entityClass)¶ Retrieves
org.motechproject.mds.service.MotechDataService
implementation for the given entity class. It will throworg.motechproject.mds.exception.entity.ServiceNotFoundException
, in case a service for the given entity class cannot be found.Parameters: - bundleContext – context of a bundle
- entityClass – fully qualified class name of an entity
Returns: generated
org.motechproject.mds.service.MotechDataService
implementation
getDataService¶
-
public static MotechDataService
getDataService
(BundleContext bundleContext, Entity entity)¶ Retrieves
org.motechproject.mds.service.MotechDataService
implementation for the given entity. It will throworg.motechproject.mds.exception.entity.ServiceNotFoundException
, in case a service for the given entity class cannot be found.Parameters: - bundleContext – context of a bundle
- entity – entity representation, to retrieve its service for
Returns: generated
org.motechproject.mds.service.MotechDataService
implementation
EntityDefaultFieldsHelper¶
-
public final class
EntityDefaultFieldsHelper
¶ Helper class, responsible for generating default fields, that are a part of each base entity.
EntityHelper¶
-
public final class
EntityHelper
¶ The
EntityHelper
class contains useful methods that helps managing entities.See also:
org.motechproject.mds.domain.Entity
EntitySorter¶
-
public final class
EntitySorter
¶ The
EntitySorter
is a helper class that allows to sort and validate entities.
Methods¶
sortByHasARelation¶
-
public static List<EntityDto>
sortByHasARelation
(List<EntityDto> allEntities, SchemaHolder schemaHolder)¶ Takes a list of entities and sorts them, according to relationships they have. The entities that have uni-directional relationship with another entity, will be moved to the position behind the entity they are related with. The bi-directional relationships are not sorted, moreover if invalid bi-directional relationship is found, an exception is thrown.
Parameters: - schemaHolder – the holder of the current MDS schema
Returns: List of entities, sorted by relationship
sortByInheritance¶
-
public static List<EntityDto>
sortByInheritance
(List<EntityDto> list)¶ Takes a list of entities and sorts them by the inheritance tree. The entities that extend the Object class or MdsEntity class will be moved to the beggining of the list. After that, the entites that are already present on the list will be added, up the inheritance tree.
Parameters: - list – Initial list of entities to sort
Returns: List of entities, sorted by inheritance tree
EnumHelper¶
-
public final class
EnumHelper
¶ This is a helper class, used while generating enums in MDS.
Methods¶
prefixEnumValue¶
-
public static String
prefixEnumValue
(String value)¶ Prefixes enum values, if they start with illegal character (other than letter, dollar sign or underscore
Parameters: - value – an enum value
Returns: either the same value, if the value is legal, or value prefixed with underscore, if the value is illegal
prefixEnumValues¶
-
public static Collection<String>
prefixEnumValues
(Collection<String> values)¶ Prefixes a collection of enum values. For each value in the collection,
prefixEnumValue(java.lang.String)
is called.Parameters: - values – a collection of enum values
Returns: a collection of prefixed values
FieldHelper¶
-
public final class
FieldHelper
¶ Utility class handling dynamic setting of field values
JavassistBuilder¶
-
public final class
JavassistBuilder
¶ Builder class for javassist related tasks. Helps with building appropriate elements of class e.g. fields, getters, field initializer
Methods¶
createCollectionInitializer¶
createEnumInitializer¶
createField¶
-
public static CtField
createField
(CtClass declaring, CtClass type, String name, String genericSignature)¶ Creates class field with the given name for the given class declaration and type.
Parameters: - declaring – the class to which the field will be added
- type – the field type
- name – the field name
- genericSignature – the generic signature
Throws: - CannotCompileException – when bytecode transformation has failed
Returns: An instance of
javassist.CtField
represents a field
createGetter¶
-
public static CtMethod
createGetter
(String fieldName, CtClass declaring, CtField field)¶ Creates a public getter method with the given field name for the given class declaration and type.
Parameters: - fieldName – the field name
- declaring – the class to which the getter will be added
- field – the field declaration
Throws: - CannotCompileException – when bytecode transformation has failed
Returns: An instance of
javassist.CtMethod
represents a getter method
createInitializer¶
createInitializer¶
createJavaTimeInitializer¶
-
public static CtField.Initializer
createJavaTimeInitializer
(String type, String defaultValue)¶ Makes a initializer for
java.time.LocalDate
orjava.time.LocalDateTime
classParameters: - type – the field type
- defaultValue – the default value as string
Returns: java.time.LocalDate
orjava.time.LocalDateTime
initializer based on a type parameter
createListInitializer¶
createLocaleInitializer¶
-
public static CtField.Initializer
createLocaleInitializer
(Object defaultValue)¶ Makes an initializer for
java.util.Locale
class.Parameters: - defaultValue – the default value
Returns: java.util.Locale
initializer
createSetInitializer¶
createSetter¶
-
public static CtMethod
createSetter
(String fieldName, CtField field)¶ Creates a public setter method with the given field name for the given class declaration and type.
Parameters: - fieldName – the field name
- field – the field declaration
Throws: - CannotCompileException – when bytecode transformation has failed
Returns: An instance of
javassist.CtMethod
represents a setter method
createSimpleInitializer¶
RelationshipResolver¶
-
public class
RelationshipResolver
¶ The
RelationshipResolver
class provides a method that removes unresolved entities from a set. Entity is considered unresolved if at least one of its dependencies is not contained in provided set or does not exist in database.See also:
org.motechproject.mds.domain.Entity
RelationshipSorter¶
-
public class
RelationshipSorter
¶ The
RelationshipSorter
class provides method that sorts given entities list using dependency ordering. It means, that if entity A depends on entity B, B will be before A in sorted list. In case of any circular dependencies, entities contained in the cycle are considered equal, thus their mutual positions are unspecified.
org.motechproject.mds.helper.bundle¶
MdsBundleHelper¶
-
public final class
MdsBundleHelper
¶ Helper class, that provides utility methods for MDS OSGi bundles.
Methods¶
findMdsBundle¶
-
public static Bundle
findMdsBundle
(BundleContext bundleContext)¶
findMdsEntitiesBundle¶
-
public static Bundle
findMdsEntitiesBundle
(BundleContext bundleContext)¶
getMdsBundleClassLoader¶
-
public static ClassLoader
getMdsBundleClassLoader
(BundleContext bundleContext)¶ Returns the Bundle ClassLoader of the MDS bundle.
Parameters: - bundleContext – the bundle context from which the MDS bundle should get retrieved from
Returns: the MDS bundle ClassLoader
getMdsEntitiesBundleClassLoader¶
-
public static ClassLoader
getMdsEntitiesBundleClassLoader
(BundleContext bundleContext)¶ Returns the Bundle ClassLoader of the MDS Entities bundle.
Parameters: - bundleContext – the bundle context from which the MDS Entities bundle should get retrieved from
Returns: the MDS bundle ClassLoader
isMdsClassLoader¶
-
public static boolean
isMdsClassLoader
(ClassLoader classLoader)¶
searchForBundle¶
-
public static Bundle
searchForBundle
(BundleContext context, Entity entity)¶ Method used to retrieve bundle of the entity passed as a parameter. It converts Entity object to EntityDto and then tries to find bundle basing on module symbolic name. If module symbolic name is null it retrieves bundle basing on module name.
Parameters: - context – BundleContext to be searched
- entity – Entity for which bundle is searched
Returns: Bundle of the entity passed as a parameter
searchForBundle¶
-
public static Bundle
searchForBundle
(BundleContext context, EntityDto entity)¶ Method used to retrieve bundle of the entity dto passed as a parameter. It tries to find bundle basing on module symbolic name. If module symbolic name is null it retrieves bundle basing on module name.
Parameters: - context – BundleContext to be searched
- entity – EntityDto for which bundle is searched
Returns: Bundle of the entity dto passed as a parameter
unregisterBundleJDOClasses¶
-
public static void
unregisterBundleJDOClasses
(Bundle bundle)¶ Unregisters all entity classes registered to JDO that are accessible from bundle class loader. This method should be called after bundle that registers MDS entities gets unresolved, so that they are removed from JDO cache. Not doing this might produce hard to track exception when refreshing MDS Entities Bundle after bundle removal.
Parameters: - bundle – the bundle for which entity classes are to be unregistered
org.motechproject.mds.javassist¶
JavassistLoader¶
-
public class
JavassistLoader
extends Loader<ClassData>¶ The
JavassistLoader
is a implementation of theorg.motechproject.mds.util.Loader
interface. It takes class information from instance oforg.motechproject.mds.domain.ClassData
and the missing classes are taken fromorg.motechproject.mds.javassist.MotechClassPool
See also:
org.motechproject.mds.util.Loader
,org.motechproject.mds.domain.ClassData
,org.motechproject.mds.javassist.MotechClassPool
Constructors¶
JavassistLoader¶
-
public
JavassistLoader
(MDSClassLoader classLoader)¶
MotechClassPool¶
-
public final class
MotechClassPool
¶ This class holds the javasisst classpool, enriched by motech classes. All predefined additions to the ClassPool should take place here. The classpool should also be retrieved using this class, in order to be sure that the a initialization took place.
Methods¶
getEnhancedClasses¶
-
public static Collection<ClassData>
getEnhancedClasses
(boolean includeInerfaces)¶
registerEnhancedClassData¶
registerServiceInterface¶
registeredEnums¶
-
public static Collection<String>
registeredEnums
()¶
registeredInterfaces¶
-
public static Collection<String>
registeredInterfaces
()¶
org.motechproject.mds.jdo¶
AbstractObjectValueGenerator¶
-
public abstract class
AbstractObjectValueGenerator
<T> implements ObjectValueGenerator¶ Base class for other generator classes. It takes value of property (see
getPropertName()
method) from object and modify it depending on the implementation. If the modified value is null then thejava.lang.IllegalStateException
is thrown.Parameters: - <T> – type of property
Methods¶
CreationDateValueGenerator¶
-
public class
CreationDateValueGenerator
extends DateTimeValueGenerator¶ The
CreationDateValueGenerator
class is responsible for generating value fororg.motechproject.mds.util.Constants.Util.CREATION_DATE_FIELD_NAME
field.
CreatorValueGenerator¶
-
public class
CreatorValueGenerator
extends UsernameValueGenerator¶ The
CreatorValueGenerator
class is responsible for generating value fororg.motechproject.mds.util.Constants.Util.CREATOR_FIELD_NAME
field.
DateTimeValueGenerator¶
-
public abstract class
DateTimeValueGenerator
extends AbstractObjectValueGenerator<DateTime>¶ The
DateTimeValueGenerator
class modifies properties withorg.joda.time.DateTime
type. If the given value is null then the current time is returned; otherwise the given value is returned.
MDSClassLoaderResolver¶
-
public class
MDSClassLoaderResolver
implements ClassLoaderResolver¶ This is a wrapper for
org.motechproject.mds.jdo.MDSClassLoaderResolverImpl
. All calls for theorg.datanucleus.ClassLoaderResolver
interface are passed to the current instance of the ClassLoaderResolver implementation. When we hit a NullPointerException originating in Felix, we can determine it is due to a synchronization bug after bundle updates - as a result of this DataNucleus has passed us ClassLoaders from the former Bundle version. In that case we reload the instance passing it the ClassLoaders from the new bundle.
Constructors¶
MDSClassLoaderResolver¶
-
public
MDSClassLoaderResolver
(ClassLoader pmLoader)¶
Methods¶
classForName¶
-
public Class
classForName
(String name, ClassLoader primary)¶
classForName¶
-
public Class
classForName
(String name, ClassLoader primary, boolean initialize)¶
getResource¶
-
public URL
getResource
(String resourceName, ClassLoader primary)¶
getResources¶
-
public Enumeration<URL>
getResources
(String resourceName, ClassLoader primary)¶
registerUserClassLoader¶
-
public void
registerUserClassLoader
(ClassLoader loader)¶
setPrimary¶
-
public void
setPrimary
(ClassLoader primary)¶
setRuntimeClassLoader¶
-
public void
setRuntimeClassLoader
(ClassLoader loader)¶
MDSClassLoaderResolverImpl¶
-
class
MDSClassLoaderResolverImpl
extends ClassLoaderResolverImpl¶ The main purpose of the
MDSClassLoaderResolverImpl
class is to avoid situation in which standard datanucleus class loader resolver does not see classes that are saved in database. This is the main implementation that extends the standard ClassLoaderResolverImpl from datanucleus. Due to a synchronization bug in Felix, there are cases when we will instantiate this more then once (after we hit the bug).
Constructors¶
MDSClassLoaderResolverImpl¶
-
public
MDSClassLoaderResolverImpl
(ClassLoader pmLoader)¶
MdsIgnoreAnnotationHandler¶
-
public class
MdsIgnoreAnnotationHandler
implements MemberAnnotationHandler¶ The
MdsIgnoreAnnotationHandler
provides a mechanism to handle entity fields annotated with @Ignore at the DataNucleus level, so that there is no database column created for that field.See also:
org.motechproject.mds.annotations.Ignore
MdsJdoAnnotationReader¶
-
public class
MdsJdoAnnotationReader
extends JDOAnnotationReader¶ MDS JDO annotation reader, extends the regular
org.datanucleus.api.jdo.metadata.JDOAnnotationReader
This class was introduced becauseorg.datanucleus.api.jdo.metadata.JDOAnnotationReader
would not read field annotations for metadata if there was no class level JDO annotations. This extension will recognize theorg.motechproject.mds.annotations.Entity
annotation as an annotation indicating that the class is persistence capable.
MdsJdoDialect¶
-
public class
MdsJdoDialect
extends DefaultJdoDialect¶ This is an extensions of Springs default JDO dialect that allows controlling the transaction serialization level per transaction with Spring transactions. This was fixed in newer versions of Spring and this class should get removed once we upgrade to a newer Spring version.
Methods¶
beginTransaction¶
-
public Object
beginTransaction
(Transaction transaction, TransactionDefinition definition)¶
getJdoIsolationLevel¶
-
protected String
getJdoIsolationLevel
(TransactionDefinition definition)¶
MdsLongVarBinaryRDBMSMapping¶
-
public class
MdsLongVarBinaryRDBMSMapping
extends LongVarBinaryRDBMSMapping¶ Mapping of a LONGVARBINARY RDBMS type. This implementation will try use context class loader, joda -time bundle class loader and mds-entities bundle class loader for resolving classes during object deserialisation when errors occur when using the default implementation.
Constructors¶
MdsTransactionManager¶
-
public class
MdsTransactionManager
extends JdoTransactionManager¶ We override springs transaction for classloader control. We store context classloaders as thread local variables, and switch them with the bundle classloader for the transaction. Since we only allow operations in transactions, this entry point for classloader switching is enough.
Methods¶
doBegin¶
-
protected void
doBegin
(Object transaction, TransactionDefinition definition)¶
getBundleClassLoader¶
-
public ClassLoader
getBundleClassLoader
()¶
setBundleClassLoader¶
-
public void
setBundleClassLoader
(ClassLoader bundleClassLoader)¶
setBundleContext¶
-
public void
setBundleContext
(BundleContext bundleContext)¶
ModificationDateValueGenerator¶
-
public class
ModificationDateValueGenerator
extends DateTimeValueGenerator¶ The
ModificationDateValueGenerator
class is responsible for generating value fororg.motechproject.mds.util.Constants.Util.MODIFICATION_DATE_FIELD_NAME
field.
ModifiedByValueGenerator¶
-
public class
ModifiedByValueGenerator
extends UsernameValueGenerator¶ The
ModifiedByValueGenerator
class is responsible for generating value fororg.motechproject.mds.util.Constants.Util.MODIFIED_BY_FIELD_NAME
field.
OwnerValueGenerator¶
-
public class
OwnerValueGenerator
extends UsernameValueGenerator¶ The
OwnerValueGenerator
class is responsible for generating value fororg.motechproject.mds.util.Constants.Util.OWNER_FIELD_NAME
field.
SchemaGenerator¶
-
public class
SchemaGenerator
implements InitializingBean¶ The schema generator class is responsible for generating the table schema for entities and for running entities migrations upon start. Schema for all entity classes has to be generated, otherwise issues might arise in foreign key generation for example. This code runs in the generated entities bundle.
Fields¶
Constructors¶
TimeTypeConverter¶
-
public class
TimeTypeConverter
implements TypeConverter<Time, String>¶ This is datanucleus type converter we plug in. It is responsible for converting
org.motechproject.commons.date.model.Time
instances to Strings which are persisted.
UsernameValueGenerator¶
-
public abstract class
UsernameValueGenerator
extends AbstractObjectValueGenerator<String>¶ The
UsernameValueGenerator
class modifies properties withjava.lang.String
type. The given value is returned without any change if it is not blank. Otherise the class tries to get current logged user name. If the user exists and name is not blank then this name is returned otherwise the empty string is returned.
org.motechproject.mds.listener¶
MotechLifecycleListener¶
-
public class
MotechLifecycleListener
¶ Contains essential information about InstanceLifecycleListeners, which are provided by
org.motechproject.mds.annotations.InstanceLifecycleListener
annotation.See also:
org.motechproject.mds.annotations.InstanceLifecycleListener
Constructors¶
Methods¶
org.motechproject.mds.listener.proxy¶
ProxyJdoListener¶
-
public class
ProxyJdoListener
implements CreateLifecycleListener, StoreLifecycleListener, DeleteLifecycleListener, LoadLifecycleListener¶ The
ProxyJdoListener
is a listener for persistence events. This listener is for a set of defined classes which are registered in DataNucleus byorg.motechproject.mds.listener.register.JdoListenerRegister
. It is responsible for invoking methods, which are annotated byorg.motechproject.mds.annotations.InstanceLifecycleListener
.See also:
org.motechproject.mds.listener.register.JdoListenerRegister
,org.motechproject.mds.annotations.InstanceLifecycleListener
Methods¶
postCreate¶
-
public void
postCreate
(InstanceLifecycleEvent event)¶
postDelete¶
-
public void
postDelete
(InstanceLifecycleEvent event)¶
postLoad¶
-
public void
postLoad
(InstanceLifecycleEvent event)¶
postStore¶
-
public void
postStore
(InstanceLifecycleEvent event)¶
preDelete¶
-
public void
preDelete
(InstanceLifecycleEvent event)¶
preStore¶
-
public void
preStore
(InstanceLifecycleEvent event)¶
org.motechproject.mds.listener.records¶
BaseListener¶
-
public abstract class
BaseListener
<T> implements ServiceListener¶ A base class for listeners in MDS. Since listeners get constructed by JDO, we don’t normally have access to the spring context of MDS entities. This class retrieves this context by registering as a service listener that for the
org.springframework.context.ApplicationContext
. After the context gets retrieved it can be used for retrieving the service specified by the implementing listener. If service retrieval is initiated before the context is available, a wait time of max 5 minutes will begin.Parameters: - <T> – the type of the service which is used by the implementing listener
HistoryListener¶
-
public class
HistoryListener
extends BaseListener<HistoryService> implements StoreLifecycleListener¶ The history listener which listens to store events. After the object gets stored this listener will create its history using the
org.motechproject.mds.service.HistoryService
. Listener operations are executed in one transaction with the actual store.
Methods¶
getServiceClass¶
-
protected Class<HistoryService>
getServiceClass
()¶
postStore¶
-
public void
postStore
(InstanceLifecycleEvent event)¶
preStore¶
-
public void
preStore
(InstanceLifecycleEvent event)¶
TrashListener¶
-
public class
TrashListener
extends BaseListener<TrashService> implements DeleteLifecycleListener¶ The trash listener which listens to delete events. Before an object gets delete this listener will act based on the configured trash mode. If the trash mode is set to using trash, it will move this object to the trash bin using the
org.motechproject.mds.service.TrashService
. If trash mode is not set and deletes are permanent, this listener will remove the object history. Listener operations are executed in one transaction with the actual delete.
Methods¶
getServiceClass¶
-
protected Class<TrashService>
getServiceClass
()¶
postDelete¶
-
public void
postDelete
(InstanceLifecycleEvent event)¶
preDelete¶
-
public void
preDelete
(InstanceLifecycleEvent event)¶
org.motechproject.mds.listener.register¶
EntitiesClassListLoader¶
-
public final class
EntitiesClassListLoader
¶ Utility classes used in the MDS Entities Bundle for reading the txt files containing class names.
Methods¶
JdoListenerRegister¶
-
public class
JdoListenerRegister
¶ This class adds listener entries to the properties passed to DataNucleus. The classes for which listeners will be called are read from the entities file. This class executes within the entities bundle, constructed through xml.
Methods¶
addJdoListeners¶
-
public Properties
addJdoListeners
(Properties properties)¶
org.motechproject.mds.lookup¶
EntityLookups¶
-
public class
EntityLookups
¶ Stores information about lookups and classname of the related entity.
LookupExecutor¶
-
public class
LookupExecutor
¶ This class allows executing lookups by providing the lookup name as a string and the lookup params in name-value map. Used both by the REST api and the Databrowser UI for executing lookups based on only metadata. The dataservice and metadata must be provided during construction.
Constructors¶
org.motechproject.mds.performance.service¶
MdsDummyDataGenerator¶
-
public interface
MdsDummyDataGenerator
¶
Methods¶
generateDummyEntities¶
-
void
generateDummyEntities
(int numberOfEntities, boolean regenerateBundle)¶ Generate a given amount of empty entities
Parameters: - numberOfEntities – How many entities should be generated
- regenerateBundle – Should the data bundle be regenerated after entities are created
Throws: - IOException –
generateDummyEntities¶
-
void
generateDummyEntities
(int numberOfEntities, int fieldsPerEntity, int lookupsPerEntity, boolean regenerateBundle)¶ Generate a given amount of entities
Parameters: - numberOfEntities – How many entities should be generated
- fieldsPerEntity – How many fields should each entity have - type of field is assigned randomly
- lookupsPerEntity – How many lookups should each entity have
- regenerateBundle – Should the data bundle be regenerated after entities are created
Throws: - IOException –
generateDummyInstances¶
-
void
generateDummyInstances
(Long entityId, int numberOfInstances)¶ Generates a given amount of instances. For most common field types, values will be automatically assigned.
Parameters: - entityId – Id of an entity, for which we want to generate instances
- numberOfInstances – How many instances should be generated
Throws:
generateDummyInstances¶
-
void
generateDummyInstances
(Long entityId, int numberOfInstances, int numberOfHistoricalRevisions, int numberOfTrashInstances)¶ Generates a given amount of instances, historical revisions and deleted instances. For most common field types, values will be automatically assigned.
Parameters: - entityId – Id of an entity, for which we want to generate instances
- numberOfInstances – How many instances should be generated
- numberOfHistoricalRevisions – How many historical revisions should be generated
- numberOfTrashInstances – How many instances in trash should be generated
Throws:
getService¶
-
MotechDataService
getService
(BundleContext bundleContext, String className)¶
makeDummyInstance¶
-
Object
makeDummyInstance
(Long entityId)¶ Makes a dummy instance for a given entity. It won’t insert the created instance into the database, so it can be used to prepare a large dataset of random instances (for example, to insert them manually and measure time)
Parameters: - entityId – Id of an entity, for which we want to generate instance
Throws: Returns: Generated instance, with randomly assigned fields
setEntityPrefix¶
setFieldPrefix¶
SampleService¶
-
public interface
SampleService
extends MotechDataService<Sample>¶
org.motechproject.mds.performance.service.impl¶
MdsDummyDataGeneratorImpl¶
-
public class
MdsDummyDataGeneratorImpl
implements MdsDummyDataGenerator¶ The
MdsDummyDataGenerator
class, allows developers and testers to create any amount of dummy entities and instances in MDS.
Constructors¶
MdsDummyDataGeneratorImpl¶
-
public
MdsDummyDataGeneratorImpl
(EntityService entityService, JarGeneratorService jarGeneratorService, BundleContext bundleContext)¶
Methods¶
generateDummyEntities¶
-
public void
generateDummyEntities
(int numberOfEntities, int fieldsPerEntity, int lookupsPerEntity, boolean regenerateBundle)¶
generateDummyInstances¶
getService¶
-
public MotechDataService
getService
(BundleContext bundleContext, String className)¶
org.motechproject.mds.query¶
AbstractCollectionBasedProperty¶
-
public abstract class
AbstractCollectionBasedProperty
<T extends Collection> extends Property<T>¶ Base for collection based properties
Parameters: - <T> – type of the underlying collection
Methods¶
generateDeclareParameter¶
-
public CharSequence
generateDeclareParameter
(int idx)¶
unwrap¶
-
public Collection
unwrap
()¶
CollectionProperty¶
-
public class
CollectionProperty
extends AbstractCollectionBasedProperty<Collection>¶ The
CollectionProperty
class represent a property that will be used in JDO query and it has to have the given value(s).
Constructors¶
Methods¶
generateFilter¶
-
public CharSequence
generateFilter
(int idx)¶
CustomOperatorProperty¶
EqualProperty¶
-
public class
EqualProperty
<T> extends Property<T>¶ The
EqualProperty
class represents a property that will be used in JDO query and it has to be equal to the given value.Parameters: - <T> – type of the passed value
Constructors¶
Methods¶
generateFilter¶
-
public CharSequence
generateFilter
(int idx)¶
EqualsCaseInsensitiveProperty¶
-
public class
EqualsCaseInsensitiveProperty
extends CustomOperatorProperty<String>¶ A convenience extension of the
CustomOperatorProperty
. The custom operator is “equalsIgnoreCase()”, the underlying type is String.
InMemoryQueryFilter¶
-
public final class
InMemoryQueryFilter
¶ A utility for performing in memory filtering on collections. This is not performance efficient, since its done on the application level. Filtering at the database level is advised.
Methods¶
filter¶
-
public static <T> List<T>
filter
(Collection<T> objects, QueryParams queryParams)¶ Filters the provided collection based on the provided query params.
Parameters: - objects – the collection to filter
- queryParams – the query params with the ordering and paging information to apply
- <T> – the type of the filtered collection
Returns: the filtered, ordered list of objects from the original collection
MatchesCaseInsensitiveProperty¶
-
public class
MatchesCaseInsensitiveProperty
extends CustomOperatorProperty<String>¶ A convenience extension of the
CustomOperatorProperty
. The custom operator is “matches()” with an added case insensitivity flag added, the underlying type is String. The value passed will be wrapped inside (?i).*.* for matching purposes.
Constructors¶
MatchesProperty¶
-
public class
MatchesProperty
extends CustomOperatorProperty<String>¶ A convenience extension of the
org.motechproject.mds.query.CustomOperatorProperty
. The custom operator is “matches()” and the underlying type is String. The value passed will be wrapped inside .*.* for matching purposes.
Constructors¶
Property¶
-
public abstract class
Property
<T>¶ The
Property
class represents a property that will be used in JDO query. Classes that extend this class should define how that property should be used in WHERE section in JDO query.Parameters: - <T> – type of the passed value
Constructors¶
Methods¶
asDeclareParameter¶
-
public CharSequence
asDeclareParameter
(int idx)¶
asFilter¶
-
public CharSequence
asFilter
(int idx)¶
generateDeclareParameter¶
-
protected CharSequence
generateDeclareParameter
(int idx)¶
generateFilter¶
-
protected abstract CharSequence
generateFilter
(int idx)¶
unwrap¶
-
public Collection
unwrap
()¶
PropertyBuilder¶
-
public final class
PropertyBuilder
¶ The
PropertyBuilder
class is a util class that helps create appropriate property class based on passed name and value.
QueryExecution¶
-
public interface
QueryExecution
<T>¶ Allows users to execute custom queries through Motech Data Services. Implementations need only to implement the execute method, which can operate directly on the
javax.jdo.Query
object. The return value type is left to the implementation.Parameters: - <T> – the type that will be returned from this query
Methods¶
execute¶
-
T
execute
(Query query, InstanceSecurityRestriction restriction)¶ The implementation of this method is supposed to run the JDO query on the provided
Query
object.Parameters: - query – the query object that is supposed to be executed
- restriction – the entity instances restrictions put on this query
Returns: defining the return type is left to whoever implements this interface
QueryExecutor¶
-
public final class
QueryExecutor
¶ The
QueryExecutor
util class provides methods that help execute a JDO query.
Methods¶
execute¶
-
public static Object
execute
(Query query, InstanceSecurityRestriction restriction)¶
execute¶
-
public static Object
execute
(Query query, Object value, InstanceSecurityRestriction restriction)¶
executeDelete¶
-
public static long
executeDelete
(Query query, Object value, InstanceSecurityRestriction restriction)¶
executeDelete¶
-
public static long
executeDelete
(Query query, Object[] values, InstanceSecurityRestriction restriction)¶
QueryParams¶
-
public class
QueryParams
implements Serializable¶ Utility class containing parameters which control order and size of query results. Used mainly for paging/ordering queries from the UI.
Fields¶
ORDER_ID_ASC¶
-
public static final QueryParams
ORDER_ID_ASC
¶ Constant query parameter, that orders records ascending by ID.
Methods¶
ascOrder¶
-
public static QueryParams
ascOrder
(String field)¶ Creates query parameter that sorts records ascending, by the given field.
Parameters: - field – field to sort records by
Returns: query parameter, ordering records ascending
descOrder¶
-
public static QueryParams
descOrder
(String field)¶ Creates query parameter that sorts records descending, by the given field.
Parameters: - field – field to sort records by
Returns: query parameter, ordering records descending
QueryUtil¶
-
public final class
QueryUtil
¶ The
QueryUtil
util class provides methods that help developer to create a JDO query.See also:
javax.jdo.Query
RangeProperty¶
-
public class
RangeProperty
<T> extends Property<Range<T>>¶ The
RangeProperty
class represents a property that will be used in JDO query and it has to be inside the given range.Parameters: - <T> – type used in range.
Constructors¶
Methods¶
generateDeclareParameter¶
-
public CharSequence
generateDeclareParameter
(int idx)¶
generateFilter¶
-
public CharSequence
generateFilter
(int idx)¶
generateFilterForRelation¶
-
public CharSequence
generateFilterForRelation
(int idx)¶
unwrap¶
-
public Collection
unwrap
()¶
RestrictionProperty¶
-
public class
RestrictionProperty
extends EqualProperty<String>¶ The
RestrictionProperty
class represents a property that will be used in JDO query and depends on restriction criteria thecreator
orowner
field in an instance has to have the appropriate user name.
Constructors¶
RestrictionProperty¶
-
public
RestrictionProperty
(InstanceSecurityRestriction restriction, String value)¶
SetProperty¶
-
public class
SetProperty
<T> extends AbstractCollectionBasedProperty<Set<T>>¶ The
SetProperty
class represents a property that will be used in JDO query and it has to have one of the value from the given set.Parameters: - <T> – type used in set.
Constructors¶
Methods¶
generateFilter¶
-
public CharSequence
generateFilter
(int idx)¶
unwrap¶
-
public Collection
unwrap
()¶
SqlQueryExecution¶
-
public interface
SqlQueryExecution
<T>¶ Allows users to execute custom SQL queries through Motech Data Services. Implementations need to implement the execute method, which can operate directly on the
javax.jdo.Query
object andgetSqlQuery()
should return the sql query that will be executed. The return value type is left to the implementation. It is not advised to rely on raw SQL, however some use cases may require it.Parameters: - <T> – the type that will be returned from this query
Methods¶
execute¶
-
T
execute
(Query query)¶ The implementation of this method should prepare the
Query
object for the SQL query execution (eg. by inserting the necessary params).Parameters: - query – query object, that will be used during query execution
Returns: defining the return type is left to whoever implements this interface
org.motechproject.mds.repository¶
AbstractRepository¶
-
public abstract class
AbstractRepository
¶ Base for all repository classes used in Motech
Methods¶
doubleQuote¶
getPersistenceManager¶
-
public PersistenceManager
getPersistenceManager
()¶
getPersistenceManagerFactory¶
-
public PersistenceManagerFactory
getPersistenceManagerFactory
()¶
setPersistenceManagerFactory¶
-
public void
setPersistenceManagerFactory
(PersistenceManagerFactory persistenceManagerFactory)¶
ComboboxValueRepository¶
-
public class
ComboboxValueRepository
extends AbstractRepository¶ Responsible for fetching possible values for a combobox from the database. This repository is only defined in the MDS entities bundle.
Methods¶
getComboboxValuesForCollection¶
-
public List<String>
getComboboxValuesForCollection
(String cbTableName)¶ Retrieves all values for a multi-select combobox given its table name in the database. Multi-select comboboxes have values stored in a separate table, hence we need the table name.
Parameters: - cbTableName – the name of the combobox tables
Returns: all values for the combobox currently in the database
getComboboxValuesForStringField¶
-
public List<String>
getComboboxValuesForStringField
(EntityDto entityDto, FieldDto cbFieldDto)¶ Retrieves all values for a single-select combobox.
Parameters: - entityDto – the entity to which the combobox belongs to
- cbFieldDto – the field representing the combobox
Returns: all values for the combobox currently in the database
MotechDataRepository¶
-
public abstract class
MotechDataRepository
<T> extends AbstractRepository¶ This is a basic repository class with standard CRUD operations. It should be used by other repositories inside this package.
This class is also used as super class to create a repository related with the given entity schema in
org.motechproject.mds.builder.EntityInfrastructureBuilder
.Parameters: - <T> – the type of class
Constructors¶
Methods¶
count¶
-
public long
count
(InstanceSecurityRestriction restriction)¶
count¶
-
public long
count
(String[] properties, Object[] values, InstanceSecurityRestriction restriction)¶
count¶
-
public long
count
(List<Property> properties, InstanceSecurityRestriction restriction)¶
countForFilters¶
-
public long
countForFilters
(Filters filters, InstanceSecurityRestriction restriction)¶
delete¶
-
public long
delete
(String property, Object value, InstanceSecurityRestriction restriction)¶
delete¶
-
public long
delete
(String[] properties, Object[] values, InstanceSecurityRestriction restriction)¶
filter¶
-
public List<T>
filter
(Filters filters, QueryParams queryParams, InstanceSecurityRestriction restriction)¶
getPersistenceManager¶
-
public PersistenceManager
getPersistenceManager
()¶
retrieve¶
-
public T
retrieve
(String property, Object value, InstanceSecurityRestriction restriction)¶
retrieve¶
-
public T
retrieve
(String[] properties, Object[] values, InstanceSecurityRestriction restriction)¶
retrieveAll¶
-
public List<T>
retrieveAll
(Collection<Long> keys)¶
retrieveAll¶
-
public List<T>
retrieveAll
(InstanceSecurityRestriction restriction)¶
retrieveAll¶
-
public List<T>
retrieveAll
(String property, Object value, InstanceSecurityRestriction restriction)¶
retrieveAll¶
-
public List<T>
retrieveAll
(String[] properties, Object[] values, InstanceSecurityRestriction restriction)¶
retrieveAll¶
-
public List<T>
retrieveAll
(String[] properties, Object[] values, QueryParams queryParams, InstanceSecurityRestriction restriction)¶
retrieveAll¶
-
public List<T>
retrieveAll
(QueryParams queryParams, InstanceSecurityRestriction restriction)¶
retrieveAll¶
-
public List<T>
retrieveAll
(List<Property> properties, InstanceSecurityRestriction restriction)¶
retrieveAll¶
-
public List<T>
retrieveAll
(List<Property> properties, QueryParams queryParams, InstanceSecurityRestriction restriction)¶
retrieveUnique¶
-
public T
retrieveUnique
(List<Property> properties, InstanceSecurityRestriction restriction)¶
org.motechproject.mds.rest¶
MdsRestFacade¶
-
public interface
MdsRestFacade
<T>¶ Interface called by the REST controller REST operations. Should be exposed as an OSGi service for each MDS Entity. If rest is not supported, it throws a
org.motechproject.mds.exception.rest.RestNotSupportedException
.Parameters: - <T> – the entity class.
Methods¶
create¶
-
RestProjection
create
(InputStream instanceBody)¶ Creates an instance in MDS, reading it from the input stream. Only fields that are visible via REST will be set in the created instance. It will fail, if data read from input stream contains fields that do not exists or if field values do not match their type. It also throws
org.motechproject.mds.exception.rest.RestOperationNotSupportedException
if the entity settings do not permit CREATE access via REST.Parameters: - instanceBody – input stream, containing instance representation in JSON
Returns: created instance, in form of a map with field names and their respective values
delete¶
-
void
delete
(Long id)¶ Deletes an instance by id. This works exactly like deleting an instance in any other way, but will throw
org.motechproject.mds.exception.rest.RestOperationNotSupportedException
if the entity settings do not permit DELETE access via REST.Parameters: - id – id of the instance
executeLookup¶
-
Object
executeLookup
(String lookupName, Map<String, String> lookupMap, QueryParams queryParams, boolean includeBlob)¶ Executes a lookup for REST, given the lookup name, lookup parameters and query parameters. The result will only contain fields that are visible for REST. If requested lookup is not available via REST, this will throw
RestLookupExecutionForbiddenException
. If a lookup of given name does not exist, it throwsorg.motechproject.mds.exception.rest.RestLookupNotFoundException
.Parameters: - lookupName – name of the lookup
- lookupMap – map containing field names and their respective values
- queryParams – query parameters to use retrieving instances
- includeBlob – set to true, if you wish to retrieve value for binary object fields
Returns: lookup result, that can be either a single instance or a collection of instances. Response contains also metadata.
get¶
-
RestResponse
get
(QueryParams queryParams, boolean includeBlob)¶ Retrieves entity instances for REST. This will only include fields that are visible for REST. It throws
org.motechproject.mds.exception.rest.RestOperationNotSupportedException
if the entity settings do not permit READ access via REST.Parameters: - queryParams – query parameters to use retrieving instances
- includeBlob – set to true, if you wish to retrieve value for binary object fields
Returns: a response that contains metadata and list of instances, in form of a map with field names and their respective values
get¶
-
RestResponse
get
(Long id, boolean includeBlob)¶ Retrieves a single instance for REST. This will only include fields that are visible for REST. It throws
org.motechproject.mds.exception.rest.RestOperationNotSupportedException
if the entity settings do not permit READ access via REST.Parameters: - id – id of the instance
- includeBlob – set to true, if you wish to retrieve value for binary object fields
Returns: a response that contains metadata and instance
update¶
-
RestProjection
update
(InputStream instanceBody)¶ Updates an instance in MDS, reading it from the input stream. Only fields that are visible via REST will be set in the updated instance. It will fail, if data read from input stream contains fields that do not exists or if field values do not match their type. It also throws
org.motechproject.mds.exception.rest.RestOperationNotSupportedException
if the entity settings do not permit UPDATE access via REST.Parameters: - instanceBody – input stream, containing instance representation in JSON
Returns: updated instance, in form of a map with field names and their respective values
MdsRestFacadeImpl¶
-
public class
MdsRestFacadeImpl
<T> implements MdsRestFacade<T>¶ This
org.motechproject.mds.rest.MdsRestFacade
implementation retrieves REST related metadata on initialization. It uses an instance oforg.motechproject.mds.service.MotechDataService
for operations and the jackson JSON library for parsing InputStreams.Parameters: - <T> – the entity class
Methods¶
create¶
-
public RestProjection
create
(InputStream instanceBody)¶
executeLookup¶
get¶
-
public RestResponse
get
(QueryParams queryParams, boolean includeBlob)¶
get¶
-
public RestResponse
get
(Long id, boolean includeBlob)¶
setDataService¶
-
public void
setDataService
(MotechDataService<T> dataService)¶
setEntityInfoReader¶
-
public void
setEntityInfoReader
(EntityInfoReader entityInfoReader)¶
update¶
-
public RestProjection
update
(InputStream instanceBody)¶
RestMetadata¶
-
public class
RestMetadata
¶ The
RestResponse
class represents metadata of retrieved instances over REST. It contains entity name, entity class name, module name, namespace and pagination informationSee also:
org.motechproject.mds.rest.MdsRestFacade
,org.motechproject.mds.rest.RestProjection
,org.motechproject.mds.rest.RestMetadata
Constructors¶
RestMetadata¶
-
public
RestMetadata
(String entity, String className, String moduleName, String namespace, Long totalCount, QueryParams queryParams)¶ Constructor.
Parameters: - entity – the entity name
- className – the name of the entity class
- moduleName – the module name
- namespace – the namespace in which the entity is defined
- totalCount – the total number of instances that match the search conditions
- queryParams – the query params used to retrieve instances
RestProjection¶
-
public class
RestProjection
extends LinkedHashMap<String, Object>¶ The
RestProjection
class represents entity fields projection onto entity fields exposed over REST. Because of its Map interface inheritance, we can leave output handling to other components. Additionally, LinkedHashMap ensures unchanged fields order.See also:
org.motechproject.mds.rest.MdsRestFacade
RestResponse¶
-
public class
RestResponse
¶ The
RestResponse
class represents data retrieved over REST. It contains metadata and data.See also:
org.motechproject.mds.rest.MdsRestFacade
,org.motechproject.mds.rest.RestProjection
,org.motechproject.mds.rest.RestMetadata
Constructors¶
RestResponse¶
-
public
RestResponse
(String entity, String className, String moduleName, String namespace, Long totalSize, QueryParams queryParams, List<RestProjection> data)¶ Constructor.
Parameters: - entity – the entity name
- className – the name of the entity class
- moduleName – the module name
- namespace – the namespace in which the entity is defined
- totalSize – the total number of data that match the search conditions
- queryParams – the query params used to retrieve data
- data – the list of the data
RestResponse¶
-
public
RestResponse
(String entity, String className, String moduleName, String namespace, Long totalSize, QueryParams queryParams, RestProjection data)¶ Constructor.
Parameters: - entity – the entity name
- className – the name of the entity class
- moduleName – the module name
- namespace – the namespace in which the entity is defined
- totalSize – the total number of data that match the search conditions
- queryParams – the query params used to retrieve data
- data – the record
Methods¶
getData¶
-
public List<RestProjection>
getData
()¶ Returns: the list of the data
getMetadata¶
-
public RestMetadata
getMetadata
()¶ Returns: the metadata for the response
setData¶
-
public void
setData
(List<RestProjection> data)¶ Parameters: - data – the list of the data
setMetadata¶
-
public void
setMetadata
(RestMetadata metadata)¶ Parameters: - metadata – the metadata for the response
org.motechproject.mds.service¶
ActionHandlerService¶
-
public interface
ActionHandlerService
¶ The
ActionHandlerService
interface provides methods for handling tasks actions events related with MDS CRUD operations.
Methods¶
create¶
-
void
create
(Map<String, Object> parameters)¶ Creates an instance of the entity, based on the provided parameters. The parameters should contain the entity class name and field values.
Parameters: - parameters – a map of parameters
Throws: - ActionHandlerException – if the instance of the entity could not get created due to missing class name, lack of constructor, or any other reasons
createOrUpdate¶
-
void
createOrUpdate
(Map<String, Object> parameters)¶ Updates or creates an instance of the entity, based on the provided parameters.
Parameters: - parameters – a map of parameters
Throws: - ActionHandlerException – if the instance could not get updated / created due to missing class name, missing id of the instance, missing instance of the given id, problems setting instance properties, or any other reasons
delete¶
-
void
delete
(Map<String, Object> parameters)¶ Deletes an instance of the entity, based on the provided parameters. The parameters should contain the entity class name and instance id.
Parameters: - parameters – a map of parameters
Throws: - ActionHandlerException – if the instance could not get deleted due to missing class name, missing id of the instance, missing instance of the given id, or any other reasons.
queryAndUpdate¶
-
void
queryAndUpdate
(Map<String, Object> parameters)¶ Query and updates each instance of the entity, based on the provided parameters.
Parameters: - parameters –
Throws: - ActionHandlerException – if the instance could not get updated due to missing class name, missing id of the instance, missing instance of the given id, problems setting instance properties, or any other reasons
update¶
-
void
update
(Map<String, Object> parameters)¶ Updates an instance of the entity, based on the provided parameters. The parameters should contain the entity class name, id of the instance and field values to update.
Parameters: - parameters – a map of parameters
Throws: - ActionHandlerException – if the instance could not get updated due to missing class name, missing id of the instance, missing instance of the given id, problems setting instance properties, or any other reasons
BundleWatcherSuspensionService¶
-
public interface
BundleWatcherSuspensionService
¶ An OSGi service, allowing to temporarily disable bundle processing by MDS. When processing gets suspended, MDS will still listen to bundle events, but instead of processing them, they will be queued and processed after the processing gets restored. This allows, besides others, to install/uninstall a larger amount of bundles at one time, without facing annotation processing problems.
ComboboxValueService¶
-
public interface
ComboboxValueService
¶ This service is responsible for retrieving all possible values for comboboxes. This is useful with comboboxes that take user supplied values, since the total number of selections depends on what the users has entered. Instead of updating the data on each instance save, this service will retrieve the values from the database at read time using a distinct query. This service lives in the entities bundle, since it needs access to entity classes.
Methods¶
getAllValuesForCombobox¶
-
List<String>
getAllValuesForCombobox
(String entityClassName, String fieldName)¶ Retrieves all values for a combobox. For string comboboxes a DISTINCT query on the instances will be performed. For comboboxes that are enums, only their settings will used.
Parameters: - entityClassName – the class name of the entity that contains the combobox field
- fieldName – the name of the combobox field
Returns: all values for the combobox, as a list of strings
getAllValuesForCombobox¶
-
List<String>
getAllValuesForCombobox
(EntityDto entityDto, FieldDto fieldDto)¶ Retrieves all values for a combobox. For string comboboxes a DISTINCT query on the instances will be performed. For comboboxes that are enums, only their settings will used.
Parameters: - entityDto – the entity to which the combobox field belongs to
- fieldDto – the combobox field
Returns: all values for the combobox, as a list of strings
CsvExportCustomizer¶
-
public interface
CsvExportCustomizer
¶ The
CsvExportCustomizer
interface allows to provide custom method to format related instances during csv import.
Methods¶
columnOrderComparator¶
-
Comparator<FieldDto>
columnOrderComparator
(BrowsingSettingsDto browsingSettingsDtos)¶ Allows the customizer to change the ordering of columns in the exporter file. The comparator returned by this method will be used for ordering fields. Note that the comparator might be requested to order fields that were not selected for export - it will be used to order the entire collection of fields from the entity.
Returns: the comparator that will be used for determining the column order
exportDisplayName¶
-
String
exportDisplayName
(FieldDto fieldDto)¶ Retrieves the display name for the given entity field, that will be shown in the top row while exporting instances to CSV/PDF file. By default, the display name of the field is used.
Parameters: - fieldDto – entity field to retrieve display name for
Returns: display name of the given field in the exported files
CsvImportCustomizer¶
-
public interface
CsvImportCustomizer
¶ The
CsvImportCustomizer
interface allows to provide custom methods for finding, creating and updating an instance during csv import.See also:
org.motechproject.mds.domain.Entity
Methods¶
doCreate¶
-
Object
doCreate
(Object instance, MotechDataService dataService)¶ Creates an instance using given dataService
Parameters: - instance – the instance to create
- dataService – the data service of an entity
Returns: the created instance
doUpdate¶
-
Object
doUpdate
(Object instance, MotechDataService dataService)¶ Updates an instance using given dataService
Parameters: - instance – the instance to update
- dataService – the data service of an entity
Returns: the updated instance
findExistingInstance¶
-
Object
findExistingInstance
(Map<String, String> row, MotechDataService dataService)¶ Retrieves an instance based on the fields imported from csv
Parameters: - row – the imported row containing fields of an instance
- dataService – the data service of an entity
Returns: single instance or null if none is found
findField¶
-
FieldDto
findField
(String headerName, List<FieldDto> fieldDtos)¶ Finds entity field, being provided the display name of the column header. The default implementation looks for entity field with matching display name. If such matching cannot be found, it looks for field with matching name. If that also cannot be found, it returns null.
Parameters: - headerName – the column display name from CSV file
- fieldDtos – the list of entity fields
Returns: entity field matching the implemented criteria
CsvImportExportService¶
-
public interface
CsvImportExportService
¶ Service for exporting and importing entity data in CSV format. The format is the same for both import and export. Columns are separated by the ‘,’ character. The top row(header row) consists of names of the fields represented by the columns.
Methods¶
exportCsv¶
exportCsv¶
exportCsv¶
-
long
exportCsv
(long entityId, Writer writer, CsvExportCustomizer exportCustomizer)¶ Exports entity instances to a CSV file.
Parameters: - entityId – id of the entity for which the instances will be exported
- writer – the writer that will be used for output
- exportCustomizer – customizer, that allows to adjust CSV file output
Returns: number of exported instances
exportCsv¶
-
long
exportCsv
(String entityClassName, Writer writer, CsvExportCustomizer exportCustomizer)¶ Exports entity instances to a CSV file.
Parameters: - entityClassName – class name of the entity for which the instances will be exported
- writer – the writer that will be used for output
- exportCustomizer – customizer, that allows to adjust CSV file output
Returns: number of exported instances
exportCsv¶
-
long
exportCsv
(long entityId, Writer writer, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields)¶ Exports entity instances to a CSV file.
Parameters: - entityId – id of the entity for which the instances will be exported
- writer – the writer that will be used for output
- lookupName – the name of lookup
- params – query parameters to be used retrieving instances
- headers – the headers of exported file
- lookupFields – the lookupFields used in the lookup
Returns: number of exported instances
exportCsv¶
-
long
exportCsv
(String entityClassName, Writer writer, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields)¶ Exports entity instances to a CSV file.
Parameters: - entityClassName – class name of the entity for which the instances will be exported
- writer – the writer that will be used for output
- lookupName – the name of lookup
- params – query parameters to be used retrieving instances
- headers – the headers of exported file
- lookupFields – the lookupFields used in the lookup
Returns: number of exported instances
exportCsv¶
-
long
exportCsv
(long entityId, Writer writer, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields, CsvExportCustomizer exportCustomizer)¶ Exports entity instances to a CSV file.
Parameters: - entityId – id of the entity for which the instances will be exported
- writer – the writer that will be used for output
- lookupName – the name of lookup
- params – query parameters to be used retrieving instances
- headers – the headers of exported file
- lookupFields – the lookupFields used in the lookup
- exportCustomizer – customizer, that allows to adjust CSV file output
Returns: number of exported instances
exportCsv¶
-
long
exportCsv
(String entityClassName, Writer writer, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields, CsvExportCustomizer exportCustomizer)¶ Exports entity instances to a CSV file.
Parameters: - entityClassName – class name of the entity for which the instances will be exported
- writer – the writer that will be used for output
- lookupName – the name of lookup
- params – query parameters to be used retrieving instances
- headers – the headers of exported file
- lookupFields – the lookupFields used in the lookup
- exportCustomizer – customizer, that allows to adjust CSV file output
Returns: number of exported instances
exportPdf¶
-
long
exportPdf
(long entityId, OutputStream outputStream)¶ Exports entity instances to a PDF file.
Parameters: - entityId – id of the entity for which the instances will be exported
- outputStream – the stream to write the PDF to
Returns: number of exported instances
exportPdf¶
-
long
exportPdf
(String entityClassName, OutputStream outputStream)¶ Exports entity instances to a PDF file.
Parameters: - entityClassName – class name of the entity for which the instances will be exported
- outputStream – the stream to write the PDF to
Returns: number of exported instances
exportPdf¶
-
long
exportPdf
(long entityId, OutputStream outputStream, CsvExportCustomizer exportCustomizer)¶ Exports entity instances to a PDF file.
Parameters: - entityId – id of the entity for which the instances will be exported
- outputStream – the stream to write the PDF to
- exportCustomizer – customizer, that allows to adjust PDF file output
Returns: number of exported instances
exportPdf¶
-
long
exportPdf
(String entityClassName, OutputStream outputStream, CsvExportCustomizer exportCustomizer)¶ Exports entity instances to a PDF file.
Parameters: - entityClassName – class name of the entity for which the instances will be exported
- outputStream – the writer that will be used for output
- exportCustomizer – customizer, that allows to adjust PDF file output
Returns: number of exported instances
exportPdf¶
-
long
exportPdf
(long entityId, OutputStream outputStream, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields)¶ Exports entity instances to a PDF file.
Parameters: - entityId – id of the entity for which the instances will be exported
- outputStream – the stream to write the PDF to
- lookupName – the name of lookup
- params – query parameters to be used retrieving instances
- headers – the headers of exported file
- lookupFields – the lookupFields used in the lookup
Returns: number of exported instances
exportPdf¶
-
long
exportPdf
(String entityClassName, OutputStream outputStream, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields)¶ Exports entity instances to a PDF file.
Parameters: - entityClassName – class name of the entity for which the instances will be exported
- outputStream – the stream to write the PDF to
- lookupName – the name of lookup
- params – query parameters to be used retrieving instances
- headers – the headers of exported file
- lookupFields – the lookupFields used in the lookup
Returns: number of exported instances
exportPdf¶
-
long
exportPdf
(long entityId, OutputStream outputStream, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields, CsvExportCustomizer exportCustomizer)¶ Exports entity instances to a PDF file.
Parameters: - entityId – id of the entity for which the instances will be exported
- outputStream – the stream to write the PDF to
- lookupName – the name of lookup
- params – query parameters to be used retrieving instances
- headers – the headers of exported file
- lookupFields – the lookupFields used in the lookup
- exportCustomizer – customizer, that allows to adjust PDF file output
Returns: number of exported instances
exportPdf¶
-
long
exportPdf
(String entityClassName, OutputStream outputStream, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields, CsvExportCustomizer exportCustomizer)¶ Exports entity instances to a PDF file.
Parameters: - entityClassName – class name of the entity for which the instances will be exported
- outputStream – the stream to write the PDF to
- lookupName – the name of lookup
- params – query parameters to be used retrieving instances
- headers – the headers of exported file
- lookupFields – the lookupFields used in the lookup
- exportCustomizer – customizer, that allows to adjust PDF file output
Returns: number of exported instances
importCsv¶
-
CsvImportResults
importCsv
(long entityId, Reader reader, String fileName, boolean continueOnError, boolean clearData)¶ Import instances from a CSV file
Parameters: - entityId – id of the entity for which the instances will be imported
- reader – the reader that will be used for reading the file contents
- fileName – the name of the CSV file
- continueOnError – if true, import will continue with next row if exception was encountered, if false, import process will stop and rethrow the exception
- clearData – if true, import will clear instances from table
Returns: IDs of instances updated/added during import
importCsv¶
-
CsvImportResults
importCsv
(long entityId, Reader reader, String fileName, CsvImportCustomizer importCustomizer, boolean continueOnError, boolean clearData)¶ Import instances from a CSV file
Parameters: - entityId – id of the entity for which the instances will be imported
- reader – the reader that will be used for reading the file contents
- fileName – the name of the CSV file
- importCustomizer – the customizer that will be used during import
- continueOnError – if true, import will continue with next row if exception was encountered, if false, import process will stop and rethrow the exception
- clearData – if true, import will clear instances from table
Returns: IDs of instances updated/added during import
importCsv¶
-
CsvImportResults
importCsv
(String entityClassName, Reader reader, String fileName, boolean continueOnError)¶ Import instances from a CSV file
Parameters: - entityClassName – class name of the entity for which the instances will be imported
- reader – the reader that will be used for reading the file contents
- fileName – the name of the CSV file
- continueOnError – if true, import will continue with next row if exception was encountered, if false, import process will stop and rethrow the exception
Returns: IDs of instances updated/added during import
DefaultCsvExportCustomizer¶
-
public class
DefaultCsvExportCustomizer
implements CsvExportCustomizer¶ This is a basic implementation of
org.motechproject.mds.service.CsvExportCustomizer
.
DefaultCsvImportCustomizer¶
-
public class
DefaultCsvImportCustomizer
implements CsvImportCustomizer¶ This is a basic implementation of
org.motechproject.mds.service.CsvImportCustomizer
.
DefaultMotechDataService¶
-
public abstract class
DefaultMotechDataService
<T> implements MotechDataService<T>¶ This is a basic implementation of
org.motechproject.mds.service.MotechDataService
. Mainly it is used as super class to create a service related with the given entity schema inorg.motechproject.mds.builder.EntityInfrastructureBuilder
but it can be also used by other services inside this package.Parameters: - <T> – the type of entity schema.
Methods¶
doInTransaction¶
-
public <R> R
doInTransaction
(TransactionCallback<R> transactionCallback)¶
executeQuery¶
-
public <R> R
executeQuery
(QueryExecution<R> queryExecution)¶
executeSQLQuery¶
-
public <R> R
executeSQLQuery
(SqlQueryExecution<R> queryExecution)¶
filter¶
-
public List<T>
filter
(Filters filters, QueryParams queryParams)¶
findByIds¶
-
public List<T>
findByIds
(Collection<Long> ids)¶
getRepository¶
-
protected MotechDataRepository<T>
getRepository
()¶
retrieveAll¶
-
public List<T>
retrieveAll
(QueryParams queryParams)¶
revertToHistoricalRevision¶
setApplicationContext¶
-
public void
setApplicationContext
(ApplicationContext applicationContext)¶
setEntityInfoReader¶
-
public void
setEntityInfoReader
(EntityInfoReader entityInfoReader)¶
setHistoryService¶
-
public void
setHistoryService
(HistoryService historyService)¶
setOsgiEventProxy¶
-
public void
setOsgiEventProxy
(OsgiEventProxy osgiEventProxy)¶
setRepository¶
-
public void
setRepository
(MotechDataRepository<T> repository)¶
setTransactionManager¶
-
public void
setTransactionManager
(JdoTransactionManager transactionManager)¶
setTrashService¶
-
public void
setTrashService
(TrashService trashService)¶
validateCredentials¶
-
protected InstanceSecurityRestriction
validateCredentials
()¶
validateCredentials¶
-
protected InstanceSecurityRestriction
validateCredentials
(T instance)¶
EntityService¶
-
public interface
EntityService
¶ This interface provides methods related with executing actions on an entity.
See also:
org.motechproject.mds.domain.Entity
Methods¶
abandonChanges¶
addDisplayedFields¶
-
void
addDisplayedFields
(EntityDto entityDto, Map<String, Long> positions)¶ Adds ability to point fields that should be displayed on the data browser by default and allows to set their position on the UI. If not invoked on any field and no field has the
org.motechproject.mds.annotations.UIDisplayable
annotation, all the fields, except auto-generated ones will be displayed. If invoked on at least one field, all other fields will get hidden by default.Parameters: - entityDto – entity representation
- positions – a map of field names and their positions. If position is irrelevant, place -1 as entry value
addFields¶
-
void
addFields
(EntityDto entity, FieldDto... fields)¶ Adds fields to the given entity. If the field of identical name already exists in the entity definition, it will be updated. If the entity does not exist, it throws
org.motechproject.mds.exception.entity.EntityNotFoundException
Parameters: - entity – the entity to add fields to
- fields – fields to add or update
addFields¶
-
void
addFields
(EntityDto entity, Collection<FieldDto> fields)¶ Adds fields to the given entity. If the field of identical name already exists in the entity definition, it will be updated. If the entity does not exist, it throws
org.motechproject.mds.exception.entity.EntityNotFoundException
Parameters: - entity – the entity to add fields to
- fields – fields to add or update
addFields¶
-
void
addFields
(Long entityId, FieldDto... fields)¶ Adds fields to the given entity. If the field of identical name already exists in the entity definition, it will be updated. If the entity does not exist, it throws
org.motechproject.mds.exception.entity.EntityNotFoundException
Parameters: - entityId – id of the entity to add fields to
- fields – fields to add or update
addFields¶
-
void
addFields
(Long entityId, Collection<FieldDto> fields)¶ Adds fields to the given entity. If the field of identical name already exists in the entity definition, it will be updated. If the entity does not exist, it throws
org.motechproject.mds.exception.entity.EntityNotFoundException
Parameters: - entityId – id of the entity to add fields to
- fields – fields to add or update
addFilterableFields¶
-
void
addFilterableFields
(EntityDto entityDto, Collection<String> fieldNames)¶ Provides ability to point fields, for which UI should provide the ability to filter through. Note, that only several field types support filtering via UI. If a field of not supported type is marked as filterable, this will have no effect.
Parameters: - entityDto – entity representation
- fieldNames – the names of the fields, that should be marked filterable
addLookups¶
addLookups¶
-
void
addLookups
(EntityDto entityDto, Collection<LookupDto> lookups)¶ Adds or updates lookups for the given entity.
Parameters: - entityDto – entity representation
- lookups – lookups to add or update
addLookups¶
addLookups¶
-
void
addLookups
(Long entityId, Collection<LookupDto> lookups)¶ Adds or updates lookups for the given entity.
Parameters: - entityId – id of an entity
- lookups – lookups to add or update
addNonEditableFields¶
commitChanges¶
-
List<String>
commitChanges
(Long entityId)¶ Retrieves a draft and attempts to update actual entity, according to the changes present in the draft. The username, for which the draft should be retrieved, will be determined on the current security context. If the draft is outdated, which means that somebody else has already updated the entity, the
org.motechproject.mds.exception.entity.EntityChangedException
will be thrown. If the draft is not outdated, a validation will be performed to determine whether the changes are valid and can be applied, and if so the changes will be made and the draft will get deleted.Parameters: - entityId – id of the draft or actual entity
Returns: a list of modules, affected by the commit
commitChanges¶
-
List<String>
commitChanges
(Long entityId, String changesOwner)¶ Retrieves a draft for a given user and attempts to update actual entity, according to the changes present in the draft. If the draft is outdated, which means that somebody else has already updated the entity, the
org.motechproject.mds.exception.entity.EntityChangedException
will be thrown. If the draft is not outdated, a validation will be performed to determine whether the changes are valid and can be applied, and if so the changes will be made and the draft will get deleted.Parameters: - entityId – id of the draft or actual entity
Returns: a list of modules, affected by the commit
createEntity¶
-
EntityDto
createEntity
(EntityDto entityDto)¶ Creates an entity and adds default fields, provided the entity does not contain them already (from inheritance). It will throw
org.motechproject.mds.exception.entity.EntityAlreadyExistException
if an entity of identical class name already exists.Parameters: - entityDto – representation of an entity to construct from.
Returns: representation of a created entity.
deleteEntity¶
findEntitiesByPackage¶
findEntityFieldByName¶
findFieldByName¶
-
FieldDto
findFieldByName
(Long entityId, String name)¶ Retrieves a field by name. This will be able to find any draft fields, that the current user has added, deleted or modified in any way.
Parameters: - entityId – id of an entity
- name – name of the field
Returns: Actual or draft field of the given name for given entity id
getAdvancedSettings¶
-
AdvancedSettingsDto
getAdvancedSettings
(Long entityId)¶ Retrieves advanced settings for an entity. This will include any draft changes that the current user has made to the entity.
Parameters: - entityId – id of an entity
Returns: advanced settings for the entity
getAdvancedSettings¶
-
AdvancedSettingsDto
getAdvancedSettings
(Long entityId, boolean committed)¶ Retrieves advanced settings for an entity.
Parameters: - entityId – id of an entity
- committed – a flag indicating whether the settings should come from actual entity or a draft
Returns: advanced settings for the entity
getCurrentSchemaVersion¶
-
Long
getCurrentSchemaVersion
(String entityClassName)¶ Retrieves current version of the entity schema. The version gets incremented each time the entity gets updated. It throws
org.motechproject.mds.exception.entity.EntityNotFoundException
if entity of given class name does not exist.Parameters: - entityClassName – fully qualified class name of the entity
Returns: schema version for the entity
getDisplayFields¶
-
List<FieldDto>
getDisplayFields
(Long entityId)¶ Retrieves all fields of an entity, that are marked as displayable. By default, these are all the fields that aren’t auto-generated by the MDS. The displayable fields can be adjusted using annotations or
addDisplayedFields(org.motechproject.mds.dto.EntityDto,java.util.Map)
method. If entity of given id does not exist, it throwsorg.motechproject.mds.exception.entity.EntityNotFoundException
.Parameters: - entityId – id of an entity
Returns: All fields of the entity, that are marked as displayable
getEntity¶
getEntityByClassName¶
getEntityDraft¶
-
EntityDraft
getEntityDraft
(Long entityId)¶ Retrieves the entity draft. The user, for which the draft should be obtained, will be determined on the current security context.
Parameters: - entityId – id of the draft or actual entity
Returns: Entity draft for the user
getEntityDraft¶
-
EntityDraft
getEntityDraft
(Long entityId, String username)¶ Retrieves the entity draft for the given user.
Parameters: - entityId – id of the draft or actual entity
Returns: Entity draft for the user
getEntityFieldById¶
getEntityFields¶
getEntityFieldsByClassName¶
getEntityFieldsByClassNameForUI¶
-
List<FieldDto>
getEntityFieldsByClassNameForUI
(String className)¶ Retrieves a list of all fields for the given entity class name. This will not include any draft fields. Since this for the UI, additional display options such as all combobox values will be added to the resultant fields.
Parameters: - className – the entity class name
Returns: a list of fields for the entity
getEntityFieldsForUI¶
getEntityForEdit¶
getEntityLookups¶
getFields¶
getLookupByName¶
-
LookupDto
getLookupByName
(Long entityId, String lookupName)¶ Retrieves lookup representation by entity id and lookup name. If entity of given id does not exists, it throws
org.motechproject.mds.exception.entity.EntityNotFoundException
. If there is no lookup of such name in the entity, it returnsnull
.Parameters: - entityId – id of an entity
- lookupName – name of a lookup to retrieve
Returns: Lookup representation, or null if a lookup of given name does not exist
getLookupFieldsMapping¶
-
Map<String, FieldDto>
getLookupFieldsMapping
(Long entityId, String lookupName)¶ Returns a map which contains lookup fields. Fields may come from related entities. Map keys represents lookup fields name which can contains a dot operator(for example relationshipField.id).
Parameters: - entityId – The id of an entity
- lookupName – name of a lookup
Returns: a map of lookup fields.
getSchema¶
-
SchemaHolder
getSchema
()¶ Retrieves the current MDS schema - entities, fields, lookups, advanced settings etc. This schema can be processed outside of a transacton.
Returns: the current MDS schema
incrementVersion¶
-
void
incrementVersion
(Long entityId)¶ Increments the version of the entity.
Parameters: - entityId – id of an entity
Throws: - org.motechproject.mds.exception.entity.EntityNotFoundException – when entity of the given id does not exist
listEntities¶
listEntities¶
-
List<EntityDto>
listEntities
(boolean withSecurityCheck)¶ Returns all entities, that are currently stored in the database. Allows to filter out entities, that the current user does not have access to. This will not return Entity drafts and Entity audit.
Parameters: - withSecurityCheck – set to true, if you wish to filter out entities, that current user does not have access to
Returns: A list of all entities, that currently logged user has got access to.
listEntitiesByBundle¶
-
List<EntityDto>
listEntitiesByBundle
(String bundleSymbolicName)¶ Returns all entities of the bundle with the given name. This will not return Entity drafts and Entity audit. It will also not perform any security checks on the entities.
Parameters: - bundleSymbolicName – the symbolic name of the bundle
Returns: A list of the bundle entities.
listWorkInProgress¶
safeGetAdvancedSettingsCommitted¶
-
AdvancedSettingsDto
safeGetAdvancedSettingsCommitted
(String entityClassName)¶ Returns the advanced settings for the entity with the given class name. This method is safe, meaning that it will return null for non-existent entities.
Parameters: - entityClassName – the class name of the entity
Returns: the advanced settings of the entity, or null if the entity does not exist
saveDraftEntityChanges¶
-
DraftResult
saveDraftEntityChanges
(Long entityId, DraftData draftData, String username)¶ Creates, updates or removes draft data for the user. If there’s no draft for given user, it will be created. If a draft already exists, the existing draft will get updated.
Parameters: - entityId – id of an actual entity
- draftData – data representing changes to the entity
- username – the username to whom draft will be assigned
Returns: The result, indicating whether changes have been made and whether a draft is outdated
saveDraftEntityChanges¶
-
DraftResult
saveDraftEntityChanges
(Long entityId, DraftData draftData)¶ Creates, updates or removes draft data. The username will be retrieved from the existing security context. If there’s no draft for given user, it will be created. If a draft already exists, the existing draft will get updated.
Parameters: - entityId – id of an actual entity
- draftData – data representing changes to the entity
Returns: The result, indicating whether changes have been made and whether a draft is outdated
updateDraft¶
-
EntityDto
updateDraft
(Long entityId)¶ Updates draft entity for the user, determined on the current security context. The update changes the parent entity of the draft to the latest version, which may happen if another user commits changes to the entity.
Parameters: - entityId – id of an entity
Returns: updated draft entity
updateMaxFetchDepth¶
-
void
updateMaxFetchDepth
(Long entityId, Integer maxFetchDepth)¶ Updated the max fetch depth for a given entity. That fetch depth will be passed to the fetch plan of the persistence manager for that entity.
Parameters: - entityId – the id of the entity to update
- maxFetchDepth – the new maximum fetch depth
updateRestOptions¶
-
void
updateRestOptions
(Long entityId, RestOptionsDto restOptionsDto)¶ Updates rest options for the given entity. If entity of the given id does not exist, it throws
org.motechproject.mds.exception.entity.EntityNotFoundException
Parameters: - entityId – id of an entity
- restOptionsDto – new rest options
updateSecurityOptions¶
-
void
updateSecurityOptions
(Long entityId, SecurityMode securityMode, Set<String> securityMembers, SecurityMode readOnlySecurityMode, Set<String> readOnlySecurityMembers)¶ Updates security options for the given entity. If entity of the given id does not exist, it throws
org.motechproject.mds.exception.entity.EntityNotFoundException
Parameters: - entityId – id of an entity
- securityMode – new security mode
- securityMembers – set of user or role names
- readOnlySecurityMode – new read only security mode
- readOnlySecurityMembers – set of user or role names for read only security mode
updateTracking¶
-
void
updateTracking
(Long entityId, TrackingDto trackingDto)¶ Updates audit settings for the given entity. If entity of the given id does not exist, it throws
org.motechproject.mds.exception.entity.EntityNotFoundException
Parameters: - entityId – id of an entity
- trackingDto – new audit settings
HistoryService¶
-
public interface
HistoryService
¶ The
HistoryService
provides methods related with processing historical changes on the given instance of entity.
Methods¶
countHistoryRecords¶
getHistoryForInstance¶
-
List
getHistoryForInstance
(Object instance, QueryParams queryParams)¶ Returns the historical data for the given instance. This method return historical data only for objects that are not in the MDS trash. For trash instances the return value will be incorrect.
Parameters: - instance – an instance created from the given entity definition.
- queryParams – Query parameters such as page number, size of page and sort direction. If null method will return all history records.
Returns: a list of historical data related with the given instance.
getSingleHistoryInstance¶
record¶
-
void
record
(Object instance)¶ Records changes made on the given instance of entity. The first historical data should be equal to data inside the given instance. Two instance of historical data should be connected using appropriate fields (defined in history class definition). This method should be used only for instances that are not in the MDS trash.
Parameters: - instance – an instance created from the given entity definition.
HistoryTrashClassHelper¶
-
public final class
HistoryTrashClassHelper
¶ Contains utility methods for dealing with history and trash clasess
Methods¶
getClass¶
-
public static Class<?>
getClass
(Object src, EntityType type, BundleContext bundleContext)¶
getClass¶
-
public static Class<?>
getClass
(String srcClassName, EntityType type, BundleContext bundleContext)¶
ImportExportService¶
-
public interface
ImportExportService
¶ The
ImportExportService
interface provides methods for importing and exporting entities schema and data in json format.See also:
org.motechproject.mds.domain.ImportExportBlueprint
Methods¶
exportEntities¶
-
void
exportEntities
(ImportExportBlueprint blueprint, Writer writer)¶ Exports entities schema and/or instances based on provided blueprint.
Parameters: - blueprint – export blueprint containing information which entities to export and what to include
- writer – the writer used for output
importEntities¶
-
void
importEntities
(String importId, ImportExportBlueprint blueprint)¶ Imports entities schema and/or instances from previously stored import file.
Parameters: - importId – previously saved import file id
- blueprint – import blueprint containing information which entities to import and what to include
saveImportFileAndExtractManifest¶
-
ImportManifest
saveImportFileAndExtractManifest
(byte[] bytes)¶ Saves uploaded import file to temporary location, validates it and extracts
org.motechproject.mds.domain.ImportManifest
from it.Parameters: - bytes – binary file representation
Returns: import manifest extracted from saved file
JarGeneratorService¶
-
public interface
JarGeneratorService
¶ This interface provides methods to create a bundle jar with all entities defined in MDS module.
Fields¶
Methods¶
generate¶
-
File
generate
(SchemaHolder schemaHolder)¶ Generates a jar file that contains entity class definitions, repositories, interfaces, implementations of these interfaces. The jar should also contains class related with historical data and trash.
Parameters: - schemaHolder – the holder of the MDS that should be built
Throws: - IOException – if an I/O error occurs while creating the jar file.
Returns: file that points to the entities bundle jar.
regenerateMdsDataBundle¶
-
void
regenerateMdsDataBundle
(SchemaHolder schemaHolder)¶ Constructs entities, builds and starts the entities bundle jar
Parameters: - schemaHolder – the holder of the MDS that should be built
See also:
.generate(SchemaHolder)
regenerateMdsDataBundle¶
-
void
regenerateMdsDataBundle
(SchemaHolder schemaHolder, boolean startBundle)¶ Constructs entities, builds the entities bundle jar. The generated bundle will start only if the startBundle will be set to
true
.Parameters: - schemaHolder – the holder of the MDS that should be built
- startBundle –
true
if the generated bundle should start; otherwisefalse
.
See also:
.generate(SchemaHolder)
regenerateMdsDataBundleAfterDdeEnhancement¶
-
void
regenerateMdsDataBundleAfterDdeEnhancement
(SchemaHolder schemaHolder, String... moduleNames)¶ Constructs entities, builds and starts the entities bundle jar. This method should be used after DDE enhancement. It will build all DDE classes and refresh modules from which the DDE being enhanced comes from.
Parameters: - schemaHolder – the holder of the MDS that should be built
- moduleNames – modules names of the entities from which the enhanced DDE comes from
See also:
.generate(SchemaHolder)
JdoListenerRegistryService¶
-
public interface
JdoListenerRegistryService
¶ Gives access to the registry of listeners for persistence events.
Methods¶
getEntitiesListenerStr¶
getListeners¶
-
List<MotechLifecycleListener>
getListeners
()¶ Gets the listeners from the registry.
Returns: the list of listeners
getListeners¶
-
List<MotechLifecycleListener>
getListeners
(String entity, InstanceLifecycleListenerType type)¶ Gets the list of listeners for the given entity and type of persistence event.
Parameters: - entity – the class name of persistence object
- type – the type of persistence event
Returns: the list of listeners
getMethods¶
-
Set<String>
getMethods
(MotechLifecycleListener listener, InstanceLifecycleListenerType type)¶ Gets the list of methods from the listener for the given type of persistence event.
Parameters: - listener – the listener for persistence object
- type – the type of persistence event
Returns: the list of methods
registerEntityWithListeners¶
registerListener¶
-
void
registerListener
(MotechLifecycleListener listener)¶ Registers the listener. If the registry already has listener for this type of persistence event, the methods from the given listener will be added to the existed one.
Parameters: - listener – the listener to be registered
removeInactiveListeners¶
removeListener¶
-
void
removeListener
(MotechLifecycleListener listener)¶ Removes the listener from the registry.
Parameters: - listener – the listener to be removed
JsonLookupService¶
-
public interface
JsonLookupService
¶ Service for managing lookups coming from JSON files.
Methods¶
createJsonLookup¶
-
void
createJsonLookup
(JsonLookupDto jsonLookup)¶ Stores the given
jsonLookup
in the database.Parameters: - jsonLookup – the lookup to be stored.
exists¶
-
boolean
exists
(String entityClassName, String originLookupName)¶ Checks if a lookup with the given
originLookupName
was already added for the entity with the givenentityClassName
.Parameters: - entityClassName – the class name of the entity
- originLookupName – the origin name of the lookup
Returns: true if the lookup was added, false otherwise
MDSLookupService¶
-
public interface
MDSLookupService
¶ This service allows executing lookups on entities given their classes or class names and lookup names as Strings. Allows generic access to any entity in MDS. This is just a facade and all data access goes through the underlying data service. EUDE can be identified either by their fully qualified class name (eg: “org.motechproject.mds.entity.Patient”) or by their entity name (eg: “Patient”)
Methods¶
count¶
-
long
count
(Class entityClass, String lookupName, Map<String, ?> lookupParams)¶ Retrieves a total number of instances, that match the specified lookup parameters, for the given lookup and entity. This will fail if specified lookup parameters do not match the lookup definition or if the lookup of given name is not specified for the given entity.
Parameters: - entityClass – entity class
- lookupName – name of the lookup from entity
- lookupParams – parameters to use, when executing the lookup
Returns: number of instances
count¶
-
long
count
(String entityClassName, String lookupName, Map<String, ?> lookupParams)¶ Retrieves a total number of instances, that match the specified lookup parameters, for the given lookup and entity class name. This will fail if specified lookup parameters do not match the lookup definition or if the lookup of given name is not specified for the given entity.
Parameters: - entityClassName – entity class name
- lookupName – name of the lookup from entity
- lookupParams – parameters to use, when executing the lookup
Returns: number of instances
countAll¶
countAll¶
findMany¶
-
<T> List<T>
findMany
(Class<T> entityClass, String lookupName, Map<String, ?> lookupParams)¶ Retrieves and executes multi-return lookup for the given entity class, lookup name and parameters. It will fail, if lookup parameters do not match the parameters specified in the lookup or if the lookup of given name does not exist for the retrieved entity.
Parameters: - entityClass – entity class
- lookupName – name of the lookup from entity
- lookupParams – parameters to use, when executing the lookup
- <T> – entity class
Returns: collection of instances, retrieved using given lookup criteria
findMany¶
-
<T> List<T>
findMany
(String entityClassName, String lookupName, Map<String, ?> lookupParams)¶ Retrieves and executes multi-return lookup for the given entity class name, lookup name and parameters. It will fail, if lookup parameters do not match the parameters specified in the lookup or if the lookup of given name does not exist for the retrieved entity.
Parameters: - entityClassName – entity class name
- lookupName – name of the lookup from entity
- lookupParams – parameters to use, when executing the lookup
- <T> – entity class
Returns: collection of instances, retrieved using given lookup criteria
findMany¶
-
<T> List<T>
findMany
(Class<T> entityClass, String lookupName, Map<String, ?> lookupParams, QueryParams queryParams)¶ Retrieves and executes multi-return lookup for the given entity class, lookup name and parameters. It will fail, if lookup parameters do not match the parameters specified in the lookup or if the lookup of given name does not exist for the retrieved entity. This version additionally allows to use query parameters, to adjust retrieved instances (eg. limit their number).
Parameters: - entityClass – entity class
- lookupName – name of the lookup from entity
- lookupParams – parameters to use, when executing the lookup
- queryParams – parameters to use, retrieving the instances
- <T> – entity class
Returns: collection of instances, retrieved using given lookup criteria
findMany¶
-
<T> List<T>
findMany
(String entityClassName, String lookupName, Map<String, ?> lookupParams, QueryParams queryParams)¶ Retrieves and executes multi-return lookup for the given entity class name, lookup name and parameters. It will fail, if lookup parameters do not match the parameters specified in the lookup or if the lookup of given name does not exist for the retrieved entity. This version additionally allows to use query parameters, to adjust retrieved instances (eg. limit their number).
Parameters: - entityClassName – entity class name
- lookupName – name of the lookup from entity
- lookupParams – parameters to use, when executing the lookup
- queryParams – parameters to use, retrieving the instances
- <T> – entity class
Returns: collection of instances, retrieved using given lookup criteria
findOne¶
-
<T> T
findOne
(Class<T> entityClass, String lookupName, Map<String, ?> lookupParams)¶ Retrieves and executes single-return lookup for the given entity class, lookup name and parameters. It will fail, if lookup parameters do not match the parameters specified in the lookup or if the lookup of given name does not exist for the retrieved entity. It will also throw
org.motechproject.mds.exception.lookup.SingleResultFromLookupExpectedException
in case lookup returns a collection of instances, rather than single instance.Parameters: - entityClass – entity class
- lookupName – name of the lookup from entity
- lookupParams – parameters to use, when executing the lookup
- <T> – entity class
Returns: Single instance, retrieved using given lookup criteria
findOne¶
-
<T> T
findOne
(String entityClassName, String lookupName, Map<String, ?> lookupParams)¶ Retrieves and executes single-return lookup for the given entity class name, lookup name and parameters. It will fail, if lookup parameters do not match the parameters specified in the lookup or if the lookup of given name does not exist for the retrieved entity. It will also throw
org.motechproject.mds.exception.lookup.SingleResultFromLookupExpectedException
in case lookup returns a collection of instances, rather than single instance.Parameters: - entityClassName – entity class name
- lookupName – name of the lookup from entity
- lookupParams – parameters to use, when executing the lookup
- <T> – entity class
Returns: Single instance, retrieved using given lookup criteria
retrieveAll¶
retrieveAll¶
retrieveAll¶
-
<T> List<T>
retrieveAll
(Class<T> entityClass, QueryParams queryParams)¶ Retrieves all instances for the given entity class name. This version additionally allows to use query parameters, to adjust retrieved instances (eg. limit their number).
Parameters: - entityClass – entity class
- <T> – entity class
Returns: a list of all instances for the given entity
retrieveAll¶
-
<T> List<T>
retrieveAll
(String entityClassName, QueryParams queryParams)¶ Retrieves all instances for the given entity class name. This version additionally allows to use query parameters, to adjust retrieved instances (eg. limit their number).
Parameters: - entityClassName – entity class name
- <T> – entity class
Returns: a list of all instances for the given entity
MdsBundleRegenerationService¶
-
public interface
MdsBundleRegenerationService
¶ The
MdsBundleRegenerationService
interface provides methods for regenerating MDS Entities Bundle and commands all Motech instances to do the same.
Fields¶
Methods¶
regenerateMdsDataBundle¶
-
void
regenerateMdsDataBundle
()¶ Constructs entities, builds and starts the MDS Entities Bundle, commands other Motech instances to regenerate their MDS Entities Bundle.
regenerateMdsDataBundleAfterDdeEnhancement¶
-
void
regenerateMdsDataBundleAfterDdeEnhancement
(String... moduleNames)¶ Constructs entities, builds and starts the MDS Entities Bundle, commands other Motech instances to regenerate their MDS Entities Bundle. This method should be used after DDE enhancement. It will build all DDE classes and refresh modules from which the DDE being enhanced comes from.
Parameters: - moduleNames – modules names of the entities from which the enhanced DDE comes from
MdsOsgiBundleApplicationContextListener¶
-
public class
MdsOsgiBundleApplicationContextListener
implements OsgiBundleApplicationContextListener¶ The
MdsOsgiBundleApplicationContextListener
acts as an listener for Blueprint events to get notified about modules being started or failing. When the module failing then it will be automatically restarted.
Fields¶
Methods¶
onOsgiApplicationEvent¶
-
public void
onOsgiApplicationEvent
(OsgiBundleApplicationContextEvent event)¶
setAllBundleFailureReports¶
-
public void
setAllBundleFailureReports
(AllBundleFailureReports allBundleFailureReports)¶
setOsgiEventProxy¶
-
public void
setOsgiEventProxy
(OsgiEventProxy osgiEventProxy)¶
setSettingsService¶
-
public void
setSettingsService
(SettingsService settingsService)¶
setTransactionManager¶
-
public void
setTransactionManager
(JdoTransactionManager transactionManager)¶
MdsSchedulerService¶
-
public interface
MdsSchedulerService
¶ The
MdsSchedulerService
provides methods for scheduling and unscheduling jobs. We do not use the MOTECH scheduler, to avoid circular dependencies. This service only allows to schedule MDS-specific jobs.
Methods¶
scheduleRepeatingJob¶
-
void
scheduleRepeatingJob
(long interval)¶ Schedules a job, responsible for periodic emptying of the MDS trash. Throws
java.lang.IllegalArgumentException
if the passed interval is set to 0.Parameters: - interval – interval between next fires, in milliseconds
MetadataService¶
-
public interface
MetadataService
¶ A service that allows access to JDO metadata for MDS. Allows lookups for actual table names. Exposed by the generated MDS entities bundle, since it needs it
javax.jdo.PersistenceManagerFactory
for retrieving accurate metadata.
Methods¶
getComboboxTableName¶
-
String
getComboboxTableName
(String entityClassName, String cbFieldName)¶ Returns the datastore table for the given combobox field in an entity.
Parameters: - entityClassName – the class name of the entity
- cbFieldName – the name of the combobox field
Throws: - IllegalArgumentException – if there is no table name available in the metadta for this field
Returns: the table name for the combobox
MigrationService¶
-
public interface
MigrationService
¶ This interface provides method for finding flyway migrations within bundle. Default search location is db/migration.
See also:
org.motechproject.mds.jdo.SchemaGenerator
,org.motechproject.mds.domain.MigrationMapping
MotechDataService¶
-
public interface
MotechDataService
<T>¶ This is a basic service interface with CRUD operations. Mainly it is used as super interface to create service interface related with the given entity schema in
org.motechproject.mds.builder.EntityInfrastructureBuilder
but it can be also used by other service interfaces inside this package.Parameters: - <T> – the type of entity schema.
Methods¶
countForFilters¶
create¶
-
T
create
(T object)¶ Creates the given instance in MDS.
Parameters: - object – instance to create
Returns: created instance
createOrUpdate¶
-
T
createOrUpdate
(T object)¶ Updates the given instance in MDS if it exists (checks the presence of the instances id to verify that) or creates a new one if it doesn’t.
Parameters: - object – instance to update or create
Returns: updated or created instance
delete¶
-
void
delete
(T object)¶ Deletes given instance from MDS.
Parameters: - object – instance to delete
delete¶
deleteById¶
-
void
deleteById
(long id)¶ Deletes instance from MDS, by its id.
Parameters: - id – id of the instance to delete.
detachedCopy¶
-
T
detachedCopy
(T object)¶ Returns detached copy of the given object
Parameters: - object – the object to be detached
Returns: the detached copy of the given object
detachedCopyAll¶
doInTransaction¶
-
<R> R
doInTransaction
(TransactionCallback<R> transactionCallback)¶ Allows to wrap several instructions into a single transaction. Developers should implement the
TransactionCallback
interface and override theTransactionCallback.doInTransaction(org.springframework.transaction.TransactionStatus)
method with whatever should be done in the transaction.Parameters: - transactionCallback – implementation of the
TransactionCallback
- <R> – type that should be returned from the transaction
Returns: anything of type {@param }. Left to the developer, implementing the transaction
- transactionCallback – implementation of the
evictCacheForInstance¶
-
void
evictCacheForInstance
(T instance)¶ Evicts cache for a single entity instance.
Parameters: - instance – the instance to clear the cache for
evictEntityCache¶
-
void
evictEntityCache
(boolean withSubclasses)¶ Evicts cache for the entity class of this data service.
Parameters: - withSubclasses – if true, the cache for subclasses of the entity will be also cleared
executeQuery¶
-
<R> R
executeQuery
(QueryExecution<R> queryExecution)¶ Allows to execute custom query in MDS. Users are supposed to implement the
QueryExecution
interface and override itsQueryExecution.execute(javax.jdo.Query,org.motechproject.mds.util.InstanceSecurityRestriction)
method with their custom behaviour.Parameters: - queryExecution – implementation of the
QueryExecution
, with custom behaviour - <R> – type that should be returned from the custom query
Returns: anything of type {@param }. Left to the developer, implementing the custom query.
- queryExecution – implementation of the
executeSQLQuery¶
-
<R> R
executeSQLQuery
(SqlQueryExecution<R> queryExecution)¶ Allows to execute custom SQL query in MDS. Users should implement the
SqlQueryExecution
interface and override its methods, defining their custom query.Parameters: - queryExecution – implementation of the
SqlQueryExecution
- <R> – type that should be returned by the custom sql query
Returns: anything of type {@param }, left to the developer, implementing the custom sql query.
- queryExecution – implementation of the
filter¶
-
List<T>
filter
(Filters filters, QueryParams queryParams)¶ Retrieves all instances of type {@param } from MDS, filtered using specified filters and query params.
Parameters: - filters – filters to use filtering instances
- queryParams – query parameters to use filtering instances
Returns: a list of instances, filtered using specified parameters
findById¶
findByIds¶
-
List<T>
findByIds
(Collection<Long> ids)¶ Retrieves multiple instances of type {@param } and given ids from MDS. It will not fail if it is unable to find an instance for one or more IDs and will return a collection of these instances that could be found. If null is passed as keys, it will return an empty list.
Parameters: - ids – a collection of ids to find
Returns: a collection of instances with the given ids
findTrashInstanceById¶
getClassType¶
getDetachedField¶
getSchemaVersion¶
getVersionFieldName¶
recordHistory¶
-
boolean
recordHistory
()¶ Checks whether the entity for this service has history recording enabled.
Returns: true if the entity has history recording enabled, false otherwise
retrieve¶
retrieveAll¶
retrieveAll¶
-
List<T>
retrieveAll
(QueryParams queryParams)¶ Retrieves all instances of the {@param } type, that match the provided parameters.
Parameters: - queryParams – query parameters to be used retrieving instances
Returns: all isntances matching query parameters
revertFromTrash¶
-
T
revertFromTrash
(Long trashId)¶ Brings an instance back from trash.
Parameters: - trashId – the id of the trash instance
Throws: - TrashInstanceNotFoundException – if the trash instance with the given id was not found
Returns: the brought back instance
revertToHistoricalRevision¶
-
T
revertToHistoricalRevision
(Long instanceId, Long historicalId)¶ Reverts data from a historical revision of the given instance.
Parameters: - instanceId – the id of the instance which will be reverted
- historicalId – the id of the historical revision that we are reverting to
Throws: - org.motechproject.mds.exception.object.ObjectNotFoundException – if entity with instanceId was not found
- HistoryInstanceNotFoundException – if the historical instance with historicalId was not found
Returns: the reverted instance
update¶
-
T
update
(T object)¶ Updates the given instance in MDS.
Parameters: - object – instance to update
Returns: updated instance
updateFromTransient¶
-
T
updateFromTransient
(T transientObject)¶ Returns the persistent instance, updated with the values from the transient instance. If there’s no instance of the id from the transient instance, it will create one.
Parameters: - transientObject – transient object, from which an update will take place
Returns: persistent instance, updated with the values from the transient instance
updateFromTransient¶
-
T
updateFromTransient
(T transientObject, Set<String> fieldsToUpdate)¶ Returns the persistent instance, updated with the values from the transient instance. If there’s no instance of the id from the transient instance, it will create one. Only fields with the names passed to the method will be updated.
Parameters: - transientObject – transient object, from which an update will take place
- fieldsToUpdate – set of field names that should be updated
Returns: persistent instance, updated with the values from the transient instance
RestDocumentationService¶
-
public interface
RestDocumentationService
¶ This service allows retrieval of dynamically generated MDS REST documentation. This is an OSGi service interface, it is used by the mds-web module to serve the documentation through HTTP. The documentation returned is a JSON representation of the API in Swagger json format.
Methods¶
retrieveDocumentation¶
-
void
retrieveDocumentation
(Writer writer, String serverPrefix, Locale locale)¶ Writes REST API documentation the documentation to the writer provided.
Parameters: - writer – the output for the documentation.
- serverPrefix – the prefix of the server, for example /motech-platform-server, will be used in the swagger spec
- locale – the locale to be used while generating REST documentation
RevertConverter¶
-
public class
RevertConverter
implements PropertyUtil.ValueConverter¶ An implementation of
org.motechproject.mds.util.PropertyUtil.ValueConverter
.
Constructors¶
RevertConverter¶
-
public
RevertConverter
(EntityInfo entityInfo, ApplicationContext applicationContext)¶
ServiceUtil¶
-
public final class
ServiceUtil
¶ The
ServiceUtil
class provides utility methods to work with services
Methods¶
getServiceForInterfaceName¶
-
public static <S> S
getServiceForInterfaceName
(BundleContext bundleContext, String interfaceName)¶
getServiceFromAppContext¶
-
public static <S> MotechDataService<S>
getServiceFromAppContext
(ApplicationContext applicationContext, Class<S> entityClass)¶
getServiceFromAppContext¶
-
public static <S> MotechDataService<S>
getServiceFromAppContext
(ApplicationContext applicationContext, String entityClassName)¶
TableWriter¶
-
public interface
TableWriter
extends AutoCloseable¶ An interface for writing tabular data. A writer should be created for each supported format such as PDF or CSV.
Methods¶
writeHeader¶
writeRow¶
-
void
writeRow
(Map<String, String> row, String[] headers)¶ Writes a row of data to the table.
Parameters: - row – the row data, keys are field names and values are their values in string form that should be directly written to the output
- headers – the array of headers for the table
Throws: - IOException –
TransactionalMotechDataService¶
-
public abstract class
TransactionalMotechDataService
<T> extends DefaultMotechDataService<T>¶ The main goal of the
TransactionalMotechDataService
class is to resolve problems with transaction annotations not working for generated lookups. We use the traditional transaction callback instead.Parameters: - <T> – the type of entity schema.
TrashService¶
-
public interface
TrashService
¶ The
TrashService
provides methods related with the module trash mode (by default the mode is active and it can be turned off by the user).
Methods¶
countTrashRecords¶
-
long
countTrashRecords
(String className)¶ Gets a number of instances moved to trash, for entity with given class name. This will only consider the instances, that have been moved to trash on the current entity schema version.
Parameters: - className – fully qualified entity class name
Returns: trash instances count
emptyTrash¶
-
void
emptyTrash
(Collection<String> entitiesClassNames)¶ Cleans the module trash. All instances in trash should be removed permanently and if they contain any historical data they should also be removed permanently.
This method should only be executed by the job created in the
scheduleEmptyTrashJob()
method.Parameters: - entitiesClassNames – the list of class names for which the trash should get cleared
findTrashById¶
getInstancesFromTrash¶
-
Collection
getInstancesFromTrash
(String entityName, QueryParams queryParams)¶ Returns the collection of instances from trash of a certain entity. Returned collection contains only instances that are on the current schema version.
Parameters: - entityName – Instances of what entity should be looked for
- queryParams – Query parameters such as page number, size of page and sort direction. If null method will return all records in trash.
Returns: Collection of instances on the current schema version in trash
isTrashMode¶
-
boolean
isTrashMode
()¶ Checks if trash mode is active. This method should be used before executing the
moveToTrash(Object,Long)
method to resolve whether the given instance should be moved to trash or removed permanently.Returns: true if delete mode is equal to org.motechproject.mds.config.DeleteMode.TRASH
; false otherwise.
moveToTrash¶
-
void
moveToTrash
(Object instance, Long schemaVersion)¶ Moves the given instance to the trash. This method should only be executed, when the module trash mode is active.
Parameters: - instance – an instance created from the given entity definition.
- schemaVersion – the current version of the schema for the entity
See also:
.isTrashMode()
removeFromTrash¶
scheduleEmptyTrashJob¶
-
void
scheduleEmptyTrashJob
()¶ Sets the repeating schedule job that will be executed from time to time. Execution time depends on the value of time value and time unit (defined in
org.motechproject.mds.util.Constants.Config.MODULE_FILE
).Before scheduling new job, the old one should be unscheduled to prevent the errors.
TypeService¶
-
public interface
TypeService
¶ The
TypeService
is an interface defining available methods to execute various actions on Field Types.
Methods¶
findType¶
-
TypeDto
findType
(Class<?> clazz)¶ Retrieves MDS type, based on the class that handles that type in the backend. Throws
org.motechproject.mds.exception.type.NoSuchTypeException
when the given class does not handle any MDS type.Parameters: - clazz – handler class
Returns: MDS type that is handled by the given class
findValidations¶
-
List<TypeValidation>
findValidations
(TypeDto type, Class<? extends Annotation> aClass)¶ Retrieves all MDS validations for the given type, that are triggered by the given annotation.
Parameters: - type – MDS type representation
- aClass – Annotation class type
Returns: A list of validations that match the criteria or empty list, if none were found
getAllTypes¶
getType¶
-
Type
getType
(TypeValidation validation)¶ Retrieves MDS Type, connected to the given validation.
Parameters: - validation – Validation representation
Returns: MDS Type that is connected to this validation
UserPreferencesService¶
-
public interface
UserPreferencesService
¶ The
UserPreferencesService
provides API for managing the entity user preferences (grid size, visible fields).
Methods¶
getEntityPreferences¶
-
List<UserPreferencesDto>
getEntityPreferences
(Long entityId)¶ Returns preferences for entity with the given id.
Parameters: - entityId – the id of the entity for the preferences
Returns: list of user preferences for the entity
getUserPreferences¶
-
UserPreferencesDto
getUserPreferences
(Long entityId, String username)¶ Returns preferences for given user and entity. If preferences don’t exist then default ones will be created.
Parameters: - entityId – the id of the entity for the preferences
- username – the owner of the preferences
Returns: user preferences for the entity and username
removeUserPreferences¶
selectField¶
-
void
selectField
(Long entityId, String username, String fieldName)¶ Adds field with the given name to the user visible fields. If preferences don’t exist then default ones will be created.
Parameters: - entityId – the id of the entity for the preferences
- username – the owner of the preferences
- fieldName – the name of the field to add
selectFields¶
unselectField¶
-
void
unselectField
(Long entityId, String username, String fieldName)¶ Removes field with the given name from the user visible fields. If preferences don’t exist then default ones will be created.
Parameters: - entityId – the id of the entity for the preferences
- username – the owner of the preferences
- fieldName – the name of the field to remove
unselectFields¶
updateGridSize¶
-
void
updateGridSize
(Long entityId, String username, Integer newSize)¶ Updates grid size preferences for given user and entity. If preferences don’t exist then default ones will be created.
Parameters: - entityId – the id of the entity for the preferences
- username – the owner of the preferences
- newSize – the new size og the grid
org.motechproject.mds.service.impl¶
ActionHandlerServiceImpl¶
-
public class
ActionHandlerServiceImpl
implements ActionHandlerService¶ Default implementation of ActionHandlerService interface
See also:
org.motechproject.mds.service.ActionHandlerService
Methods¶
setBundleContext¶
-
public void
setBundleContext
(BundleContext bundleContext)¶
BundleWatcherSuspensionServiceImpl¶
-
public class
BundleWatcherSuspensionServiceImpl
implements BundleWatcherSuspensionService¶
ComboboxValueServiceImpl¶
-
public class
ComboboxValueServiceImpl
implements ComboboxValueService¶ Implementation of the combobox service. Uses
ComboboxValueRepository
for retrieval of combobox user supplied values from the database. For comboboxes that don’t allow user supplied values, no database queries are performed.
EntityServiceImpl¶
-
public class
EntityServiceImpl
implements EntityService¶ Default implementation of
org.motechproject.mds.service.EntityService
interface.
Methods¶
addDisplayedFields¶
addFields¶
-
public void
addFields
(EntityDto entity, Collection<FieldDto> fields)¶
addFields¶
-
public void
addFields
(Long entityId, Collection<FieldDto> fields)¶
addFilterableFields¶
-
public void
addFilterableFields
(EntityDto entityDto, Collection<String> fieldNames)¶
addLookups¶
-
public void
addLookups
(EntityDto entityDto, Collection<LookupDto> lookups)¶
addLookups¶
-
public void
addLookups
(Long entityId, Collection<LookupDto> lookups)¶
addNonEditableFields¶
getAdvancedSettings¶
-
public AdvancedSettingsDto
getAdvancedSettings
(Long entityId)¶
getAdvancedSettings¶
-
public AdvancedSettingsDto
getAdvancedSettings
(Long entityId, boolean committed)¶
getEntityDraft¶
-
public EntityDraft
getEntityDraft
(Long entityId)¶
getEntityDraft¶
-
public EntityDraft
getEntityDraft
(Long entityId, String username)¶
getEntityFieldsByClassNameForUI¶
getLookupFieldsMapping¶
getSchema¶
-
public SchemaHolder
getSchema
()¶
safeGetAdvancedSettingsCommitted¶
-
public AdvancedSettingsDto
safeGetAdvancedSettingsCommitted
(String entityClassName)¶
saveDraftEntityChanges¶
-
public DraftResult
saveDraftEntityChanges
(Long entityId, DraftData draftData, String username)¶
saveDraftEntityChanges¶
-
public DraftResult
saveDraftEntityChanges
(Long entityId, DraftData draftData)¶
setBundleContext¶
-
public void
setBundleContext
(BundleContext bundleContext)¶
setComboboxDataMigrationHelper¶
-
public void
setComboboxDataMigrationHelper
(ComboboxDataMigrationHelper comboboxDataMigrationHelper)¶
setUserPreferencesService¶
-
public void
setUserPreferencesService
(UserPreferencesService userPreferencesService)¶
updateRestOptions¶
-
public void
updateRestOptions
(Long entityId, RestOptionsDto restOptionsDto)¶
updateSecurityOptions¶
-
public void
updateSecurityOptions
(Long entityId, SecurityMode securityMode, Set<String> securityMembers, SecurityMode readOnlySecurityMode, Set<String> readOnlySecurityMembers)¶
updateTracking¶
-
public void
updateTracking
(Long entityId, TrackingDto trackingDto)¶
ImportExportServiceImpl¶
-
public class
ImportExportServiceImpl
implements ImportExportService¶ Implementation of
org.motechproject.mds.service.ImportExportService
.See also:
org.motechproject.mds.domain.ImportExportBlueprint
,org.motechproject.mds.json.EntityWriter
,org.motechproject.mds.json.InstancesWriter
,com.google.gson.stream.JsonWriter
Methods¶
exportEntities¶
-
public void
exportEntities
(ImportExportBlueprint blueprint, Writer writer)¶
importEntities¶
-
public void
importEntities
(String importId, ImportExportBlueprint blueprint)¶
saveImportFileAndExtractManifest¶
-
public ImportManifest
saveImportFileAndExtractManifest
(byte[] bytes)¶
setBundleContext¶
-
public void
setBundleContext
(BundleContext bundleContext)¶
setMdsBundleRegenerationService¶
-
public void
setMdsBundleRegenerationService
(MdsBundleRegenerationService mdsBundleRegenerationService)¶
setRelationshipResolver¶
-
public void
setRelationshipResolver
(RelationshipResolver relationshipResolver)¶
setTransactionManager¶
-
public void
setTransactionManager
(JdoTransactionManager transactionManager)¶
JarGeneratorServiceImpl¶
-
public class
JarGeneratorServiceImpl
implements JarGeneratorService¶ Default implementation of
org.motechproject.mds.service.JarGeneratorService
interface.
Methods¶
generate¶
-
public File
generate
(SchemaHolder schemaHolder)¶
regenerateMdsDataBundle¶
-
public synchronized void
regenerateMdsDataBundle
(SchemaHolder schemaHolder)¶
regenerateMdsDataBundle¶
-
public void
regenerateMdsDataBundle
(SchemaHolder schemaHolder, boolean startBundle)¶
regenerateMdsDataBundleAfterDdeEnhancement¶
-
public void
regenerateMdsDataBundleAfterDdeEnhancement
(SchemaHolder schemaHolder, String... moduleNames)¶
setBundleContext¶
-
public void
setBundleContext
(BundleContext bundleContext)¶
setListenerRegistryService¶
-
public void
setListenerRegistryService
(JdoListenerRegistryService jdoListenerRegistryService)¶
setMdsDataProvider¶
-
public void
setMdsDataProvider
(MDSDataProvider mdsDataProvider)¶
setMdsOsgiBundleApplicationContextListener¶
-
public void
setMdsOsgiBundleApplicationContextListener
(MdsOsgiBundleApplicationContextListener mdsOsgiBundleApplicationContextListener)¶
JsonLookupServiceImpl¶
-
public class
JsonLookupServiceImpl
implements JsonLookupService¶
MdsBundleRegenerationServiceImpl¶
-
public class
MdsBundleRegenerationServiceImpl
implements MdsBundleRegenerationService, EventHandler¶ Default implementation of the
MdsBundleRegenerationService
interface. It uses theorg.motechproject.mds.service.JarGeneratorService
to perform the MDS Entities Bundle regeneration and messages broadcasting for communication with other Motech instances. This class usesOsgiEventProxy
to proxy Motech events though OSGi events, in order to avoid a dependency on the event module.
Methods¶
regenerateMdsDataBundleAfterDdeEnhancement¶
setEntityService¶
-
public void
setEntityService
(EntityService entityService)¶
setJarGeneratorService¶
-
public void
setJarGeneratorService
(JarGeneratorService jarGeneratorService)¶
setOsgiEventProxy¶
-
public void
setOsgiEventProxy
(OsgiEventProxy osgiEventProxy)¶
MdsLookupServiceImpl¶
-
public class
MdsLookupServiceImpl
implements MDSLookupService¶ Implementation of the
org.motechproject.mds.service.MDSLookupService
. This runs in the MDS context(not entities context). All calls are delegated to the respective data service for the entity.
MdsScheduledJob¶
-
public class
MdsScheduledJob
implements Job¶ Job responsible for emptying MDS trash.
MdsSchedulerServiceImpl¶
-
public class
MdsSchedulerServiceImpl
implements MdsSchedulerService¶ Default implementation of the
MdsSchedulerService
.
Fields¶
Constructors¶
MdsSchedulerServiceImpl¶
-
public
MdsSchedulerServiceImpl
(BundleContext bundleContext)¶
MetadataServiceImpl¶
-
public class
MetadataServiceImpl
implements MetadataService¶ Implementation of the
MetadataServiceImpl
. Will use thePersistenceManagerFactory
available for retrieving metadata. This allows retrieving the DataNucleus metadata without making any assumptions.
MigrationServiceImpl¶
-
public class
MigrationServiceImpl
implements MigrationService¶ Default implementation of
org.motechproject.mds.service.MigrationService
interface.
RestDocumentationServiceImpl¶
-
public class
RestDocumentationServiceImpl
implements RestDocumentationService¶ Implementation of
org.motechproject.mds.service.RestDocumentationService
TypeServiceImpl¶
-
public class
TypeServiceImpl
implements TypeService¶ Default implementation of
org.motechproject.mds.service.TypeService
interface
Methods¶
findValidations¶
-
public List<TypeValidation>
findValidations
(TypeDto type, Class<? extends Annotation> aClass)¶
getType¶
-
public Type
getType
(TypeValidation validation)¶
UserPreferencesServiceImpl¶
-
public class
UserPreferencesServiceImpl
implements UserPreferencesService¶ Implementation of the
org.motechproject.mds.service.UserPreferencesService
.
Methods¶
getEntityPreferences¶
-
public List<UserPreferencesDto>
getEntityPreferences
(Long id)¶
getUserPreferences¶
-
public UserPreferencesDto
getUserPreferences
(Long id, String username)¶
setSettingsService¶
-
public void
setSettingsService
(SettingsService settingsService)¶
org.motechproject.mds.service.impl.csv¶
AbstractMdsExporter¶
-
public abstract class
AbstractMdsExporter
¶ Base class used by classes responsible for exporting MDS Data in a tabular CSV-like form. Using the
TableWriter
class, implementing classes can provide their own ouput format.
Methods¶
exportData¶
-
protected long
exportData
(EntityInfo entityInfo, TableWriter writer)¶
exportData¶
-
protected long
exportData
(EntityInfo entityInfo, TableWriter writer, CsvExportCustomizer exportCustomizer)¶
exportData¶
-
protected long
exportData
(EntityInfo entityInfo, TableWriter writer, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields, CsvExportCustomizer exportCustomizer)¶
getBundleContext¶
-
protected BundleContext
getBundleContext
()¶
getEntity¶
-
protected EntityInfo
getEntity
(long entityId)¶
getEntity¶
-
protected EntityInfo
getEntity
(String entityClassName)¶
getEntityInfoReader¶
-
protected EntityInfoReader
getEntityInfoReader
()¶
getMdsLookupService¶
-
protected MDSLookupService
getMdsLookupService
()¶
orderHeaders¶
-
protected String[]
orderHeaders
(BrowsingSettingsDto browsingSettingsDtos, String[] selectedHeaders, List<FieldDto> entityFields, CsvExportCustomizer customizer)¶
CsvImportExportServiceImpl¶
-
public class
CsvImportExportServiceImpl
implements CsvImportExportService¶ Implementation of the
org.motechproject.mds.service.CsvImportExportService
. Uses the SuperCSV library for handling CSV files.CsvImporterExporter
is used for handling import/export logic. This service implementation also fires MOTECH events upon import completion or import failure. This bean lives in the context of the generated MDS entities bundle.See also:
CsvImporterExporter
Methods¶
exportCsv¶
-
public long
exportCsv
(long entityId, Writer writer, CsvExportCustomizer exportCustomizer)¶
exportCsv¶
exportCsv¶
-
public long
exportCsv
(long entityId, Writer writer, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields, CsvExportCustomizer exportCustomizer)¶
exportCsv¶
-
public long
exportCsv
(String entityClassName, Writer writer, CsvExportCustomizer exportCustomizer)¶
exportCsv¶
exportCsv¶
exportPdf¶
-
public long
exportPdf
(long entityId, OutputStream outputStream)¶
exportPdf¶
-
public long
exportPdf
(String entityClassName, OutputStream outputStream)¶
exportPdf¶
-
public long
exportPdf
(long entityId, OutputStream outputStream, CsvExportCustomizer exportCustomizer)¶
exportPdf¶
-
public long
exportPdf
(String entityClassName, OutputStream outputStream, CsvExportCustomizer exportCustomizer)¶
exportPdf¶
-
public long
exportPdf
(long entityId, OutputStream outputStream, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields)¶
exportPdf¶
-
public long
exportPdf
(String entityClassName, OutputStream outputStream, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields)¶
exportPdf¶
-
public long
exportPdf
(long entityId, OutputStream outputStream, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields, CsvExportCustomizer exportCustomizer)¶
exportPdf¶
-
public long
exportPdf
(String entityClassName, OutputStream outputStream, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields, CsvExportCustomizer exportCustomizer)¶
importCsv¶
-
public CsvImportResults
importCsv
(long entityId, Reader reader, String fileName, boolean continueOnError, boolean clearData)¶
importCsv¶
-
public CsvImportResults
importCsv
(long entityId, Reader reader, String fileName, CsvImportCustomizer importCustomizer, boolean continueOnError, boolean clearData)¶
CsvImporterExporter¶
-
public class
CsvImporterExporter
extends AbstractMdsExporter¶ Component used for importing CSV records to the database. The reason for separating import logic is keeping the db transaction and sending the MOTECH event at completion separate. This bean lives in the context of the generated MDS entities bundle.
Methods¶
exportCsv¶
exportCsv¶
exportCsv¶
-
public long
exportCsv
(long entityId, Writer writer, CsvExportCustomizer exportCustomizer)¶ Exports entity instances to a CSV file.
Parameters: - entityId – id of the entity for which the instances will be exported
- writer – the writer that will be used for output
- exportCustomizer – the customizer that will be used during export
Returns: number of exported instances
exportCsv¶
-
public long
exportCsv
(String entityClassName, Writer writer, CsvExportCustomizer exportCustomizer)¶ Exports entity instances to a CSV file.
Parameters: - entityClassName – the class name of the entity for which instances will be exported
- writer – the writer that will be used for output
- exportCustomizer – the customizer that will be used during export
Returns: number of exported instances
exportCsv¶
-
public long
exportCsv
(long entityId, Writer writer, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields)¶ Exports entity instances to a CSV file.
Parameters: - entityId – id of the entity for which the instances will be exported
- writer – the writer that will be used for output
- lookupName – the name of lookup
- params – query parameters to be used retrieving instances
- headers – the headers of exported file
- lookupFields – the lookupFields used in the lookup
Returns: number of exported instances
exportCsv¶
-
public long
exportCsv
(String entityClassName, Writer writer, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields)¶ Exports entity instances to a CSV file.
Parameters: - entityClassName – the class name of the entity for which instances will be exported
- writer – the writer that will be used for output
- lookupName – the name of lookup
- params – query parameters to be used retrieving instances
- headers – the headers of exported file
- lookupFields – the lookupFields used in the lookup
Returns: number of exported instances
exportCsv¶
-
public long
exportCsv
(long entityId, Writer writer, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields, CsvExportCustomizer exportCustomizer)¶ Exports entity instances to a CSV file.
Parameters: - entityId – id of the entity for which the instances will be exported
- writer – the writer that will be used for output
- lookupName – the name of lookup
- params – query parameters to be used retrieving instances
- headers – the headers of exported file
- lookupFields – the lookupFields used in the lookup
- exportCustomizer – the customizer that will be used during export
Returns: number of exported instances
exportCsv¶
-
public long
exportCsv
(String entityClassName, Writer writer, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields, CsvExportCustomizer exportCustomizer)¶ Exports entity instances to a CSV file.
Parameters: - entityClassName – the class name of the entity for which instances will be exported
- writer – the writer that will be used for output
- lookupName – the name of lookup
- params – query parameters to be used retrieving instances
- headers – the headers of exported file
- lookupFields – the lookupFields used in the lookup
- exportCustomizer – the customizer that will be used during export
Returns: number of exported instances
importCsv¶
-
public CsvImportResults
importCsv
(long entityId, Reader reader, boolean continueOnError, boolean clearData)¶ Imports instances of the given entity to the database.
Parameters: - entityId – the ID of the entity for which instances will be imported
- reader – reader from which the csv file will be read
- continueOnError – if true, import will continue with next row if exception was encountered, if false, import process will stop and rethrow the exception
Returns: IDs of instances updated/added during import
importCsv¶
-
public CsvImportResults
importCsv
(long entityId, Reader reader, CsvImportCustomizer importCustomizer, boolean continueOnError, boolean clearData)¶ Imports instances of the given entity to the database.
Parameters: - entityId – the ID of the entity for which instances will be imported
- reader – reader from which the csv file will be read
- importCustomizer – the customizer that will be used during instance import from rows
- continueOnError – if true, import will continue with next row if exception was encountered, if false, import process will stop and rethrow the exception
- clearData – if true, import will clear instances from table
Returns: IDs of instances updated/added during import
importCsv¶
-
public CsvImportResults
importCsv
(String entityClassName, Reader reader, boolean continueOnError)¶ Imports instances of the given entity to the database.
Parameters: - entityClassName – the class name of the entity for which instances will be imported
- reader – reader from which the csv file will be read
- continueOnError – if true, import will continue with next row if exception was encountered, if false, import process will stop and rethrow the exception
Returns: IDs of instances updated/added during import
PdfCsvExporter¶
-
public class
PdfCsvExporter
extends AbstractMdsExporter¶ A class exporting CSV-like tables in PDF format.
Methods¶
exportPdf¶
-
public long
exportPdf
(long entityId, OutputStream outputStream)¶ Exports entity instances to a PDF file.
Parameters: - entityId – id of the entity for which the instances will be exported
- outputStream – the output stream that will be used for writing the file
Returns: number of exported instances
exportPdf¶
-
public long
exportPdf
(String entityClassName, OutputStream outputStream)¶ Exports entity instances to a PDF file.
Parameters: - entityClassName – the class name of the entity for which instances will be exported
- outputStream – the output stream that will be used for writing the file
Returns: number of exported instances
exportPdf¶
-
public long
exportPdf
(long entityId, OutputStream outputStream, CsvExportCustomizer exportCustomizer)¶ Exports entity instances to a PDF file.
Parameters: - entityId – id of the entity for which the instances will be exported
- outputStream – the output stream that will be used for writing the file
- exportCustomizer – the customizer that will be used during export
Returns: number of exported instances
exportPdf¶
-
public long
exportPdf
(String entityClassName, OutputStream outputStream, CsvExportCustomizer exportCustomizer)¶ Exports entity instances to a PDF file.
Parameters: - entityClassName – the class name of the entity for which instances will be exported
- outputStream – the output stream that will be used for writing the file
- exportCustomizer – the customizer that will be used during export
Returns: number of exported instances
exportPdf¶
-
public long
exportPdf
(long entityId, OutputStream outputStream, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields)¶ Exports entity instances to a PDF file.
Parameters: - entityId – id of the entity for which the instances will be exported
- outputStream – the output stream that will be used for writing the file
- lookupName – the name of lookup
- params – query parameters to be used retrieving instances
- headers – the headers of exported file
- lookupFields – the lookupFields used in the lookup
Returns: number of exported instances
exportPdf¶
-
public long
exportPdf
(String entityClassName, OutputStream outputStream, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields)¶ Exports entity instances to a PDF file.
Parameters: - entityClassName – the class name of the entity for which instances will be exported
- outputStream – the output stream that will be used for writing the file
- lookupName – the name of lookup
- params – query parameters to be used retrieving instances
- headers – the headers of exported file
- lookupFields – the lookupFields used in the lookup
Returns: number of exported instances
exportPdf¶
-
public long
exportPdf
(long entityId, OutputStream outputStream, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields, CsvExportCustomizer exportCustomizer)¶ Exports entity instances to a PDF file.
Parameters: - entityId – id of the entity for which the instances will be exported
- outputStream – the output stream that will be used for writing the file
- lookupName – the name of lookup
- params – query parameters to be used retrieving instances
- headers – the headers of exported file
- lookupFields – the lookupFields used in the lookup
- exportCustomizer – the customizer that will be used during export
Returns: number of exported instances
exportPdf¶
-
public long
exportPdf
(String entityClassName, OutputStream outputStream, String lookupName, QueryParams params, List<String> headers, Map<String, Object> lookupFields, CsvExportCustomizer exportCustomizer)¶ Exports entity instances to a PDF file.
Parameters: - entityClassName – the class name of the entity for which instances will be exported
- outputStream – the output stream that will be used for writing the file
- lookupName – the name of lookup
- params – query parameters to be used retrieving instances
- headers – the headers of exported file
- lookupFields – the lookupFields used in the lookup
- exportCustomizer – the customizer that will be used during export
Returns: number of exported instances
org.motechproject.mds.service.impl.history¶
BasePersistenceService¶
-
public abstract class
BasePersistenceService
¶ The
BasePersistenceService
class provides utility methods for communication with the database forHistoryServiceImpl
andTrashServiceImpl
. It allows to create and retrieve instances, load proper classes and parse values.
Methods¶
convertToIdsCollection¶
-
protected Collection<Long>
convertToIdsCollection
(Collection collection)¶
getBundleContext¶
-
protected BundleContext
getBundleContext
()¶
getPersistenceManagerFactory¶
-
protected PersistenceManagerFactory
getPersistenceManagerFactory
()¶
setAppContext¶
-
public void
setAppContext
(ApplicationContext appContext)¶
setBundleContext¶
-
public void
setBundleContext
(BundleContext bundleContext)¶
setPersistenceManagerFactory¶
-
public void
setPersistenceManagerFactory
(PersistenceManagerFactory persistenceManagerFactory)¶
HistoryServiceImpl¶
-
public class
HistoryServiceImpl
extends BasePersistenceService implements HistoryService¶ Default implementation of
org.motechproject.mds.service.HistoryService
interface.
RecordRepository¶
-
class
RecordRepository
¶ This class is responsible for storing records persisted in history during a single TX. The purpose is updating records in case one record gets multiple store events, which may happen in case of relationship trees.
TrashServiceImpl¶
-
public class
TrashServiceImpl
extends BasePersistenceService implements TrashService¶ Default implementation of
org.motechproject.mds.service.TrashService
interface.
Methods¶
emptyTrash¶
-
public void
emptyTrash
(Collection<String> entitiesClassNames)¶
getInstancesFromTrash¶
-
public Collection
getInstancesFromTrash
(String className, QueryParams queryParams)¶
setMdsSchedulerService¶
-
public void
setMdsSchedulerService
(MdsSchedulerService mdsSchedulerService)¶
setSettingsService¶
-
public void
setSettingsService
(SettingsService settingsService)¶
org.motechproject.mds.tasks¶
MDSDataProvider¶
-
public class
MDSDataProvider
extends AbstractDataProvider¶ Class responsible for all actions connected with registering MDS data provider in Task module.
Constructors¶
MDSDataProvider¶
-
public
MDSDataProvider
(ResourceLoader resourceLoader)¶
Methods¶
setBundleContext¶
-
public void
setBundleContext
(BundleContext bundleContext)¶
setEntityService¶
-
public void
setEntityService
(EntityService entityService)¶
setMdsDataProviderBuilder¶
-
public void
setMdsDataProviderBuilder
(MDSDataProviderBuilder mdsDataProviderBuilder)¶
updateDataProvider¶
-
public void
updateDataProvider
(SchemaHolder schemaHolder)¶
org.motechproject.mds.util¶
BlobDeserializer¶
ClassName¶
-
public final class
ClassName
¶ The
ClassName
util provides several methods which should help for example with getting class name or package from string representation of class. There is also methods related with creating names for repository, service interface and implementation of this service interface.
Methods¶
getEntityClassName¶
getEntityTypeSuffix¶
getEnumPackage¶
getHistoryClassName¶
getInterfaceName¶
getPackage¶
getRepositoryName¶
getServiceClassName¶
-
public static String
getServiceClassName
(String className)¶ Retrieves fully qualified class name of the
org.motechproject.mds.service.MotechDataService
service implementation.Parameters: - className – entity class name
Returns: fully qualified MDS service implementation name
getServiceName¶
getSimpleName¶
getTrashClassName¶
isHistoryClassName¶
isTrashClassName¶
restId¶
restLookupUrl¶
-
public static String
restLookupUrl
(String entityName, String entityModule, String entityNamespace, String lookupMethodName)¶ Builds URL endpoint, to access lookups via REST, based on the entity name, module, namespace and lookup method name.
Parameters: - entityName – name of the entity
- entityModule – name of the module
- entityNamespace – namespace
- lookupMethodName – name of the lookup method
Returns: URL endpoint for REST lookup
restUrl¶
-
public static String
restUrl
(String entityName, String entityModule, String entityNamespace)¶ Builds URL endpoint to access REST operations, based on the entity name, module name and namespace.
Parameters: - entityName – name of the entity
- entityModule – name of the module
- entityNamespace – namespace
Returns: URL endpoint for REST
simplifiedModuleName¶
Constants¶
-
public final class
Constants
¶ The
Constants
contains constant values used in MDS module. They are grouped by their role.
Constants.AnnotationFields¶
-
public static final class
AnnotationFields
¶ The
AnnotationFields
contains constant values related with attributes names in mds annotations.See also:
org.motechproject.mds.annotations.Entity
,org.motechproject.mds.annotations.Field
,org.motechproject.mds.annotations.Ignore
,org.motechproject.mds.annotations.Lookup
,org.motechproject.mds.annotations.LookupField
Constants.Config¶
-
public static final class
Config
¶ The
Config
contains constant values related with properties inside files:- datanucleus_data.properties
- datanucleus_schema.properties
- motech-mds.properties
Constants.EntitiesMigration¶
-
public static final class
EntitiesMigration
¶ Constants corresponding to the entities migrations.
Fields¶
Constants.ExportFormat¶
-
public static final class
ExportFormat
¶ Formats for table data exported by MDS.
Constants.FetchDepth¶
-
public static final class
FetchDepth
¶ Constants corresponding to the fetch depths when retrieving entities.
Constants.HistoryTrash¶
-
public static final class
HistoryTrash
¶ Constants related to history and trash classes.
Constants.MDSEvents¶
-
public static final class
MDSEvents
¶ The
MDSEvents
contains constant values related with MDS CRUD events.
Fields¶
Constants.Manifest¶
-
public static final class
Manifest
¶ The
Manifest
contains constant values related with attributes inside the motech-platform-dataservices-entities bundle manifest.See also:
org.motechproject.mds.service.JarGeneratorService
,org.motechproject.mds.service.impl.JarGeneratorServiceImpl
Fields¶
BUNDLE_MANIFESTVERSION¶
BUNDLE_NAME_SUFFIX¶
-
public static final String
BUNDLE_NAME_SUFFIX
¶ Constant
BUNDLE_NAME_SUFFIX
presents suffix of the name of bundle that will be created by implementation oforg.motechproject.mds.service.JarGeneratorService
interface.
MANIFEST_VERSION¶
SYMBOLIC_NAME_SUFFIX¶
-
public static final String
SYMBOLIC_NAME_SUFFIX
¶ Constant
SYMBOLIC_NAME_SUFFIX
presents suffix of the bundle symbolic name of bundle that will be created by implementation oforg.motechproject.mds.service.JarGeneratorService
interface.
Constants.MetadataKeys¶
-
public static final class
MetadataKeys
¶ The keys used in fields metadata
Fields¶
Constants.Operators¶
-
public static final class
Operators
¶ Operators that users can use in lookups.
Fields¶
Constants.Packages¶
-
public static final class
Packages
¶ The
Packages
contains constant values related with packages inside MDS module.
Constants.PackagesGenerated¶
-
public static final class
PackagesGenerated
¶
Constants.Roles¶
-
public static final class
Roles
¶ The
Roles
contains constant values related with security roles.
Constants.Util¶
-
public static final class
Util
¶ The
Util
contains constant values to help avoid string literal repetition.See also: pmd
Fields¶
DEFAULT_DATE_FORMAT¶
-
public static final DateFormat
DEFAULT_DATE_FORMAT
¶ Default
java.text.DateFormat
to be used to parse and formatjava.util.Date
.
ENTITY¶
-
public static final String
ENTITY
¶ Constant
ENTITY
corresponding to the field name of the class that want to create a bidirectional connection with instane oforg.motechproject.mds.domain.Entity
MODIFICATION_DATE_DISPLAY_FIELD_NAME¶
InstanceSecurityRestriction¶
-
public class
InstanceSecurityRestriction
¶ Represents a restriction on entity instances
Methods¶
isByCreator¶
-
public boolean
isByCreator
()¶ Returns: true, if only creators of an instance should be able to access it; false otherwise
isByOwner¶
-
public boolean
isByOwner
()¶ Returns: true, if only owners of an instance should be able to access it; false otherwise
JavassistUtil¶
-
public final class
JavassistUtil
¶ Utils class for javassist related tasks. Helps with generic signature generation, plus methods related with analyzing and loading javassist class representations.
Loader¶
-
public abstract class
Loader
<T>¶ The
Loader
is an abstract class that checks if all class dependencies to the given class definition are resolved. If not then the missing class name is taken from exception and thedoWhenClassNotFound(String)
method is executed.Parameters: - <T> – the type of argument data
LookupName¶
-
public final class
LookupName
¶ Utility class for dealing with lookup names.
Methods¶
buildLookupFieldName¶
-
public static String
buildLookupFieldName
(String fieldName, String relatedFieldName)¶ Builds lookup field name which may contain information about the searching by relationship.
Parameters: - fieldName – The name of the field from entity
- relatedFieldName – The name of the field in related entity
Returns: lookup field name
getFieldName¶
lookupCountMethod¶
MDSClassLoader¶
-
public class
MDSClassLoader
extends ClassLoader¶ The
MDSClassLoader
class is a mds wrapper forClassLoader
.
Constructors¶
MDSClassLoader¶
-
protected
MDSClassLoader
(ClassLoader parent)¶
Methods¶
getInstance¶
-
public static MDSClassLoader
getInstance
()¶
getStandaloneInstance¶
-
public static MDSClassLoader
getStandaloneInstance
()¶
getStandaloneInstance¶
-
public static MDSClassLoader
getStandaloneInstance
(ClassLoader parent)¶
MemberUtil¶
-
public final class
MemberUtil
¶ Util class that provides convenient methods connected with the class members.
Fields¶
Methods¶
getCorrectType¶
-
public static Class<?>
getCorrectType
(AnnotatedElement object)¶ Gets annotated element type. If this element is not a member of the class, it returns null. Otherwise, it will try to resolve the type by checking it directly, or via getter/setter methods. If member is neither a field or getter/setter method, it returns null.
Parameters: - object – annotated element to retrieve type from
Returns: type of the element, or null if not applicable
getCorrectType¶
-
public static Class<?>
getCorrectType
(Member object)¶ Gets member type. It will try to resolve the type by checking it directly, or via getter/setter methods. If member is neither a field or getter/setter method, it returns null.
Parameters: - object – annotated element to retrieve type from
Returns: type of the element, or null if not applicable
getDeclaringClass¶
-
public static Class<?>
getDeclaringClass
(AccessibleObject ac)¶ Retrieves a declaring class for the given object. Returns null if the given object is not a member of a class.
Parameters: - ac – object to verify
Returns: A class, to which this object belongs
getDefaultEnumName¶
getFieldAndAccessorsForElement¶
-
public static List<AccessibleObject>
getFieldAndAccessorsForElement
(AccessibleObject ao)¶ Returns a list of objects, that are either field or getter/setter methods of this field, based on single accessible object of a class. If it fails to find anything, it returns the passed object.
Parameters: - ao – an object to find field, getter/setter method for
Returns: a list of field and getter/setter methods or
ao
if nothing has been found
getFieldName¶
-
public static String
getFieldName
(AnnotatedElement object)¶ Gets field name, from the specified annotated element. It will return null, if annotated element is not a class member. Otherwise, it will try to resolve the field name, by either reading it directly from the member, or by determining the name, based on the getter/setter method. It will return null if member is neither a field or getter/setter.
Parameters: - object – annotated element to retrieve field name from
Returns: field name, if possible; null otherwise
getFieldName¶
-
public static String
getFieldName
(Member object)¶ Gets field name, from the specified member. It will try to resolve the field name, by either reading it directly from the member, or by determining the name, based on the getter/setter method. It will return null if member is neither a field or getter/setter.
Parameters: - object – class member to retrieve field name from
Returns: field name, if possible; null otherwise
getFieldNameFromGetterSetterName¶
-
public static String
getFieldNameFromGetterSetterName
(String getterSetterName)¶ Attempts to retrieve field name from the getter/setter method name. It will throw
java.lang.IllegalArgumentException
if provided value is empty or does not match the setter/getter naming convention.Parameters: - getterSetterName – getter/setter method name
Returns: field name
getGenericType¶
-
public static Class<?>
getGenericType
(AnnotatedElement object)¶ Retrieves an actual type from the parameterized class member. If annotated element is not a class member, it returns null. It always checks for the first parameter. If you want to specify which parameter to retrieve, use
getGenericType(java.lang.reflect.AnnotatedElement,int)
. This will work on fields and getter/setter methods. It will return null for other class members or if there is no parameterized type on them.Parameters: - object – annotated element to retrieve actual type from
Returns: Actual type of the parameterized class member
getGenericType¶
-
public static Class<?>
getGenericType
(AnnotatedElement object, int typeNumber)¶ Retrieves an actual type from the parameterized class member. If annotated element is not a class member, it returns null. It will check the parameter on position
typeNumber
. This will work on fields and getter/setter methods. It will return null for other class members or if there is no parameterized type on them.Parameters: - object – annotated element to retrieve actual type from
- typeNumber – position of the parameterized type
Returns: Actual type of the parameterized class member
getGenericType¶
-
public static Class<?>
getGenericType
(Member object, int typeNumber)¶ Retrieves an actual type from the parameterized class member. It will check the parameter on position
typeNumber
This will work on fields and getter/setter methods. It will return null for other class members or if there is no parameterized type on them.Parameters: - object – class member to retrieve actual type from
- typeNumber – position of the parameterized type
Returns: Actual type of the parameterized class member
getGetterName¶
getMembers¶
getSetterName¶
isGetter¶
NumberPredicate¶
ObjectReferenceRepository¶
-
public class
ObjectReferenceRepository
¶ Represents an object reference repository. It holds historical objects for the real objects with the given id and class name.
Order¶
-
public class
Order
implements Serializable¶ Represents an order in a query
Pair¶
-
public interface
Pair
<N, V>¶ The
Pair
util interface should use everywhere where developer needs a pair of key-valueParameters: - <N> – type of key
- <V> – type of value
See also:
org.motechproject.mds.domain.FieldMetadata
,org.motechproject.mds.domain.FieldSetting
,org.motechproject.mds.dto.MetadataDto
,org.motechproject.mds.dto.SettingDto
PropertyUtil¶
-
public final class
PropertyUtil
extends PropertyUtils¶ The
PropertyUtil
util class provides the same method likeorg.apache.commons.beanutils.PropertyUtils
and two additional methods for safe writing and reading property in the given bean.
PropertyUtil.NoOpConverter¶
-
public static class
NoOpConverter
implements ValueConverter¶
SecurityMode¶
-
public enum
SecurityMode
¶ This enum describes security mode for an entity
Enum Constants¶
CREATOR¶
-
public static final SecurityMode
CREATOR
¶ Only user that created an instance can access it.
EVERYONE¶
-
public static final SecurityMode
EVERYONE
¶ Everyone has got an access to the instances of an entity
NO_ACCESS¶
-
public static final SecurityMode
NO_ACCESS
¶ Nobody can access the instances of an entity
OWNER¶
-
public static final SecurityMode
OWNER
¶ Only user marked as an owner can access the instance of an entity
PERMISSIONS¶
-
public static final SecurityMode
PERMISSIONS
¶ Only users with specified permissions can access the instances of an entity.
USERS¶
-
public static final SecurityMode
USERS
¶ Only specified users can access the instances of an entity.
SecurityUtil¶
-
public final class
SecurityUtil
¶ The
SecurityUtil
class provides helper methods to retrieve logged user details, such as username, roles or permissions
StateManagerUtil¶
-
public final class
StateManagerUtil
¶ This is a helper class, used to invoke operations on instance state manager
Methods¶
setTransactionVersion¶
-
public static void
setTransactionVersion
(Object instance, String versionFieldName)¶ Sets the transaction version to the instance state manager. Version value will be retrieved from the instance.
Parameters: - instance – the instance from which state manager will be retrieved
- versionFieldName – the name of the version field
setTransactionVersion¶
-
public static void
setTransactionVersion
(Object instance, Object version, String versionFieldName)¶ Sets the given transaction version to the instance state manager.
Parameters: - instance – the instance from which state manager will be retrieved
- version – the transaction version
- versionFieldName – the name of the version field
TypeHelper¶
-
public final class
TypeHelper
¶ A helper class for parsing and formatting MDS supported types.
Methods¶
asCollection¶
-
public static <T> Collection<T>
asCollection
(Object value)¶ Returns the provided value as a collection. If the value is a collection, it is simply returned. If the value is a non-collection and non null object, it is returned as an arrayList containing one object. IF the object is null, then an empty arraylist is returned.
Parameters: - value – the value to parse
- <T> – the type of the collection
Returns: the value as a collection
breakString¶
format¶
-
public static String
format
(Object obj)¶ Creates a
java.lang.String
representation of the given value. If given object is ajava.util.List
, each new element is placed in a new line.Parameters: - obj – value to retrieve
java.lang.String
representation for
Returns: java.lang.String
representation of an object- obj – value to retrieve
format¶
-
public static String
format
(Object obj, char collJoinChar)¶ Creates a
java.lang.String
representation of the given value. If given object is ajava.util.List
a character put between next values can be specified.Parameters: - obj – value to retrieve
java.lang.String
representation for - collJoinChar – character to put between next elements of a collection; applicable if given object is a collection
Returns: java.lang.String
representation of an object- obj – value to retrieve
getPrimitive¶
getWrapperForPrimitive¶
hasPrimitive¶
isPrimitive¶
isPrimitive¶
isSubclassOfMdsVersionedEntity¶
isTypeSupportedInMap¶
-
public static boolean
isTypeSupportedInMap
(String type, boolean isKey)¶ Returns true if the given type is supported in map, otherwise false.
Parameters: - type – the type to be checked
- isKey – true if it is key of the map, otherwise false
Returns: true if the given type is supported in map, otherwise false
parse¶
-
public static Object
parse
(Object val, Class<?> toClass)¶ Attempts to parse given value to an instance of a given class. Throws
java.lang.IllegalArgumentException
if this method is unable to parse the value.Parameters: - val – value to parse
- toClass – a class to turn value into
Returns: parsed value, and instance of the given class
parse¶
-
public static Object
parse
(Object val, String toClass)¶ Attempts to parse given value to an instance of a given class. Throws
java.lang.IllegalArgumentException
if this method is unable to parse the value.Parameters: - val – value to parse
- toClass – fully qualified class name
Returns: parsed value, and instance of the given class
parse¶
-
public static Object
parse
(Object val, String toClass, ClassLoader classLoader)¶ Attempts to parse given value to an instance of a given class. The class may be loaded using custom class loader, in case of a failure to load it via default class loader. Throws
java.lang.IllegalArgumentException
if this method is unable to parse the value.Parameters: - val – value to parse
- toClass – fully qualified class name
- classLoader – class loader to use, in case of a failure to find class of name
toClass
Returns: parsed value, and instance of the given class
parse¶
-
public static Object
parse
(Object val, String toClass, String genericType)¶ Attempts to parse given value to an instance of a given class. The class may have a generic type. Throws
java.lang.IllegalArgumentException
if this method is unable to parse the value.Parameters: - val – value to parse
- toClass – fully qualified class name
- genericType – fully qualified class name of a generic type
Returns: parsed value, and instance of the given class
parse¶
-
public static Object
parse
(Object val, String toClass, String genericType, ClassLoader classLoader)¶ Attempts to parse given value to an instance of a given class. The class may have a generic type and can be loaded using custom class loader, in case of a failure to load it via default class loader. Throws
java.lang.IllegalArgumentException
if this method is unable to parse the value.Parameters: - val – value to parse
- toClass – fully qualified class name
- genericType – fully qualified class name of a generic type
- classLoader – class loader to use, in case of a failure to find class of name
toClass
Returns: parsed value, and instance of the given class
parseCollection¶
-
public static Collection
parseCollection
(Collection val, Class<?> toClassDefinition, Class<?> generic)¶
parseDateToDate¶
-
public static Object
parseDateToDate
(Object val, String toClass)¶ Allows parsing of the various date types. Parsing from the
org.joda.time.LocalDate
andorg.motechproject.commons.date.model.Time
is not supported at the moment.Parameters: - val – value to parse
- toClass – destination class
Returns: date, parsed to the specified type
parseIntToBool¶
-
public static boolean
parseIntToBool
(Integer val)¶ Turns given
java.lang.Integer
intoboolean
.Parameters: - val – value to parse
Returns: true if value is not null and greater than 0; false otherwise
parseNumber¶
-
public static Number
parseNumber
(Object val, String toClass)¶ Parses given value into
java.lang.Number
or one of the standard Java types, extending Number.Parameters: - val – value to parse
- toClass – fully qualified class name
Returns: parsed value
parseString¶
-
public static Object
parseString
(String str, Class<?> toClass)¶ Attempts to parse given String to an instance of a given class. It will throw
java.lang.IllegalStateException
in case this method was not able to parse the value.Parameters: - str – String to parse
- toClass – a class to turn value into
Returns: parsed value, an instance of the given class
parseString¶
-
public static Object
parseString
(String str, String toClass)¶ Attempts to parse given String to an instance of a given class. It will throw
java.lang.IllegalStateException
in case this method was not able to parse the value.Parameters: - str – String to parse
- toClass – fully qualified class name
Returns: parsed value, an instance of the given class
parseString¶
-
public static Object
parseString
(String str, Class<?> toClass, Class<?> generic)¶ Attempts to parse given String to an instance of a given class. The class may also have a generic type. It will throw
java.lang.IllegalStateException
in case this method was not able to parse the value.Parameters: - str – String to parse
- toClass – a class to turn value into
- generic – generic class
Returns: parsed value, an instance of the given class
parseStringToMap¶
-
public static Map
parseStringToMap
(String str)¶ Parses given
java.lang.String
tojava.util.Map
. Each new entry should be preceeded by a comma mark (,). The key and value should be split with a colon mark (:). By default parsed values will be String type.Parameters: - str – String to parse
Returns: Map, parsed from the given String
parseStringToMap¶
-
public static <K, V> Map<K, V>
parseStringToMap
(Class<K> keyClass, Class<V> valueClass, String str)¶ Parses given
java.lang.String
tojava.util.Map
. Each new entry should be preceeded by a comma mark (,). The key and value should be split with a colon mark (:). Types of the parsed values depend on the given keyClass and valueClass.Parameters: - keyClass – the type of key
- valueClass – the type of value
- str – String String to parse
Returns: Map, parsed from the given String
parseStringToMap¶
-
public static Map
parseStringToMap
(String keyClass, String valueClass, String str)¶ Parses given
java.lang.String
tojava.util.Map
. Each new entry should be preceeded by a comma mark (,). The key and value should be split with a colon mark (:). Types of the parsed values depend on the given keyClass and valueClass.Parameters: - keyClass – the type of key
- valueClass – the type of value
- str – String String to parse
Returns: Map, parsed from the given String
suggestAndCreateCollectionImplementation¶
-
public static Collection
suggestAndCreateCollectionImplementation
(Class<? extends Collection> collectionClass)¶
suggestCollectionImplementation¶
-
public static Class
suggestCollectionImplementation
(String collectionClass)¶ Returns concrete class, for the given collection interface or abstract class. If given class is already concrete, it will return that class. Throws
java.lang.IllegalArgumentException
if class of given name cannot be loaded.Parameters: - collectionClass – fully qualified class name to find implementation for
Returns: concrete class
suggestCollectionImplementation¶
-
public static Class<? extends Collection>
suggestCollectionImplementation
(Class<? extends Collection> collectionClass)¶ Returns concrete class, for the given collection interface or abstract class. If given class is already concrete, it will return that class.
Parameters: - collectionClass – collection class to find implementation for
Returns: concrete class
toRange¶
-
public static Range
toRange
(Object object, String typeClass)¶ Parses given value to
org.motechproject.commons.api.Range
. If passed value is assignable neither to range nor to map, it throwsjava.lang.IllegalArgumentException
. If value is a map, it should contain keys “min” and “max”.Parameters: - object – value to parse
- typeClass – fully qualified class name of the range values
Returns:
toSet¶
-
public static Set
toSet
(Object object, String typeClass, ClassLoader classLoader)¶ Parses given
java.util.Collection
class intojava.util.Set
. If given value is not a subtype ofjava.util.Collection
it throwsjava.lang.IllegalArgumentException
.Parameters: - object – value to parse
- typeClass – type of the values that should be placed in
java.util.Set
- classLoader – optional class loader to use, loading type class
Returns: Set, parsed from the given value
ValidationUtil¶
-
public final class
ValidationUtil
¶ Common validation utils for mds.
Methods¶
validateNoJavaKeyword¶
-
public static void
validateNoJavaKeyword
(String str)¶ Verifies that given string is not a reserved Java keyword. Throws
org.motechproject.mds.exception.entity.ReservedKeywordException
if given String is reserved.Parameters: - str – String to verify
validateValidJavaFieldName¶
-
public static void
validateValidJavaFieldName
(String str)¶ Verifies that given string is a valid java field name. Throws
org.motechproject.mds.exception.entity.InvalidJavaFieldNameException
if given String is not blank and is not valid java identifier.Parameters: - str – String to verify
org.motechproject.mds.web.domain¶
BasicEntityRecord¶
-
public class
BasicEntityRecord
¶ Represents simplified entity instance (used in grids)
Constructors¶
BasicEntityRecord¶
-
public
BasicEntityRecord
(Long id, List<? extends BasicFieldRecord> fields)¶
Methods¶
getFieldByName¶
-
public BasicFieldRecord
getFieldByName
(String name)¶
getFields¶
-
public List<? extends BasicFieldRecord>
getFields
()¶
setFields¶
-
public void
setFields
(List<? extends BasicFieldRecord> fields)¶
BasicFieldRecord¶
-
public class
BasicFieldRecord
¶ Represents simplified field of entity instance. This class is used for UI purposes, to display values of the fields in grids.
Constructors¶
Methods¶
getSettingByName¶
-
public final SettingDto
getSettingByName
(String name)¶
getSettings¶
-
public List<SettingDto>
getSettings
()¶
setSettings¶
-
public void
setSettings
(List<SettingDto> settings)¶
BasicHistoryRecord¶
-
public class
BasicHistoryRecord
¶ Represents simplified revision of an entity instance (used in grids)
Constructors¶
Methods¶
getFields¶
-
public List<? extends BasicFieldRecord>
getFields
()¶
setFields¶
-
public void
setFields
(List<? extends BasicFieldRecord> fields)¶
ComboboxHolder¶
-
public class
ComboboxHolder
extends org.motechproject.mds.domain.ComboboxHolder¶ Extension of the
org.motechproject.mds.domain.ComboboxHolder
class, from the MDS module. Allows instantiation from web-specific classes.
Constructors¶
ComboboxHolder¶
-
public
ComboboxHolder
(Object instance, FieldRecord field)¶ Constructor.
Parameters: - instance – an actual instance of an entity
- field – representation of a field with the combobox type
EntityRecord¶
-
public class
EntityRecord
extends BasicEntityRecord¶ Represents single entity instance (used in jqGrid)
Constructors¶
Methods¶
getFieldByName¶
-
public FieldRecord
getFieldByName
(String name)¶
getFields¶
-
public List<FieldRecord>
getFields
()¶
setFieldRecords¶
-
public void
setFieldRecords
(List<FieldRecord> fieldRecords)¶
FieldRecord¶
-
public class
FieldRecord
extends BasicFieldRecord¶ Represents single field of entity instance. This class is mainly used by the UI to pass and retrieve value and other properties of a field.
Constructors¶
Methods¶
getMetadata¶
-
public List<MetadataDto>
getMetadata
()¶
getMetadata¶
-
public MetadataDto
getMetadata
(String key)¶
getSettings¶
-
public List<SettingDto>
getSettings
()¶
getValidation¶
-
public FieldValidationDto
getValidation
()¶
setMetadata¶
-
public void
setMetadata
(List<MetadataDto> metadata)¶
setSettings¶
-
public void
setSettings
(List<SettingDto> settings)¶
setValidation¶
-
public void
setValidation
(FieldValidationDto validation)¶
GridFieldSelectionUpdate¶
-
public class
GridFieldSelectionUpdate
¶ The
GridFieldSelectionUpdate
contains data about a visible fields update.
Constructors¶
GridFieldSelectionUpdate¶
-
public
GridFieldSelectionUpdate
(String field, GridSelectionAction action)¶
GridSelectionAction¶
-
public enum
GridSelectionAction
¶ The
GridSelectionAction
Enum contains the possible actions for a visible fields update.
Enum Constants¶
ADD¶
-
public static final GridSelectionAction
ADD
¶ Add field to visible fields.
ADD_ALL¶
-
public static final GridSelectionAction
ADD_ALL
¶ Add all fields to visible fields.
REMOVE¶
-
public static final GridSelectionAction
REMOVE
¶ Remove field from visible fields.
REMOVE_ALL¶
-
public static final GridSelectionAction
REMOVE_ALL
¶ Removes all field from visible fields.
GridSettings¶
-
public class
GridSettings
¶ Settings used by jqGrid to properly show entity instances list
Methods¶
HistoryRecord¶
-
public class
HistoryRecord
¶ Represents single entity instance revision.
Constructors¶
Methods¶
getFields¶
-
public List<FieldRecord>
getFields
()¶
setFields¶
-
public void
setFields
(List<FieldRecord> fields)¶
Records¶
-
public class
Records
<T>¶ Class required for jqGrid to exchange data with server
Constructors¶
Methods¶
RelationshipsUpdate¶
-
public class
RelationshipsUpdate
¶ Representation of the related instances, that have been added or removed on the UI.
Methods¶
getAddedNewRecords¶
-
public List<EntityRecord>
getAddedNewRecords
()¶
setAddedNewRecords¶
-
public void
setAddedNewRecords
(List<EntityRecord> addedNewRecords)¶
org.motechproject.mds.web.service¶
InstanceService¶
-
public interface
InstanceService
¶ The
InstanceService
interface, defines methods responsible for executing actions on the instances of the entity.
Methods¶
countHistoryRecords¶
countRecords¶
countRecordsByLookup¶
-
long
countRecordsByLookup
(Long entityId, String lookupName, Map<String, Object> lookupMap)¶ Retrieves total count of the instances, that match given lookup criteria. Throws
org.motechproject.mds.exception.lookup.LookupNotFoundException
if lookup of the given name does not exist for the given entity. It will also throworg.motechproject.mds.exception.lookup.LookupExecutionException
if lookup parameters do not match their definition.Parameters: - entityId – id of the entity
- lookupName – name of the lookup
- lookupMap – map, containing lookup parameters with their respective values
Returns: total count, of the instances that match lookup criteria
countRecordsWithFilters¶
countTrashRecords¶
deleteAllInstances¶
deleteInstance¶
deleteSelectedInstances¶
getEntityFields¶
-
List<FieldDto>
getEntityFields
(Long entityId)¶ Retrieves all fields of the entity. This will not include draft fields, created, modified or deleted by the current user. Throws
org.motechproject.mds.exception.entity.EntityNotFoundException
, if entity of the given id does not exist.Parameters: - entityId – id of the entity
Returns: all fields of the entity
getEntityInstance¶
-
EntityRecord
getEntityInstance
(Long entityId, Long instanceId)¶ Retrieves an instance of the given entity, by its id. If there’s no instance of such id, for the given entity, it throws
org.motechproject.mds.exception.object.ObjectNotFoundException
.Parameters: - entityId – id of the entity
- instanceId – id of the instance
Returns: an instance representation
getEntityRecords¶
-
List<BasicEntityRecord>
getEntityRecords
(Long entityId, QueryParams queryParams)¶ Returns all instances of the entity, that the current user has access to. Additionally, allows to tamper the results, using query parameters (eg. to limit the number of retrieves records). Throws
org.motechproject.mds.exception.entity.EntityNotFoundException
, if entity of the given id does not exist.Parameters: - entityId – id of the entity
- queryParams – query parameters to use, retrieving instances
Returns: a list of instances
getEntityRecords¶
-
List<BasicEntityRecord>
getEntityRecords
(Long entityId)¶ Returns all instances of the entity, that the current user has access to. Throws
org.motechproject.mds.exception.entity.EntityNotFoundException
, if entity of the given id does not exist.Parameters: - entityId – id of the entity
Returns: a list of instances
getEntityRecordsFromLookup¶
-
List<BasicEntityRecord>
getEntityRecordsFromLookup
(Long entityId, String lookupName, Map<String, Object> lookupMap, QueryParams queryParams)¶ Retrieves and executes a lookup of the given name, from the given entity. Additionally, allows to tamper the results, using query parameters (eg. to limit the number of retrieves records). It will throw
org.motechproject.mds.exception.lookup.LookupExecutionException
in case the provided lookup parameters do not match the lookup definition or if the execution could not be performed for any other reason. It will also throworg.motechproject.mds.exception.entity.EntityNotFoundException
andorg.motechproject.mds.exception.lookup.LookupNotFoundException
if entity of the given id or lookup of the given name does not exist.Parameters: - entityId – id of the entity
- lookupName – name of the lookup
- lookupMap – map, containing lookup parameters with their respective values
- queryParams – query parameters to use, retrieving instances
Returns: a list of instances, retrieved using the given lookup
getEntityRecordsWithFilter¶
-
List<BasicEntityRecord>
getEntityRecordsWithFilter
(Long entityId, Filters filters, QueryParams queryParams)¶ Retrieves all instances of the given entity, that match criteria, specified in the provided filters. Additionally, allows to tamper the results, using query parameters (eg. to limit the number of retrieves records). It will throw
org.motechproject.mds.exception.entity.EntityNotFoundException
when entity of given id does not exist.Parameters: - entityId – id of the entity
- filters – filters to use, retrieving instances
- queryParams – query parameters to use, retrieving instances
Returns: a list of instances, matching given filters
getHistoryRecord¶
-
HistoryRecord
getHistoryRecord
(Long entityId, Long instanceId, Long historyId)¶ Retrieves a single, historical revision of an instance, by its id.
Parameters: - entityId – id of the entity
- instanceId – id of the instance
- historyId – id of the historical revision
Returns: the historical revision of the instance
getInstanceField¶
-
Object
getInstanceField
(Long entityId, Long instanceId, String fieldName)¶ Retrieves value of a single field of an instance. Throws
org.motechproject.mds.exception.entity.EntityNotFoundException
if entity of given id does not exist.Parameters: - entityId – id of the entity
- instanceId – id of the instance
- fieldName – name of the field to retrieve
Throws: - InstanceNotFoundException – if instance with the given id does not exist
Returns: value of the field
getInstanceFields¶
-
List<FieldInstanceDto>
getInstanceFields
(Long entityId, Long instanceId)¶ Returns field definitions of the given entity, assigned to the given instance. Throws
org.motechproject.mds.exception.entity.EntityNotFoundException
if entity of the given id does not exist.Parameters: - entityId – id of the entity
- instanceId – id of the instance
Returns: a list of field definitions
getInstanceHistory¶
-
List<BasicHistoryRecord>
getInstanceHistory
(Long entityId, Long instanceId, QueryParams queryParams)¶ Retrieves a list of historical revisions for the given instance. Current revision will not be a part of the result. Additionally, allows to tamper the results, using query parameters (eg. to limit the number of retrieves records).
Parameters: - entityId – id of the entity
- instanceId – id of the instance
- queryParams – query parameters to use, retrieving instances
Returns: a list of historical revisions for the instance
getSingleTrashRecord¶
-
EntityRecord
getSingleTrashRecord
(Long entityId, Long instanceId)¶ Allows to retrieve a single instance, that has been moved to trash.
Parameters: - entityId – id of the entity
- instanceId – id of the instance in trash
Returns: instance representation
getTrashRecords¶
-
List<BasicEntityRecord>
getTrashRecords
(Long entityId, QueryParams queryParams)¶ Retrieves instances of the given entity, placed in trash. This will only return instances, that have been moved to trash on the given entity schema. Additionally, allows to tamper the results, using query parameters (eg. to limit the number of retrieves records).
Parameters: - entityId – id of the entity
- queryParams – query parameters to use, retrieving instances from trash
Returns: list of instances, placed in trash
newInstance¶
-
EntityRecord
newInstance
(Long entityId)¶ Prepares a new instance representation. Builds available fields and populates some of the auto-generated fields.
Parameters: - entityId – id of the entity
Returns: the new instance representation
revertInstanceFromTrash¶
-
void
revertInstanceFromTrash
(Long entityId, Long instanceId)¶ Brings back an instance from trash. This, in fact, creates a new instance in MDS and assigns identical field values as the deleted instance, after which the deleted instance is removed permanently. Old id of the instance will not be persisted.
Parameters: - entityId – id of the entity
- instanceId – id of the instance in trash
revertPreviousVersion¶
-
void
revertPreviousVersion
(Long entityId, Long instanceId, Long historyId)¶ Retrieves a historical revision of an instance and attempts to revert specified instance to its previous state. It will throw
org.motechproject.mds.exception.entity.EntitySchemaMismatchException
if two instances are from two different schemas (meaning, that the entity has been changed at least once).Parameters: - entityId – id of the entity
- instanceId – id of the instance
- historyId – id of the historical revision
saveInstance¶
-
Object
saveInstance
(EntityRecord entityRecord)¶ Saves the given instance representation in MDS. If the representation has the id field assigned, an update will be performed. Otherwise, it will attempt to create a new instance.
Parameters: - entityRecord – representation of the instance
Throws: - org.motechproject.mds.exception.object.ObjectNotFoundException – if the id is specified, but the instance of such id does not exist
- org.motechproject.mds.exception.object.ObjectUpdateException – if any problem arises while saving the instance
Returns: Created instance
saveInstance¶
-
Object
saveInstance
(EntityRecord entityRecord, Long deleteValueFieldId)¶ Saves the given instance representation in MDS. If the representation has the id field assigned, an update will be performed. Otherwise, it will attempt to create an instance. If the id is specified, but the instance of such id does not exist, it throws
org.motechproject.mds.exception.object.ObjectNotFoundException
. If any problem arises while saving the the instance, it throwsorg.motechproject.mds.exception.object.ObjectUpdateException
. This method is capable of removing the blob field values.Parameters: - entityRecord – representation of the instance
- deleteValueFieldId – blob field ID, to clear the value for; it will not be effective for any other field types
Returns: Created instance
validateNonEditableProperty¶
-
void
validateNonEditableProperty
(Long entityId)¶ Checks whether the entity with the given ID is non editable.
Parameters: - entityId – the id of the entity
Throws: - EntityInstancesNonEditableException – if the entity is non editable
org.motechproject.mdsmigration.java¶
AbstractMDSMigration¶
-
public abstract class
AbstractMDSMigration
implements SpringJdbcMigration¶ This is an abstract class for java migrations. Flyway-core does not see java migration files inside motech-platform-dataservices, because of that we need this class here to invoke by reflections the real implementation of migrations.
org.motechproject.osgi.web¶
BundleContextWrapper¶
-
public class
BundleContextWrapper
implements BundleContextAware¶ This is a wrapper class for the OSGi
org.osgi.framework.BundleContext
class. It provides convenience methods for processing Blueprint contexts of modules. This class implementsorg.eclipse.gemini.blueprint.context.BundleContextAware
, so if it’s published as a Spring bean, the bundle context object should get injected by Spring.
Fields¶
CONTEXT_SERVICE_NAME¶
-
public static final String
CONTEXT_SERVICE_NAME
¶ The service property set by Blueprint for application contexts published at services. The value for this property will be equal to the symbolic name of the bundle from which the context comes from. It allows to retrieve a published context for a given bundle from the bundle context.
Constructors¶
BundleContextWrapper¶
-
public
BundleContextWrapper
()¶ The default constructor, expects the bundle context to be injected by Spring.
BundleContextWrapper¶
-
public
BundleContextWrapper
(BundleContext context)¶ Constructs this wrapper for a given bundle context.
Parameters: - context – the bundle context to wrap around
Methods¶
getBundleApplicationContext¶
-
public ApplicationContext
getBundleApplicationContext
()¶ Returns the Spring
org.springframework.context.ApplicationContext
created by Blueprint for the bundle the underlying bundle context comes from. The context is retrieved from the bundle context, since Blueprint publishes application contexts as OSGi services.Returns: the context created by Blueprint for the bundle the underlying context comes from, or null if there is no context
getBundleContext¶
-
public BundleContext
getBundleContext
()¶ Returns: the underlying org.osgi.framework.BundleContext
object
getCurrentBundleSymbolicName¶
getService¶
-
public <T> T
getService
(Class<T> clazz)¶ Retrieves an OSGi service using the underlying bundle context. Note that this will return the service from the first reference, so multiple services for one class are not supported by this method (you will get a random instance).
Parameters: - clazz – the class of the service to retrieve
- <T> – the class of the service to retrieve
Returns: an OSGi service for the class, or null if there is no such service available
setBundleContext¶
-
public void
setBundleContext
(BundleContext bundleContext)¶
BundledJspView¶
-
public class
BundledJspView
extends JstlView implements BundleContextAware¶ This is a class that should be used as the viewClass with Spring view resolvers in order to support loading of JSP pages coming from OSGi bundles in Tomcat. This class will set the org.apache.catalina.jsp_file attribute in the request. That attribute is recognized by Tomcat and will make it load the JSP from the bundle. When registered as bean, this will obtain the bundle context (since it implements
org.eclipse.gemini.blueprint.context.BundleContextAware
and will point Tomcat to resources of the bundle the context comes from.
Methods¶
render¶
-
public void
render
(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)¶
setBundleContext¶
-
public void
setBundleContext
(BundleContext bundleContext)¶
ModuleRegistrationData¶
-
public class
ModuleRegistrationData
¶ Object used to registered a module withing the Motech UI system. Represents a module and is used for building the common user interface. All modules that wish to register within the UI system must either expose this class as a spring bean in their application context or manually register it through the
UIFrameworkService
OSGi service.See also:
UIFrameworkService
Constructors¶
ModuleRegistrationData¶
ModuleRegistrationData¶
-
public
ModuleRegistrationData
(String moduleName, Map<String, String> i18n)¶ Constructor for modules that just want to register i18n files (i.e. for tasks).
Parameters: - moduleName – the name of the module
- i18n – a map, where the keys are the names of the i18n files and values are their locations (HTTP locations)
ModuleRegistrationData¶
-
public
ModuleRegistrationData
(String moduleName, String url, List<String> angularModules, Map<String, String> i18n)¶ Constructor for modules that want to register their own panels in the UI.
Parameters: - moduleName – the name of the module
- url – the url under which this module can be accessed
- angularModules – the list of angular modules that should be loaded on the UI for this module
- i18n – a map, where the keys are the names of the i18n files and values are their locations (HTTP locations)
Methods¶
addAngularModule¶
addI18N¶
addSubMenu¶
-
public void
addSubMenu
(String url, String label, String roleForAccess)¶ Adds a submenu to this module. Submenu is a link on the left side of the UI.
Parameters: - url – the url to which the link will redirect to
- label – the label that will be displayed on the UI
- roleForAccess – the permission required to view this sub menu (will be hidden if the user doesn’t have the permission)
getAngularModules¶
getAngularModulesStr¶
getCriticalMessage¶
getDefaultURL¶
getDocumentationUrl¶
getI18n¶
getModuleName¶
getRestDocsPath¶
getRoleForAccess¶
getSettingsURL¶
getTabAccessMap¶
isNeedsAttention¶
-
public boolean
isNeedsAttention
()¶ Checks whether this module needs attention - meaning it requires a UI notification pointing to it.
Returns: true if the module needs attention, false otherwise
removeAngularModule¶
setBundle¶
setCriticalMessage¶
setDefaultURL¶
setModuleName¶
setNeedsAttention¶
-
public void
setNeedsAttention
(boolean needsAttention)¶ Sets whether this module needs attention - meaning it requires a UI notification pointing to it.
Parameters: - needsAttention – true if the module needs attention, false otherwise
setResourcePath¶
setRestDocsPath¶
setRoleForAccess¶
setRoleForAccess¶
setSettingsURL¶
setTabAccessMap¶
MotechOSGiWebApplicationContext¶
-
public class
MotechOSGiWebApplicationContext
extends OsgiBundleXmlApplicationContext implements ConfigurableWebApplicationContext¶ The context that is created for all Blueprint-Enabled bundles. This context will be used for the
OSGiDispatcherServlet
that we create in theHttpServiceTracker
.
Methods¶
getServletConfig¶
-
public ServletConfig
getServletConfig
()¶
getServletContext¶
-
public ServletContext
getServletContext
()¶
setServletConfig¶
-
public void
setServletConfig
(ServletConfig servletConfig)¶
setServletContext¶
-
public void
setServletContext
(ServletContext servletContext)¶
org.motechproject.osgi.web.domain¶
org.motechproject.osgi.web.exception¶
BundleConfigurationLoadingException¶
RenderException¶
ServiceWaitInterruptedException¶
-
public class
ServiceWaitInterruptedException
extends RuntimeException¶ Exception that signals that waiting for an OSGi service was interrupted.
Constructors¶
ServiceWaitInterruptedException¶
-
public
ServiceWaitInterruptedException
(String serviceCLassName, InterruptedException cause)¶
ServletRegistrationException¶
-
public class
ServletRegistrationException
extends RuntimeException¶ Thrown when an error occurs during registration of a module servlet.
org.motechproject.osgi.web.extension¶
ApplicationEnvironment¶
-
public final class
ApplicationEnvironment
¶ Utility class for handling the
ENVIRONMENT
system variable. The only meaningful value for the variable at the momentDEVELOPMENT
, which will cause MOTECH to load static resources from disk paths instead of jar classpaths. It also allows resolving of these disk paths for given bundle name.
Fields¶
Methods¶
getEnvironment¶
getModulePath¶
-
public static String
getModulePath
(BundleName bundleName)¶ Returns the root disk path from which resources for the bundle with a given name should be loaded. This is controlled by system variables with names equal to bundle symbolic names with dots and dashes replaced with underscores. For example, the path for a bundle with the symbolic name
org.motechproject.cms-lite
is controlled by the system variableorg_motechproject_cms_lite
.Parameters: - bundleName – the name of bundle
Returns: the root path from which to load bundle resources or null if it is not set
HttpContextFactory¶
-
public final class
HttpContextFactory
¶ This factory is responsible for creating
org.osgi.service.http.HttpContext
decorator objects for bundles. If dynamic resource loading is set for a given bundle, meaning theENVIRONMENT
variable is set toDEVELOPMENT
and variable with an underscored version of the bundle symbolic name is defined, an instance ofFileSystemAwareUIHttpContext
will be created for the bundle. In other cases the provided contex is unchaged.
Methods¶
getHttpContext¶
-
public static HttpContext
getHttpContext
(HttpContext httpContext, Bundle bundle)¶ Decorates the given HttpContext with a @{link FileSystemAwareUIHttpContext} if dynamic resource loading is set up.
Parameters: - httpContext – the default http context for a given bundle
- bundle – the bundle for which this http context will be registered
Returns: the decorated instance of the provided context if dynamic loading was set up, the original instance otherwise
org.motechproject.osgi.web.service¶
LocaleService¶
-
public interface
LocaleService
¶ A service responsible for localization. Allows retrieval/settings of user language as well as retrieving localized messages for a user request. Can also be used to retrieve a list of usable languages.
Methods¶
getSupportedLanguages¶
-
NavigableMap<String, String>
getSupportedLanguages
()¶
getUserLocale¶
-
Locale
getUserLocale
(HttpServletRequest request)¶
setSessionLocale¶
-
void
setSessionLocale
(HttpServletRequest request, HttpServletResponse response, Locale locale)¶
setUserLocale¶
-
void
setUserLocale
(HttpServletRequest request, HttpServletResponse response, Locale locale)¶
ServerLogService¶
-
public interface
ServerLogService
¶ Interface for accessing log4j Logger configuration.
Methods¶
changeLogLevel¶
changeRootLogLevel¶
getAllLogMappings¶
-
List<LogMapping>
getAllLogMappings
()¶ Returns details for all loggers. Root logger included.
Returns: all loggers details, including the root logger
getLogLevels¶
-
List<LogMapping>
getLogLevels
()¶ Returns details for all loggers. Root logger is NOT included.
Returns: details for all loggers, except the root logger
getRootLogLevel¶
-
LogMapping
getRootLogLevel
()¶ Returns the logger details for the root logger
Returns: root logger details
UIFrameworkService¶
-
public interface
UIFrameworkService
¶ Service responsible for managing the user interface. Provides methods for registering/un-registering modules. All modules are represented by
ModuleRegistrationData
objects, either registered directly through this service or automatically by exposing it in their spring context. This service also allows manipulation of module state, by marking given modules as requiring attention on the UI.
Methods¶
getModuleData¶
-
ModuleRegistrationData
getModuleData
(String moduleName)¶ Gets registration data for the module with the given name.
Parameters: - moduleName – the name of the module for which the registration data should be retrieved
Returns: the registration data for the given module, or null if such a module is not registered
getModuleDataByAngular¶
-
ModuleRegistrationData
getModuleDataByAngular
(String angularModule)¶ Retrieves module registration data which registers the given AngularJS module.
Parameters: - angularModule – the name of the Angular module
Returns: the registration for the module that registers the Angular module
getModuleDataByBundle¶
-
ModuleRegistrationData
getModuleDataByBundle
(Bundle bundle)¶ Retrieves the module registration data for a given bundle. Since
org.motechproject.osgi.web.ModuleRegistrationData
held by the service contain references to the bundles registering them, this will match relying on Bundle.equals().Parameters: - bundle – the bundle for which the registration data should be retrieved
Returns: the registration data for the given bundle (module)
getRegisteredModules¶
-
ModuleRegistrations
getRegisteredModules
()¶ Returns information about all modules registered with the UI system. The modules are grouped into module with their own submenus (links to menus in the top menu), those without their submenus (they are all placed in the modules section) and those without UI altogether (messages from them will be loaded though, for usage in tasks and possibly other places).
Returns: all modules registered with the system
getRestDocLinks¶
isModuleRegistered¶
moduleBackToNormal¶
-
void
moduleBackToNormal
(String moduleName)¶ Marks the module as no longer requiring attention, undoing the
moduleNeedsAttention(String,String)
call. The red marker will disappear from the link of that module.Parameters: - moduleName – the name of the module that is back to normal
moduleBackToNormal¶
-
void
moduleBackToNormal
(String moduleName, String submenu)¶ Marks the module and submenu as no longer requiring attention, undoing the
moduleNeedsAttention(String,String,String)
call. The red marker will disappear from the link of that module and submenu.Parameters: - moduleName – the name of the module that is back to normal
- submenu – the name of the submenu that is back to normal
moduleNeedsAttention¶
-
void
moduleNeedsAttention
(String moduleName, String message)¶ Marks a module as requiring attention, by setting the
org.motechproject.osgi.web.ModuleRegistrationData.setNeedsAttention(boolean)
flag and the critical message for the module usingorg.motechproject.osgi.web.ModuleRegistrationData.setCriticalMessage(String)
. This will mark the module as needing attention on the UI by display a red warning sign next to its link and displaying the message.Parameters: - moduleName – the name of the module to mark as requiring attention
- message – the message explaining the reason for this alert
moduleNeedsAttention¶
-
void
moduleNeedsAttention
(String moduleName, String submenu, String message)¶ Does the same as
moduleNeedsAttention(String,String)
, with the difference that an entire submenu (the top level menu) will be marked as requiring attention.Parameters: - moduleName – the name of the module to mark as requiring attention
- submenu – the name of the submenu to be marked as requiring attention
- message – the message explaining the reason for this alert
registerModule¶
-
void
registerModule
(ModuleRegistrationData module)¶ Registers a module in the UI system.
Parameters: - module – a
org.motechproject.osgi.web.ModuleRegistrationData
representing the module to register
- module – a
org.motechproject.osgi.web.settings¶
Loggers¶
-
public class
Loggers
¶ Holds information about all log4j loggers in our system.
Constructors¶
Loggers¶
-
public
Loggers
(List<LogMapping> loggers, LogMapping root)¶
Methods¶
getLoggers¶
-
public List<LogMapping>
getLoggers
()¶
getRoot¶
-
public LogMapping
getRoot
()¶
getTrash¶
-
public List<LogMapping>
getTrash
()¶
setLoggers¶
-
public void
setLoggers
(List<LogMapping> loggers)¶
setRoot¶
-
public void
setRoot
(LogMapping root)¶
setTrash¶
-
public void
setTrash
(List<LogMapping> trash)¶
org.motechproject.osgi.web.tracker¶
ApplicationContextTracker¶
-
public abstract class
ApplicationContextTracker
extends ServiceTracker¶ Base class for every class that wishes to track Spring application context. Contains a methods that help with synchronous processing.
Constructors¶
ApplicationContextTracker¶
-
public
ApplicationContextTracker
(BundleContext context)¶
Methods¶
contextInvalidOrProcessed¶
-
protected boolean
contextInvalidOrProcessed
(ServiceReference serviceReference, ApplicationContext applicationContext)¶ Checks whether the given context is still valid (by checking its service reference) and not yet processed.
Parameters: - serviceReference – the service reference for the context
- applicationContext – the context to check
Returns: true if the context is invalid or already processed, false otherwise
getLock¶
markAsProcessed¶
-
protected void
markAsProcessed
(ApplicationContext applicationContext)¶ Marks the given application context as already processed by this tracker, by saving its id.
Parameters: - applicationContext – the application context to be marked as processed
removeFromProcessed¶
-
protected void
removeFromProcessed
(ApplicationContext applicationContext)¶ Undoes marking an application context as processed by this tracked. Its id is removed from the list of processed ids.
Parameters: - applicationContext – the application context to remove from the list of processed contexts
HttpServiceTrackers¶
-
public class
HttpServiceTrackers
¶ This is responsible for creating and keeping track of
HttpServiceTracker
instances.
Constructors¶
HttpServiceTrackers¶
-
public
HttpServiceTrackers
(BundleContext bundleContext)¶ Creates this http tracker registry and registers a bundle listener, that will close the trackers for a bundle once it is stopped.
Parameters: - bundleContext – the context used for registering the bundle listener
UIServiceTrackers¶
-
public class
UIServiceTrackers
¶ The registry that handles
UIServiceTracker
instances created for bundles withBlueprint-Enabled
header in their manifest.See also:
UIServiceTracker
Constructors¶
UIServiceTrackers¶
-
public
UIServiceTrackers
(BundleContext bundleContext)¶ Constructs the registry and registers a bundle listener that will remove trackers for bundles that are stopping.
Parameters: - bundleContext – the bundle context used to register the bundle listener
Methods¶
addTrackerFor¶
-
public UIServiceTracker
addTrackerFor
(Bundle bundle, ApplicationContext applicationContext)¶ Creates a
UIServiceTracker
for the given bundle. Theorg.motechproject.osgi.web.ModuleRegistrationData
from the provided Spring context of the bundle will be used for registering the UI.Parameters: - bundle – the bundle to create the tracker for
- applicationContext – the Spring context of the bundle
Returns: the newly created
UIServiceTracker
instance
isBeingTracked¶
org.motechproject.osgi.web.util¶
BundleHeaders¶
-
public class
BundleHeaders
¶ A convenience class for reading bundle headers.
Fields¶
Constructors¶
BundleHeaders¶
-
public
BundleHeaders
(BundleContext bundleContext)¶ Constructs this class using a bundle from which the given bundle context from.
Parameters: - bundleContext – the context of the bundle for which we want to read headers
ModuleRegistrations¶
-
public class
ModuleRegistrations
¶ Represents all modules registered with the system. Modules are grouped into 3 categories: modules with sub-menu - modules that have multiple menu items, they get a link in the top level, the admin module is an example modules without sub-menu - modules that are placed in the “Modules” section on the UI, the email module is an example modules without UI - modules that don’t have any UI, but register i18n files for example, pill-reminder is an example
Constructors¶
ModuleRegistrations¶
-
public
ModuleRegistrations
()¶ Constructs a new instance, initializing all 3 groups as empty lists.
ModuleRegistrations¶
-
public
ModuleRegistrations
(Collection<ModuleRegistrationData> modulesWithSubMenu, Collection<ModuleRegistrationData> modulesWithoutSubmenu, Collection<ModuleRegistrationData> modulesWithoutUI)¶ Constructs a new instances with the 3 groups provided as collections.
Parameters: - modulesWithSubMenu – modules with sub menus
- modulesWithoutSubmenu – modules without sub-menus
- modulesWithoutUI – modules without UI
Methods¶
allRegistrations¶
-
public List<ModuleRegistrationData>
allRegistrations
()¶ Returns all registered modules from all the 3 groups as one list.
Returns: all registered modules
getModulesWithoutUI¶
-
public Collection<ModuleRegistrationData>
getModulesWithoutUI
()¶ Returns: registered modules without UI
setModulesWithoutUI¶
-
public void
setModulesWithoutUI
(Collection<ModuleRegistrationData> modulesWithoutUI)¶ Parameters: - modulesWithoutUI – registered modules without UI
OSGiServiceUtils¶
-
public final class
OSGiServiceUtils
¶ Utility class for retrieving OSGi services.
Methods¶
findService¶
-
public static <T> T
findService
(BundleContext bundleContext, Class<T> clazz)¶ Retrieves the service of the given class from the bundle context. This will retrieve the service with highest priority if there are multiple instances of the service.
Parameters: - bundleContext – the bundleContext which will be used for service retrieval
- clazz – the class of the service to be retrieved
- <T> – the type of the service to be returned
Returns: the service found or
null
if there is no such service in the bundle context
findService¶
-
public static <T> T
findService
(BundleContext bundleContext, String className)¶ Retrieves the service of the given class from the bundle context. This will retrieve the service with highest priority if there are multiple instances of the service.
Parameters: - bundleContext – the bundleContext which will be used for service retrieval
- className – the class name of the service to be retrieved
- <T> – the type of the service to be returned
Returns: the service found or
null
if there is no such service in the bundle context
findService¶
-
public static <T> T
findService
(BundleContext bundleContext, Class<T> clazz, long timeout)¶ Retrieves the service of the given class from the bundle context. This will retrieve the service with highest priority if there are multiple instances of the service. Based on the timeout parameter representing the max wait time for the service, the lookup for the service will be performed multiple times in one second intervals. The lookup will be performed at least once.
Parameters: - bundleContext – the bundleContext which will be used for service retrieval
- clazz – the class of the service to be retrieved
- timeout – the max time that will be spent waiting for the service, in miliseconds
- <T> – the type of the service to be returned
Returns: the service found or
null
if there is no such service in the bundle context
findService¶
-
public static <T> T
findService
(BundleContext bundleContext, String className, long timeout)¶ Retrieves the service of the given class from the bundle context. This will retrieve the service with highest priority if there are multiple instances of the service. Based on the timeout parameter representing the max wait time for the service, the lookup for the service will be performed multiple times in one second intervals. The lookup will be performed at least once.
Parameters: - bundleContext – the bundleContext which will be used for service retrieval
- className – the class name of the service to be retrieved
- timeout – the max time that will be spent waiting for the service, in miliseconds
- <T> – the type of the service to be returned
Returns: the service found or
null
if there is no such service in the bundle context
WebBundleUtil¶
-
public final class
WebBundleUtil
¶ Utility class for easing bundle related operations/searches.
Methods¶
findBundleByName¶
-
public static Bundle
findBundleByName
(BundleContext bundleContext, String name)¶ Does a search for a bundle with a matching Bundle-Name header in its manifest. Note that if there two bundles installed with the same name, the first one found will be returned.
Parameters: - bundleContext – the bundle context used for the search
- name – the Bundle-Name header value of the bundle we are searching for
Returns: the matching bundle, or null if there is no such bundle
findBundleBySymbolicName¶
-
public static Bundle
findBundleBySymbolicName
(BundleContext bundleContext, String symbolicName)¶ Does a search for a bundle with a matching symbolic name. Note that if there two bundles installed with the same symbolic name, the first one found will be returned.
Parameters: - bundleContext – the bundle context used for the search
- symbolicName – symbolic name of the bundle we are looking for
Returns: the matching bundle, or null if no such bundle exists
getContextLocation¶
-
public static String
getContextLocation
(Bundle bundle)¶ Returns the context file location for the bundle, by using reading its Context-File header.
Parameters: - bundle – the bundle for which we want to retrieve the context file location for
Returns: the location of the context file, or null if it is not defined
getContextPath¶
getModuleId¶
getSymbolicNames¶
-
public static List<String>
getSymbolicNames
(BundleContext context)¶ Returns the list of bundles symbolic names.
Parameters: - context – the context of the bundle, not null
Returns: the list of the bundles symbolic names
org.motechproject.scheduler.builder¶
CronJobExpressionBuilder¶
-
public class
CronJobExpressionBuilder
¶ Builder for creating cron expressions for jobs, which should be triggered every
repeatIntervalInMinutes
forrepeatWindowInHours
hours or stop at 23:startTime.getMinute()
.
Constructors¶
CronJobExpressionBuilder¶
-
public
CronJobExpressionBuilder
(Time startTime, Integer repeatWindowInHours, Integer repeatIntervalInMinutes)¶ Constructor.
Parameters: - startTime – the time at which job should become active, not null
- repeatWindowInHours – the period(in hours) in which job should be active
- repeatIntervalInMinutes – the interval between job fires
CronJobSimpleExpressionBuilder¶
-
public class
CronJobSimpleExpressionBuilder
¶ Builder for simple cron expressions for jobs, which should be fired every
repeatIntervalInDays
days.
Constructors¶
Methods¶
build¶
withRepeatIntervalInDays¶
-
public CronJobSimpleExpressionBuilder
withRepeatIntervalInDays
(int repeatIntervalInDays)¶ Sets interval on which job should be fired.
Parameters: - repeatIntervalInDays – the interval(in days) between job fires, 0 means everyday
Returns: the
CronJobSimpleExpressionBuilder
ready to build cron expressions
SchedulableJobBuilder¶
-
public final class
SchedulableJobBuilder
¶ Responsible for building jobs based on the given information;
Methods¶
buildJob¶
-
public static SchedulableJob
buildJob
(JobKey key, JobDataMap dataMap, Trigger trigger)¶ Builds a job based on the given key, data map and trigger.
Parameters: - key – the job key
- dataMap – the job data map
- trigger – the job trigger
Throws: - SchedulerException – when there were problems while building job
Returns: the created job
WeeklyCronJobExpressionBuilder¶
-
public class
WeeklyCronJobExpressionBuilder
¶ Cron expression builder for jobs, which should be triggered on given day of week at given time.
Constructors¶
WeeklyCronJobExpressionBuilder¶
WeeklyCronJobExpressionBuilder¶
-
public
WeeklyCronJobExpressionBuilder
(int dayOfWeekNumber)¶ Constructor.
Parameters: - dayOfWeekNumber – the day of week at which job should be fired, must be in range from 1 to 7
Throws: - java.lang.IllegalArgumentException – when dayOfWeekNumber isn’t in range from 1 to 7
org.motechproject.scheduler.contract¶
CronJobId¶
Constructors¶
CronJobId¶
CronJobId¶
-
public
CronJobId
(MotechEvent event)¶ Constructor.
Parameters: - event – the
MotechEvent
fired, when job is triggered, not null
- event – the
CronSchedulableJob¶
-
public class
CronSchedulableJob
extends EndingSchedulableJob¶ Schedulable Job - a data carrier class for a scheduled job that can be fired unlimited number of times as specified with the cron expression
Author: Igor (iopushnyev@2paths.com) Date: 16/02/11 Time: 1:43 PM
Constructors¶
CronSchedulableJob¶
-
public
CronSchedulableJob
(MotechEvent motechEvent, String cronExpression, DateTime startTime, DateTime endTime)¶ Constructor.
Parameters: - motechEvent – the
MotechEvent
fired, when job triggers, not null - cronExpression – the cron expression, which defines when job should be fired, not null
- startTime – the
DateTime
at which job should become ACTIVE, not null - endTime – the
DateTime
at which job should be stopped, null treated as never end
- motechEvent – the
CronSchedulableJob¶
-
public
CronSchedulableJob
(MotechEvent motechEvent, String cronExpression)¶ Constructor.
Parameters: - motechEvent – the
MotechEvent
fired, when job triggers, not null - cronExpression – the cron expression, which defines when job should be fired, not null
- motechEvent – the
CronSchedulableJob¶
-
public
CronSchedulableJob
(MotechEvent motechEvent, String cronExpression, DateTime startTime, DateTime endTime, boolean ignorePastFiresAtStart)¶ Constructor.
Parameters: - motechEvent – the
MotechEvent
fired, when job triggers, not null - cronExpression – the cron expression, which defines when job should be fired, not null
- startTime – the
DateTime
at which job should become ACTIVE, not null - endTime – the
DateTime
at which job should be stopped, null treated as never end - ignorePastFiresAtStart – the flag defining, whether job should ignore past fires at start or not
- motechEvent – the
CronSchedulableJob¶
-
public
CronSchedulableJob
(MotechEvent motechEvent, String cronExpression, DateTime startTime, DateTime endTime, boolean ignorePastFiresAtStart, boolean uiDefined)¶ Constructor.
Parameters: - motechEvent – the
MotechEvent
fired, when job triggers, not null - cronExpression – the cron expression, which defines when job should be fired, not null
- startTime – the
Date
at which job should become ACTIVE, not null - endTime – the
Date
at which job should be stopped, null treated as never end - ignorePastFiresAtStart – the flag defining, whether job should ignore past fires at start or not
- uiDefined – the flag defining, whether job has been created through the UI
- motechEvent – the
DayOfWeekSchedulableJob¶
-
public final class
DayOfWeekSchedulableJob
extends EndingSchedulableJob¶ Job that is scheduled on particular days of week
Constructors¶
DayOfWeekSchedulableJob¶
-
public
DayOfWeekSchedulableJob
(MotechEvent motechEvent, DateTime startDate, DateTime endDate, List<DayOfWeek> days, Time time, boolean ignorePastFiresAtStart)¶ Constructor.
Parameters: - motechEvent – the
MotechEvent
fired, when job triggers, not null - startDate – the
Date
at which job should become ACTIVE, not null - endDate – the
Date
at which job should be stopped, null treated as never end - days – the list of days at which job should be fired, not null
- time – the time at which job should be fired, not null
- ignorePastFiresAtStart – the flag defining whether job should ignore past fires at start or not
- motechEvent – the
DayOfWeekSchedulableJob¶
-
public
DayOfWeekSchedulableJob
(MotechEvent motechEvent, DateTime startDate, DateTime endDate, List<DayOfWeek> days, Time time)¶ Constructor.
Parameters: - motechEvent – the
MotechEvent
fired, when job triggers, not null - startDate – the
Date
at which job should become ACTIVE, not null - endDate – the
Date
at which job should be stopped, null treated as never end - days – the list of days at which job should be fired, not null
- time – the time at which job should be fired, not null
- motechEvent – the
DayOfWeekSchedulableJob¶
-
public
DayOfWeekSchedulableJob
(MotechEvent motechEvent, DateTime startDate, DateTime endDate, List<DayOfWeek> days, Time time, boolean ignorePastFiresAtStart, boolean uiDefined)¶ Constructor.
Parameters: - motechEvent – the
MotechEvent
fired, when job triggers, not null - startDate – the
Date
at which job should become ACTIVE, not null - endDate – the
Date
at which job should be stopped, null treated as never end - days – the list of days at which job should be fired, not null
- time – the time at which job should be fired, not null
- ignorePastFiresAtStart – the flag defining whether job should ignore past fires at start or not
- uiDefined – the flag defining, whether job has been created through the UI
- motechEvent – the
EndingSchedulableJob¶
-
public abstract class
EndingSchedulableJob
extends SchedulableJob¶ Represents a job that can have an end date specified.
EventInfo¶
-
public class
EventInfo
¶ EventInfo is the class which contains information about event associated with scheduled job.
JobBasicInfo¶
-
public class
JobBasicInfo
¶ JobBasicInfo is the class which contains information about scheduled job and its current state.
Fields¶
Constructors¶
JobBasicInfo¶
-
public
JobBasicInfo
(String activity, String status, String name, String group, String startDate, String nextFireDate, String endDate, String jobType, String info, boolean uiDefined)¶ Constructor.
Parameters: - activity – the jobs activity (NONSTARTED, ACTIVE, FINISHED)
- status – the jobs status (ERROR, OK, PAUSED, BLOCKED)
- name – the jobs name
- startDate – the jobs start date
- nextFireDate – the jobs next fire date
- endDate – the jobs end date
- jobType – the type of job
- info – the information about job, different for each type of Job
Methods¶
JobDetailedInfo¶
-
public class
JobDetailedInfo
¶ JobDetailedInfo is the class which wraps the EventInfo list.
See also:
EventInfo
Constructors¶
JobId¶
-
public abstract class
JobId
implements Serializable¶ ID used to distinguish one job from others.
JobsSearchSettings¶
-
public class
JobsSearchSettings
¶ JobsSearchSettings
is the class used for passing search criteria to the Service Layer, it tells how theMotechSchedulerDatabaseService
should filter jobs information.See also:
org.motechproject.scheduler.service.MotechSchedulerDatabaseService
,org.motechproject.scheduler.web.controller.JobsController
Methods¶
MisfireSchedulableJob¶
-
public abstract class
MisfireSchedulableJob
extends EndingSchedulableJob¶ Represents a job that can use its original fire time after a misfire.
RepeatingJobId¶
Constructors¶
RepeatingJobId¶
RepeatingJobId¶
-
public
RepeatingJobId
(MotechEvent repeatingEvent)¶ Constructor.
Parameters: - repeatingEvent – the
MotechEvent
fired, when job is triggered
- repeatingEvent – the
RepeatingPeriodJobId¶
Constructors¶
RepeatingPeriodJobId¶
RepeatingPeriodJobId¶
-
public
RepeatingPeriodJobId
(MotechEvent repeatingEvent)¶ Constructor.
Parameters: - repeatingEvent – the
MotechEvent
fired, when job is triggered
- repeatingEvent – the
RepeatingPeriodSchedulableJob¶
-
public class
RepeatingPeriodSchedulableJob
extends MisfireSchedulableJob¶ Job that will be fired every
org.joda.time.Period
of time
Constructors¶
RepeatingPeriodSchedulableJob¶
-
public
RepeatingPeriodSchedulableJob
(MotechEvent motechEvent, DateTime startTime, DateTime endTime, Period repeatPeriod, boolean ignorePastFiresAtStart)¶ Constructor.
Parameters: - motechEvent – the
MotechEvent
which will be fired when the job triggers, not null - startTime – the
Date
at which job should become ACTIVE, not null - endTime – the
Date
at which job should be stopped, null treated as never end - repeatPeriod – the
Period
between job fires, not null - ignorePastFiresAtStart – the flag defining whether job should ignore past fires at start or not
- motechEvent – the
RepeatingPeriodSchedulableJob¶
-
public
RepeatingPeriodSchedulableJob
(MotechEvent motechEvent, DateTime startTime, DateTime endTime, Period repeatPeriod, boolean ignorePastFiresAtStart, boolean useOriginalFireTimeAfterMisfire, boolean uiDefined)¶ Constructor.
Parameters: - motechEvent – the
MotechEvent
which will be fired when the job triggers, not null - startTime – the
DateTime
at which job should become ACTIVE, not null - endTime – the
DateTime
at which job should be stopped, null treated as never end - repeatPeriod – the
Period
between job fires, not null - ignorePastFiresAtStart – the flag defining whether job should ignore past fires at start or not
- motechEvent – the
RepeatingSchedulableJob¶
-
public class
RepeatingSchedulableJob
extends MisfireSchedulableJob¶ Schedulable Job - a data carrier class for a scheduled job that can be fired set number of times
Constructors¶
RepeatingSchedulableJob¶
-
public
RepeatingSchedulableJob
()¶ Constructor. It will create a job, which will never end, won’t ignore past fires at start and will use original fire time after misfire. Start time,
MotechEvent
, repeat count and repeat interval are not assigned, which means that further usage, without setting them, can cause exceptions.
RepeatingSchedulableJob¶
-
public
RepeatingSchedulableJob
(MotechEvent motechEvent, Integer repeatCount, Integer repeatIntervalInSeconds, DateTime startTime, DateTime endTime, boolean ignorePastFiresAtStart)¶ Constructor.
Parameters: - motechEvent – the
MotechEvent
which will be fired when the job triggers, not null - repeatCount – the number of times job should be repeated, null treated as infinite
- repeatIntervalInSeconds – the interval(in seconds) between job fires
- startTime – the
DateTime
at which job should become ACTIVE, not null - endTime – the
DateTime
at which job should be stopped, null treated as never end - ignorePastFiresAtStart – the flag defining whether job should ignore past fires at start or not
- motechEvent – the
RepeatingSchedulableJob¶
-
public
RepeatingSchedulableJob
(MotechEvent motechEvent, Integer repeatIntervalInSeconds, DateTime startTime, DateTime endTime, boolean ignorePastFiresAtStart)¶ Constructor.
Parameters: - motechEvent – the
MotechEvent
which will be fired when the job triggers, not null - repeatIntervalInSeconds – the interval(in seconds) between job fires
- startTime – the
DateTime
at which job should become ACTIVE, not null - endTime – the
DateTime
at which job should be stopped, null treated as never end - ignorePastFiresAtStart – the flag defining whether job should ignore past fires at start or not
- motechEvent – the
RepeatingSchedulableJob¶
-
public
RepeatingSchedulableJob
(MotechEvent motechEvent, Integer repeatCount, Integer repeatIntervalInSeconds, DateTime startTime, DateTime endTime, boolean ignorePastFiresAtStart, boolean useOriginalFireTimeAfterMisfire, boolean uiDefined)¶ Constructor.
Parameters: - motechEvent – the
MotechEvent
which will be fired when the job triggers, not null - repeatCount – the number of times job should be repeated, null treated as infinite
- repeatIntervalInSeconds – the interval(in seconds) between job fires
- startTime – the
DateTime
at which job should become ACTIVE, not null - endTime – the
DateTime
at which job should be stopped, null treated as never end - ignorePastFiresAtStart – the flag defining whether job should ignore past fires at start or not
- motechEvent – the
Methods¶
setRepeatCount¶
-
public RepeatingSchedulableJob
setRepeatCount
(Integer repeatCount)¶
setRepeatIntervalInSeconds¶
-
public RepeatingSchedulableJob
setRepeatIntervalInSeconds
(Integer repeatIntervalInSeconds)¶
RunOnceJobId¶
Constructors¶
RunOnceJobId¶
RunOnceJobId¶
-
public
RunOnceJobId
(MotechEvent runOnceEvent)¶ Constructor.
Parameters: - runOnceEvent – the
MotechEvent
fired, when job is triggered
- runOnceEvent – the
RunOnceSchedulableJob¶
-
public final class
RunOnceSchedulableJob
extends SchedulableJob¶ Run Once Schedulable Job - a data carrier class for a job scheduled in the future that can be fired only once
This class is immutable
User: Igor (iopushnyev@2paths.com) Date: 16/02/11 Time: 1:43 PM
Constructors¶
RunOnceSchedulableJob¶
-
public
RunOnceSchedulableJob
(MotechEvent motechEvent, DateTime startDate)¶ Constructor
Parameters: - motechEvent –
- event data message that will be send by Motech Scheduler when this job is fired
- startDate –
- date and time when the job fill be fired
- motechEvent –
RunOnceSchedulableJob¶
-
public
RunOnceSchedulableJob
(MotechEvent motechEvent, DateTime startDate, boolean uiDefined)¶ Constructor
Parameters: - motechEvent –
- event data message that will be send by Motech Scheduler when this job is fired
- startDate –
- date and time when the job fill be fired
- uiDefined – the flag defining, whether job has been created through the UI
- motechEvent –
SchedulableJob¶
-
public abstract class
SchedulableJob
implements Serializable¶ Represents Job that can be scheduled
Constructors¶
SchedulableJob¶
-
protected
SchedulableJob
(MotechEvent motechEvent, DateTime startDate, boolean uiDefined, boolean ignorePastFiresAtStart)¶
Methods¶
equals¶
-
protected boolean
equals
(SchedulableJob other)¶
getMotechEvent¶
-
public MotechEvent
getMotechEvent
()¶
setIgnorePastFiresAtStart¶
-
public void
setIgnorePastFiresAtStart
(boolean ignorePastFiresAtStart)¶ Ignore past fires when start time of job is in past.
ex : repeating job with interval of 5 unit, and current time in between fire 2 and 3 will start triggering from 3rd firetime. 1 2 3 4 +-----+-----+-----+ start ^current time
Parameters: - ignorePastFiresAtStart – ignore past fires when start time of job is in past
setMotechEvent¶
-
public void
setMotechEvent
(MotechEvent motechEvent)¶
org.motechproject.scheduler.exception¶
CronExpressionException¶
-
public class
CronExpressionException
extends RuntimeException¶ Thrown when the given String is not a valid cron expression.
MotechSchedulerException¶
-
public class
MotechSchedulerException
extends RuntimeException¶ Thrown when error within MOTECH Scheduler occurs. Can be caused by updating non-existent job, job having invalid cron expression etc. User: Igor (iopushnyev@2paths.com) Date: 17/02/11 Time: 4:20 PM
MotechSchedulerJobRetrievalException¶
-
public class
MotechSchedulerJobRetrievalException
extends RuntimeException¶ Indicates an error when retrieving scheduled jobs from the database.
SchedulerInstantiationException¶
-
public class
SchedulerInstantiationException
extends RuntimeException¶ Thrown when scheduler can’t be instantiated.
SchedulerShutdownException¶
-
public class
SchedulerShutdownException
extends RuntimeException¶ The
SchedulerShutdownException
exception informs about that there were problems with shutdown scheduler.
org.motechproject.scheduler.factory¶
MotechSchedulerFactoryBean¶
-
public class
MotechSchedulerFactoryBean
¶ The
MotechSchedulerFactoryBean
is used to create scheduler and start it.
Constructors¶
MotechSchedulerFactoryBean¶
-
public
MotechSchedulerFactoryBean
(ApplicationContext applicationContext, Properties schedulerProperties)¶ Constructor.
Parameters: - applicationContext – the Spring context of the Scheduler module, not null
- schedulerProperties – the properties of scheduler, not null
org.motechproject.scheduler.service¶
MotechScheduledJob¶
-
public class
MotechScheduledJob
implements Job¶ Represents a MOTECH job scheduled with quartz. This class implements the
org.quartz.Job
interface - its execute method will be called when a MOTECH job in quartz triggers. Since jobs in MOTECH are basicallyorg.motechproject.event.MotechEvent
s getting published on a quartz schedule, upon execution this class retrieves theorg.motechproject.event.listener.EventRelay
from the application context and uses it to immediately publish the event scheduled with this job. For every execution a new copy of the event is constructed.
MotechScheduler¶
-
public final class
MotechScheduler
¶ ingroup scheduler
Main class that can bootstrap a Motech Scheduler
Author: Igor (iopushnyev@2paths.com)
MotechSchedulerActionProxyService¶
-
public interface
MotechSchedulerActionProxyService
¶ Proxy registered with the task channel, exposing the scheduler service as task actions.
Methods¶
scheduleCronJob¶
-
void
scheduleCronJob
(String subject, Map<Object, Object> parameters, String cronExpression, DateTime startTime, DateTime endTime, Boolean ignorePastFiresAtStart)¶ Schedules job, which will be fired on every match with given cron expression.
Parameters: - subject – the subject for
MotechEvent
fired, when job is triggered, not null - parameters – the parameters for
MotechEvent
, not null - cronExpression – the cron expression defining when job should be triggered, not null
- startTime – the
DateTime
at which should become ACTIVE, not null - endTime – the
DateTime
at which job should be stopped, null treated as never end. - ignorePastFiresAtStart – the flag defining whether job should ignore past fires at start or not, not null
- subject – the subject for
scheduleDayOfWeekJob¶
-
void
scheduleDayOfWeekJob
(String subject, Map<Object, Object> parameters, DateTime start, DateTime end, List<Object> days, DateTime time, Boolean ignorePastFiresAtStart)¶ Schedules job, which will be fired at given time on days of week provided by user.
Parameters: - subject – the subject for
MotechEvent
fired, when job is triggered, not null - parameters – the parameters for
MotechEvent
, not null - start – the
DateTime
at which should become ACTIVE, not null - end – the
DateTime
at which job should be stopped, null treated as never end - days – the list of days at which job should be fired, not null
- time – the
Time
at which job should be fired - ignorePastFiresAtStart – the flag defining whether job should ignore past fires at start or not, not null
- subject – the subject for
scheduleRepeatingJob¶
-
void
scheduleRepeatingJob
(String subject, Map<Object, Object> parameters, DateTime startTime, DateTime endTime, Integer repeatCount, Integer repeatIntervalInSeconds, Boolean ignorePastFiresAtStart, Boolean useOriginalFireTimeAfterMisfire)¶ Schedules job, which will be fired every user-specified time interval(in milliseconds), but won’t be fired more than given number of times.
Parameters: - subject – the subject for
MotechEvent
fired, when job is triggered, not null - parameters – the parameters for
MotechEvent
, not null - startTime – the
DateTime
at which should become ACTIVE, not null - endTime – the
DateTime
at which job should be stopped, null treated as never end - repeatCount – the number of time job should be triggered, -1 treated as infinite, not null
- repeatIntervalInSeconds – the interval(in seconds) between job fires, not null
- ignorePastFiresAtStart – the flag defining whether job should ignore past fires at start or not, not null
- useOriginalFireTimeAfterMisfire – the flag defining whether job should use original fire time after misfire, not null
- subject – the subject for
scheduleRepeatingPeriodJob¶
-
void
scheduleRepeatingPeriodJob
(String subject, Map<Object, Object> parameters, DateTime startTime, DateTime endTime, Period repeatPeriod, Boolean ignorePastFiresAtStart, Boolean useOriginalFireTimeAfterMisfire)¶ Schedules job, which will be fired every, user-specified period.
Parameters: - subject – the subject for
MotechEvent
fired, when job is triggered, not null - parameters – the parameters for
MotechEvent
, not null - startTime – the
DateTime
at which should become ACTIVE, not null - endTime – the
DateTime
at which job should be stopped, null treated as never end - repeatPeriod – the
Period
between job fires, not null - ignorePastFiresAtStart – the flag defining whether job should ignore past fires at start or not, not null
- useOriginalFireTimeAfterMisfire – the flag defining whether job should use original fire time after misfire
- subject – the subject for
scheduleRunOnceJob¶
-
void
scheduleRunOnceJob
(String subject, Map<Object, Object> parameters, DateTime startDate)¶ Schedules job, which will be fired only once at date given by user.
Parameters: - subject – the subject for
MotechEvent
fired, when job is triggered, not null - parameters – the parameters for
MotechEvent
, not null - startDate – the
DateTime
at which should become ACTIVE, not null
- subject – the subject for
MotechSchedulerDatabaseService¶
-
public interface
MotechSchedulerDatabaseService
¶ Service provides methods used to get data from Scheduler. Also provides pagination to use with jqGrid.
Methods¶
countJobs¶
-
int
countJobs
(JobsSearchSettings jobsSearchSettings)¶ Counts all triggers in TRIGGER table which matches the filters built from grid settings.
Parameters: - jobsSearchSettings – contains filter jobs information.
Throws: - MotechSchedulerJobRetrievalException – when the query fails.
Returns: number of all triggers which matches the filters built from grid settings.
getScheduledJobDetailedInfo¶
-
JobDetailedInfo
getScheduledJobDetailedInfo
(JobBasicInfo jobBasicInfo)¶ Returns detailed information about job matching given
JobBasicInfo
.Parameters: - jobBasicInfo – the
JobBasicInfo
about the job
Throws: - MotechSchedulerJobRetrievalException – when the query fails.
Returns: the detailed information about job
- jobBasicInfo – the
getScheduledJobsBasicInfo¶
-
List<JobBasicInfo>
getScheduledJobsBasicInfo
(JobsSearchSettings jobsSearchSettings)¶ Returns info about scheduled jobs for given filter information Sorts all jobs with ascending or descending order for given column.
Parameters: - jobsSearchSettings – contains filter, sorting and pagination jobs options.
Throws: - MotechSchedulerJobRetrievalException – when the query fails.
Returns: list with
org.motechproject.scheduler.contract.JobBasicInfo
for given sorting and pagination option
MotechSchedulerService¶
-
public interface
MotechSchedulerService
¶ ingroup scheduler Motech Scheduler Service Interface provides methods to schedule reschedule and unschedule a job Set a global policy that determines trigger fire behaviour for misfired triggers. For details see quartz documentations for misfire policy do_nothing -> @see CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING fire_once_now -> @see CronTrigger.MISFIRE_INSTRUCTION_FIRE_ONCE_NOW ignore -> @see CronTrigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY fire_now -> @see SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW ignore -> @see SimpleTrigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY reschedule_next_with_existing_count -> @see SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT reschedule_next_with_remaining_count -> @see SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT reschedule_now_with_existing_count -> @see SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT reschedule_now_with_remaining_count -> @see SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_REMAINING_REPEAT_COUNT
Author: Igor (iopushnyev@2paths.com) Date: 16/02/11
Methods¶
deleteJob¶
-
void
deleteJob
(JobBasicInfo info)¶ Deletes the job based on the given
info
.Parameters: - info – the information about a job
getJob¶
-
SchedulableJob
getJob
(JobBasicInfo jobInfo)¶ Retrieves a job based on the given information.
Parameters: - jobInfo – the information about a job
Returns: the job matching the given information
getNextFireDate¶
getPreviousFireDate¶
getScheduledJobTimings¶
-
List<DateTime>
getScheduledJobTimings
(String subject, String externalJobId, DateTime startDate, DateTime endDate)¶ Returns list of dates at which job will be triggered.
Parameters: - subject – the subject of job, not null
- externalJobId – the external ID of job, not null
- startDate – the
Date
after which dates should be added, not null - endDate – the
Date
before which dates should be added, not null
Returns: the list of dates, null if exception was thrown
getScheduledJobTimingsWithPrefix¶
-
List<DateTime>
getScheduledJobTimingsWithPrefix
(String subject, String externalJobIdPrefix, DateTime startDate, DateTime endDate)¶ Returns list of dates at which jobs will be triggered.
Parameters: - subject – the subject of job, not null
- externalJobIdPrefix – the prefix of jobs
- startDate – the
Date
after which dates should be added, not null - endDate – the
Date
before which dates should be added, not null
Returns: the list of dates
pauseJob¶
-
JobBasicInfo
pauseJob
(JobBasicInfo info)¶ Pauses the job based on the given
info
.Parameters: - info – the information about a job
Returns: the updated job
rescheduleJob¶
-
void
rescheduleJob
(String subject, String externalId, String cronExpression)¶ Reschedules a job with the given job ID to be fired according to the given Cron Expression Previous version of the configured Motech Scheduled Event that will be created when the job is fired remains as it was
Parameters: - subject – the subject of job, not null
- externalId – the external ID of job, not null
- cronExpression – cron expressions for job
resumeJob¶
-
JobBasicInfo
resumeJob
(JobBasicInfo info)¶ Resumes the job based on the given
info
.Parameters: - info – the information about a job
Returns: the updated job
safeScheduleJob¶
-
void
safeScheduleJob
(CronSchedulableJob cronSchedulableJob)¶ Same as scheduleJob, except that it would update existing job if one exists instead of creating a new one
Parameters: - cronSchedulableJob – a job that can be fired unlimited number of times
safeScheduleRepeatingJob¶
-
void
safeScheduleRepeatingJob
(RepeatingSchedulableJob repeatingSchedulableJob)¶ Same as safeScheduleRepeatingJob with intervening = true
Parameters: - repeatingSchedulableJob – a scheduled job that can be fired set number of times
safeScheduleRepeatingPeriodJob¶
-
void
safeScheduleRepeatingPeriodJob
(RepeatingPeriodSchedulableJob repeatingPeriodSchedulableJob)¶ Same as scheduleRepeatingPeriodJob, except that it would update existing job if one exists instead of creating a new one
Parameters: - repeatingPeriodSchedulableJob – a job that will be fired every
org.joda.time.Period
of time
- repeatingPeriodSchedulableJob – a job that will be fired every
safeScheduleRunOnceJob¶
-
void
safeScheduleRunOnceJob
(RunOnceSchedulableJob schedulableJob)¶ Same as scheduleRunOnceJob, except that it would update existing job if one exists instead of creating a new one
Parameters: - schedulableJob – ob scheduled in the future that can be fired only once
safeUnscheduleAllJobs¶
safeUnscheduleJob¶
safeUnscheduleRepeatingJob¶
safeUnscheduleRunOnceJob¶
scheduleDayOfWeekJob¶
-
void
scheduleDayOfWeekJob
(DayOfWeekSchedulableJob dayOfWeekSchedulableJob)¶ Same as safeScheduleDayOfWeekJob with intervening = true
Parameters: - dayOfWeekSchedulableJob – a job that is scheduled on particular days of week
scheduleJob¶
-
void
scheduleJob
(SchedulableJob job)¶ Schedules the given schedulable job.
Parameters: - job – the SchedulableJob
scheduleJob¶
-
void
scheduleJob
(CronSchedulableJob cronSchedulableJob)¶ Schedules the given cron schedulable job. The Job ID by which the job will be referencing in the future should be provided in an Instance of MotechEvent in SchedulableJob If a job with the same JobID as the given exists, this job will be unscheduled and the given schedulable job will be scheduled
Parameters: - cronSchedulableJob – a job that can be fired unlimited number of times
scheduleRepeatingJob¶
-
void
scheduleRepeatingJob
(RepeatingSchedulableJob repeatingSchedulableJob)¶ Schedules the given schedulable job. The Job ID by which the job will be referencing in the future should be provided in an Instance of MotechEvent in SchedulableJob (see JobID in MotechEvent parameters map ) If a job with the same job ID as the given exists, this job will be unscheduled and the given schedulable job will be scheduled
Parameters: - repeatingSchedulableJob – a scheduled job that can be fired set number of times
scheduleRepeatingPeriodJob¶
-
void
scheduleRepeatingPeriodJob
(RepeatingPeriodSchedulableJob repeatingPeriodSchedulableJob)¶ Same as scheduleRepeatingJob but schedules RepeatingPeriodSchedulableJob
Parameters: - repeatingPeriodSchedulableJob – a job that will be fired every
org.joda.time.Period
of time
- repeatingPeriodSchedulableJob – a job that will be fired every
scheduleRunOnceJob¶
-
void
scheduleRunOnceJob
(RunOnceSchedulableJob schedulableJob)¶ Schedules
RunOnceSchedulableJob
.Parameters: - schedulableJob – the
RunOnceSchedulableJob
to be scheduled, not null
- schedulableJob – the
unscheduleAllJobs¶
unscheduleJob¶
unscheduleJob¶
unscheduleRepeatingJob¶
unscheduleRunOnceJob¶
updateJob¶
-
void
updateJob
(SchedulableJob job)¶ Updates the job with jobID matching the key of the given JobID in MotechEvent.parameters map.
Parameters: - job – the updated job
org.motechproject.scheduler.tasks¶
DynamicChannelProviderRegisterer¶
-
public class
DynamicChannelProviderRegisterer
implements BundleTrackerCustomizer¶ Responsible for registering
SchedulerChannelProvider
service whenever Tasks module becomes available.
SchedulerChannelProvider¶
-
public class
SchedulerChannelProvider
implements DynamicChannelProvider¶ Scheduler module implementation of the
DynamicChannelProvider
interface.
Constructors¶
SchedulerChannelProvider¶
-
public
SchedulerChannelProvider
(Properties sqlProperties)¶
Methods¶
getTrigger¶
-
public TriggerEvent
getTrigger
(TaskTriggerInformation info)¶
getTriggers¶
-
public List<TriggerEvent>
getTriggers
(int page, int pageSize)¶
SchedulerEventParser¶
-
public class
SchedulerEventParser
implements TasksEventParser¶ Responsible for parsing subject of the Tasks triggers originating from the Scheduler module.
org.motechproject.security.authentication¶
MotechAccessVoter¶
-
public class
MotechAccessVoter
implements AccessDecisionVoter<Object>¶ A custom AccessDecisionVoter for voting on whether a specific user has access to a particular URL. For example, a security rule can specify that the users motech and admin have access to a particular URL. This loads the metadata source with attributes for ACCESS_motech and ACCESS_admin. When a user invokes that URL, an affirmative based voting system will check whether or not the user is motech or admin. If not, they are denied permission, otherwise they are granted access.
Methods¶
supports¶
-
public boolean
supports
(ConfigAttribute attribute)¶
vote¶
-
public int
vote
(Authentication authentication, Object object, Collection<ConfigAttribute> attributes)¶ Checks if given user has access to given URL. If authentication details are not instance of MotechUserProfile or ConfigAttributes are empty then return ACCESS_ABSTAIN. If attribute is supported but User is not allowed then return ACCESS_DENIED, otherwise return ACCESS_GRANTED
Parameters: - authentication – to be used for check
- object – the resource to which the access is being voted on
- attributes – that contains information about access for users
Returns: ACCESS_ABSTAIN, ACCESS_DENIED or ACCESS_GRANTED
MotechBasicAuthenticationEntryPoint¶
-
public class
MotechBasicAuthenticationEntryPoint
extends BasicAuthenticationEntryPoint¶ An entry point for BASIC authentications, sets the correct server realm key.
Constructors¶
MotechBasicAuthenticationEntryPoint¶
-
public
MotechBasicAuthenticationEntryPoint
(SettingsFacade settingsFacade)¶
MotechLoginErrorHandler¶
-
public class
MotechLoginErrorHandler
extends MotechLoginErrorJSONHandler¶ Class responsible for increasing user failure login counter. Extends
SimpleUrlAuthenticationFailureHandler
. It also redirect user to error login page.See also:
org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler
Constructors¶
Methods¶
onAuthenticationFailure¶
-
public void
onAuthenticationFailure
(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)¶
MotechLoginErrorJSONHandler¶
-
public class
MotechLoginErrorJSONHandler
extends ExceptionMappingAuthenticationFailureHandler¶ Class is responsible for checking login error responses, and returning a JSON response rather than a redirect if the response type is Ajax
Methods¶
onAuthenticationFailure¶
-
public void
onAuthenticationFailure
(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception)¶
MotechLoginSuccessHandler¶
-
public class
MotechLoginSuccessHandler
extends MotechLoginSuccessJSONHandler¶ Class responsible for logging info about users that log in and for resetting their failure login counter. Extends
SavedRequestAwareAuthenticationSuccessHandler
. It also serves as a fallback for storing sessions that started with the server before web-security was started.See also:
org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler
Methods¶
onAuthenticationSuccess¶
-
public void
onAuthenticationSuccess
(HttpServletRequest request, HttpServletResponse response, Authentication authentication)¶
MotechLoginSuccessJSONHandler¶
-
public class
MotechLoginSuccessJSONHandler
extends SavedRequestAwareAuthenticationSuccessHandler¶ Class is responsible for returning successful login attempts as JSON objects instead of a redirect if the request was Ajax
Methods¶
handle¶
-
protected void
handle
(HttpServletRequest request, HttpServletResponse response, Authentication authentication)¶
onAuthenticationSuccess¶
-
public void
onAuthenticationSuccess
(HttpServletRequest request, HttpServletResponse response, Authentication authentication)¶
MotechLoginUrlAuthenticationEntryPoint¶
-
public class
MotechLoginUrlAuthenticationEntryPoint
extends LoginUrlAuthenticationEntryPoint¶ Used to commence a form login authentication. Will redirect if the reqeust wasn’t an Ajax request.
Methods¶
commence¶
-
public void
commence
(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)¶ Performs the redirect (or forward) to the login form URL, unless the request is an Ajax request, where a 401 response will be returned.
MotechLogoutSuccessHandler¶
-
public class
MotechLogoutSuccessHandler
implements LogoutHandler¶ A logout handler for logging users that log out from MOTECH.
Methods¶
logout¶
-
public void
logout
(HttpServletRequest request, HttpServletResponse response, Authentication authentication)¶
MotechPasswordEncoder¶
-
public class
MotechPasswordEncoder
extends BCryptPasswordEncoder¶ Class responsible for password encoding
MotechRestBasicAuthenticationEntryPoint¶
-
public class
MotechRestBasicAuthenticationEntryPoint
extends BasicAuthenticationEntryPoint¶ A custom entry point that is invoked when there is an authentication exception within the filter. This ensures that when a user does not have login privileges and are unable to authenticate, a 401 unauthorized response is returned.
Constructors¶
MotechRestBasicAuthenticationEntryPoint¶
-
public
MotechRestBasicAuthenticationEntryPoint
(SettingsFacade settingsFacade)¶
Methods¶
commence¶
-
public void
commence
(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)¶
org.motechproject.security.constants¶
EmailConstants¶
-
public final class
EmailConstants
¶ Utility class for storing constants related to e-mails.
HTTPMethod¶
-
public enum
HTTPMethod
¶ Enumeration of HTTP request method.
Enum Constants¶
ANY¶
-
public static final HTTPMethod
ANY
¶
DELETE¶
-
public static final HTTPMethod
DELETE
¶
GET¶
-
public static final HTTPMethod
GET
¶
HEAD¶
-
public static final HTTPMethod
HEAD
¶
OPTIONS¶
-
public static final HTTPMethod
OPTIONS
¶
POST¶
-
public static final HTTPMethod
POST
¶
PUT¶
-
public static final HTTPMethod
PUT
¶
TRACE¶
-
public static final HTTPMethod
TRACE
¶
PermissionNames¶
-
public final class
PermissionNames
¶ Contains permission names constants
SecurityConfigConstants¶
-
public final class
SecurityConfigConstants
¶ A class for holding constants related to the options available for dynamic security rules. MotechURLSecurityRule is where these options are used. Prefixes related to security voting are also stored in this class.
org.motechproject.security.domain¶
MotechSecurityConfiguration¶
-
public class
MotechSecurityConfiguration
¶ The MotechSecurityConfiguration is a single document that contains all of the URL security rule configuration. The configuration was designed as one document because the entire filter chain must be reconstructed each time it is updated, therefore managing many references is unnecessary.
Constructors¶
MotechSecurityConfiguration¶
-
public
MotechSecurityConfiguration
(List<MotechURLSecurityRule> securityRules)¶
Methods¶
getSecurityRules¶
-
public List<MotechURLSecurityRule>
getSecurityRules
()¶
setSecurityRules¶
-
public void
setSecurityRules
(List<MotechURLSecurityRule> securityRules)¶
MotechURLSecurityRule¶
-
public class
MotechURLSecurityRule
¶ The MotechURLSecurityRule specifies the configuration for setting up a Spring SecurityFilterChain.
Details regarding configuration:
- pattern - URL pattern the security rule applies to
- supportedSchemes - Security rules that should apply to the URL, such as BASIC or OPEN_ID
- protocol - Protocol the security rule applies to, such as HTTP or HTTPS
- permissionAccess - Requires user has at least one of the listed permission to access the URL
- userAccess - User specific access for a URL, such as motech or admin, when combined with permission access they act as an either or (one must be true)
- priority - For future use in determining the ordering of filter chains, may be deprecated depending on UI implementation
- rest - Whether the endpoint is meant for a form login process or as an REST end-point that does not create a session for the
- origin - The module or user the rule originated from
- version - The version of the module or platform the rule was created
- methodsRequired - HTTP methods the rule applies to, if ANY is used then any method is matched, if a set is used, such as GET, POST, etc, then each will have its own corresponding filter chain with the same security found in that rule
Methods¶
getMethodsRequired¶
-
public List<HTTPMethod>
getMethodsRequired
()¶
setMethodsRequired¶
-
public void
setMethodsRequired
(List<HTTPMethod> methodsRequired)¶
MotechUser¶
-
public class
MotechUser
¶ Entity that represents Motech user
Constructors¶
Methods¶
getUserStatus¶
-
public UserStatus
getUserStatus
()¶
setUserStatus¶
-
public void
setUserStatus
(UserStatus userStatus)¶
MotechUserProfile¶
-
public class
MotechUserProfile
implements Serializable¶ Represents Motech user
Constructors¶
MotechUserProfile¶
-
public
MotechUserProfile
(MotechUser user)¶
Methods¶
getUserStatus¶
-
public UserStatus
getUserStatus
()¶
PasswordRecovery¶
-
public class
PasswordRecovery
¶ Entity that holds data used for password recovery
Methods¶
SecurityRuleComparator¶
-
public class
SecurityRuleComparator
implements Comparator<MotechURLSecurityRule>¶ Class that helps to compare
org.motechproject.security.domain.MotechURLSecurityRule
Methods¶
compare¶
-
public int
compare
(MotechURLSecurityRule o1, MotechURLSecurityRule o2)¶ Compares two MotechURLSecurityRules to select more important one (one with higher priority or one that comes from the system or one with longer pattern). First checks if both priorities are the same, if yes then checks for origin of both rules. If both of origins equals
org.motechproject.security.constants.SecurityConfigConstants.SYSTEM_ORIGIN
or if none of them then compares length of patterns from both rules. If origin of only one of the rules is equal then returns number that represents given rule. If priorities of both rules are not the same then just compares them.Parameters: - o1 – first rule
- o2 – second rule
Returns: number that represents one of the rules - will return 1 if first rule is more important or -1 if the second one
UserStatus¶
-
public enum
UserStatus
¶ Represents the user status.
Enum Constants¶
ACTIVE¶
-
public static final UserStatus
ACTIVE
¶ User is active.
BLOCKED¶
-
public static final UserStatus
BLOCKED
¶ User is blocked.
MUST_CHANGE_PASSWORD¶
-
public static final UserStatus
MUST_CHANGE_PASSWORD
¶ User is active but he must change the password.
org.motechproject.security.exception¶
EmailExistsException¶
-
public class
EmailExistsException
extends RuntimeException¶ Exception that signalizes that given email is already used by other user
InvalidTokenException¶
NonAdminUserException¶
PasswordTooShortException¶
-
public class
PasswordTooShortException
extends RuntimeException¶ Signals that password is shorter than the configured minimal length.
Constructors¶
PasswordValidatorException¶
-
public class
PasswordValidatorException
extends RuntimeException¶ Signals that the password didn’t pass validation.
RoleHasUserException¶
-
public class
RoleHasUserException
extends RuntimeException¶ Represents a failed attempt to delete a role currently assigned to a user.
SecurityConfigException¶
-
public class
SecurityConfigException
extends RuntimeException¶ A runtime exception thrown when the security config does not pass validation constraints required in order to construct a new security chain. Ideally should not be thrown as the UI should not allow invalid data to be submitted.
ServerUrlIsEmptyException¶
-
public class
ServerUrlIsEmptyException
extends RuntimeException¶ Exception which signalizes that server url property in platform settings is empty
UserNotFoundException¶
org.motechproject.security.mds¶
MotechPermissionsDataService¶
-
public interface
MotechPermissionsDataService
extends MotechDataService<MotechPermission>¶ Interface for data service injected by MDS
Methods¶
findByPermissionName¶
-
MotechPermission
findByPermissionName
(String permissionName)¶
MotechRolesDataService¶
-
public interface
MotechRolesDataService
extends MotechDataService<MotechRole>¶ Interface for data service injected by MDS
Methods¶
findByRoleName¶
-
MotechRole
findByRoleName
(String roleName)¶
MotechURLSecurityRuleDataService¶
-
public interface
MotechURLSecurityRuleDataService
extends MotechDataService<MotechURLSecurityRule>¶ Interface for data service injected by MDS
MotechUsersDataService¶
-
public interface
MotechUsersDataService
extends MotechDataService<MotechUser>¶ Interface for data service injected by MDS
Methods¶
findByEmail¶
-
MotechUser
findByEmail
(String email)¶
findByExternalId¶
-
List<MotechUser>
findByExternalId
(String externalId)¶
findByOpenId¶
-
MotechUser
findByOpenId
(String openId)¶
findByRole¶
-
List<MotechUser>
findByRole
(String role)¶
findByUserName¶
-
MotechUser
findByUserName
(String userName)¶
PasswordRecoveriesDataService¶
-
public interface
PasswordRecoveriesDataService
extends MotechDataService<PasswordRecovery>¶ Interface for data service injected by MDS
Methods¶
findForToken¶
-
PasswordRecovery
findForToken
(String token)¶
findForUser¶
-
PasswordRecovery
findForUser
(String username)¶
org.motechproject.security.model¶
PermissionDto¶
-
public class
PermissionDto
implements Serializable¶ The
PermissionDto
contains information about permission.
Constructors¶
PermissionDto¶
-
public
PermissionDto
(MotechPermission motechPermission)¶
Methods¶
RoleDto¶
-
public class
RoleDto
¶ Transfer Motech role data between representations.
Role data transfer object facilitates exchange of role data among services, repository, and client user interface.
Constructors¶
RoleDto¶
-
public
RoleDto
(MotechRole motechRole)¶
Methods¶
SecurityConfigDto¶
-
public class
SecurityConfigDto
¶ Used to transfer security configuration to and from a web request and UI
Methods¶
getSecurityRules¶
-
public List<SecurityRuleDto>
getSecurityRules
()¶
setSecurityRules¶
-
public void
setSecurityRules
(List<SecurityRuleDto> securityRules)¶
SecurityRuleDto¶
-
public class
SecurityRuleDto
¶ Transfer Motech security rule data between representations.
Methods¶
UserDto¶
-
public class
UserDto
¶ Transfers Motech user data between representations
Methods¶
getUserStatus¶
-
public UserStatus
getUserStatus
()¶
setUserStatus¶
-
public void
setUserStatus
(UserStatus userStatus)¶
org.motechproject.security.service¶
AuthoritiesService¶
-
public interface
AuthoritiesService
¶ Service interface to retrieve authorities (permissions) for a given
MotechUser
Methods¶
authoritiesFor¶
Gets list of
org.springframework.security.core.GrantedAuthority
for given userParameters: - user – for whom we want to get list
Returns: list that contains
org.springframework.security.core.GrantedAuthority
MotechPermissionService¶
-
public interface
MotechPermissionService
¶ Service for managing MOTECH permissions.
Methods¶
addPermission¶
-
void
addPermission
(PermissionDto permission)¶ Adds a new permission
Parameters: - permission – to be added
deletePermission¶
findPermissionByName¶
-
PermissionDto
findPermissionByName
(String name)¶ Finds permission by its name.
Parameters: - name – of the permission
Returns: permission of the given name
getPermissions¶
-
List<PermissionDto>
getPermissions
()¶ Gets list of all permissions
Returns: list that contains permissions
MotechProxyManager¶
-
public class
MotechProxyManager
¶ The MotechProxyManager acts as a wrapper around Spring’s FilterChainProxy. The FilterChainProxy contains a list of immutable SecurityFilterChain objects which Spring’s security consults for filters when handling requests. In order to dynamically define new secure, a new FilterChainProxy is constructed and the reference is updated. The MotechProxyManager acts as a customized delegate in MotechDelegatingFilterProxy.
Methods¶
getDefaultSecurityConfiguration¶
-
public MotechSecurityConfiguration
getDefaultSecurityConfiguration
()¶ This method reads default security configuration from the file containing security rules and returns it.
Returns: MotechSecurityConfiguration default security rules
getFilterChainProxy¶
-
public FilterChainProxy
getFilterChainProxy
()¶
initializeProxyChain¶
-
public void
initializeProxyChain
()¶ This method serves the same purpose of rebuildProxyChain, but does not require any kind of security authentication so it should only ever be used by the activator, which does not have an authentication object.
rebuildProxyChain¶
-
public synchronized void
rebuildProxyChain
()¶ Method to invoke to dynamically re-define the Spring security. All rules converted into security filter chains in order to create a new FilterChainProxy. The order of the rules in the list matters for filtering purposes.
setProxy¶
-
public void
setProxy
(FilterChainProxy proxy)¶
MotechRoleService¶
-
public interface
MotechRoleService
¶ Service for managing MOTECH roles
MotechURLSecurityService¶
-
public interface
MotechURLSecurityService
¶ Service to access and update security configuration details from the platform. Permission based, method level security is defined to prevent unauthorized users from updating security.
Methods¶
findAllSecurityRules¶
-
List<SecurityRuleDto>
findAllSecurityRules
()¶ A protected method for viewing security rule information for the platform.
Returns: All URL security rules found in the database
updateSecurityConfiguration¶
-
void
updateSecurityConfiguration
(SecurityConfigDto configuration)¶ A protected method for updating security configuration for the platform.
Parameters: - configuration – The updated security information, which will cause an updating of the motech proxy manager
MotechUserService¶
-
public interface
MotechUserService
¶ Service interface that defines APIs to retrieve and manage user details
Methods¶
activateUser¶
changeEmail¶
changeExpiredPassword¶
-
MotechUserProfile
changeExpiredPassword
(String userName, String oldPassword, String newPassword)¶ Changes password of user with given username when user status is ‘MUST_CHANGE_PASSWORD’ and return his
org.motechproject.security.domain.MotechUserProfile
. The new password and the old password cannot be the same. Blocks user after crossing the failure login counter.Parameters: - userName – of user
- oldPassword – password that was used before
- newPassword – new password for user
Throws: - org.springframework.security.authentication.LockedException – when user has been blocked
Returns: user profile after password change
changePassword¶
-
MotechUserProfile
changePassword
(String oldPassword, String newPassword)¶ Allows to change a password of a currently logged-in user.
Parameters: - oldPassword – An old password of currently logged user
- newPassword – A new password for the currently logged user
Returns: MotechUserProfile with updated user information
changePassword¶
-
MotechUserProfile
changePassword
(String userName, String oldPassword, String newPassword)¶ Changes password of user with given username and return his
org.motechproject.security.domain.MotechUserProfile
Parameters: - userName – of user
- oldPassword – password that was used before
- newPassword – new password for user
Returns: user profile after password change
getCurrentUser¶
getLocale¶
-
Locale
getLocale
(String userName)¶ Returns
java.util.Locale
of user with given nameParameters: - userName – of user
Returns: locale of user
getOpenIdUsers¶
-
List<MotechUserProfile>
getOpenIdUsers
()¶ Returns
org.motechproject.security.domain.MotechUserProfile
of users with set OpenIdReturns: list that contains users with OpenId
getRoles¶
getUser¶
getUserByEmail¶
getUsers¶
-
List<MotechUserProfile>
getUsers
()¶ Returns
org.motechproject.security.domain.MotechUserProfile
of all users.Returns: list that contains profiles of all users
hasActiveMotechAdmin¶
-
boolean
hasActiveMotechAdmin
()¶ Checks if there active user with Admin role
Returns: true if user exists, otherwise false
hasEmail¶
hasUser¶
register¶
-
void
register
(String username, String password, String email, String externalId, List<String> roles, Locale locale)¶ Registers new user
Parameters: - username – of new user
- password – of new user
- email – of new user
- externalId – of new user
- roles – list that contains roles for new user
- locale – to be set as default for new user
register¶
-
void
register
(String username, String password, String email, String externalId, List<String> roles, Locale locale, UserStatus userStatus, String openId)¶ Registers new user
Parameters: - username – of new user
- password – of new user
- email – of new user
- externalId – of new user
- roles – list that contains roles for new user
- locale – to be set as default for new user
- userStatus – user status,
org.motechproject.security.domain.UserStatus
- openId – of new user
registerMotechAdmin¶
-
void
registerMotechAdmin
(String username, String password, String email, Locale locale)¶ A method that allows to register the first MOTECH Admin in the application. Throws
java.lang.IllegalStateException
when an active Admin User is already registered.Parameters: - username – Username of a new user
- password – Password of a new user
- email – Email address of a new user
- locale – Selected locale for the new user
retrieveUserByCredentials¶
-
MotechUserProfile
retrieveUserByCredentials
(String username, String password)¶ Returns
org.motechproject.security.domain.MotechUserProfile
for user with given username and passwordParameters: - username – of user to be returned
- password – of user to be returned
Returns: profile of user with given credentials
sendLoginInformation¶
-
void
sendLoginInformation
(String userName)¶ Sends login information by email using address set for user with given name
Parameters: - userName – name of user
Throws: - UserNotFoundException – when user has not been found
- NonAdminUserException – when user is not an admin
setLocale¶
-
void
setLocale
(Locale locale)¶ Sets
org.motechproject.security.domain.MotechUserProfile
for user in current sessionParameters: - locale – to be set for user
updateUserDetailsWithPassword¶
updateUserDetailsWithoutPassword¶
validatePassword¶
-
void
validatePassword
(String password)¶ Checks whether the password meets requirements
Parameters: - password – the password to validate
Throws: - PasswordValidatorException – when password is not valid
PasswordRecoveryService¶
-
public interface
PasswordRecoveryService
¶ Service that defines APIs to manage password recovery
Methods¶
oneTimeTokenOpenId¶
-
String
oneTimeTokenOpenId
(String email)¶ Creates an one time token for OpenId for the user with the given email address and sends a recovery email
Parameters: - email – address of the user
Throws: - UserNotFoundException – when no user for the given email exists
- NonAdminUserException – when the user for the given email is not an admin (don’t have Admin role)
Returns: the recovery token that can be used for resetting the password
oneTimeTokenOpenId¶
-
String
oneTimeTokenOpenId
(String email, boolean notify)¶ Creates an one time token for OpenId for the user with the given email address, with an optional email notification.
Parameters: - email – address of the user
- notify – about the recovery
Throws: - UserNotFoundException – when no user with the given email exists
- NonAdminUserException – when the user for the given email is not an admin (don’t have Admin role)
Returns: the recovery token that can be used for resetting the password
oneTimeTokenOpenId¶
-
String
oneTimeTokenOpenId
(String email, DateTime expiration, boolean notify)¶ Creates an one time token for OpenId for the user with the given email address, with an optional email notification. The recovery will expire on the given date.
Parameters: - email – address of the user
- expiration – date of recovery, it shouldn’t be a past date
- notify – about the recovery
Throws: - UserNotFoundException – when no user with the given email exists
- NonAdminUserException – when the user for the given email is not an admin (don’t have Admin role)
Returns: the recovery token that can be used for resetting the password
passwordRecoveryRequest¶
-
String
passwordRecoveryRequest
(String email)¶ Creates password recovery for the user with the given email address and sends a recovery email
Parameters: - email – address of the user
Throws: - UserNotFoundException – when no user for the given email exists
Returns: the recovery token that can be used for resetting the password
passwordRecoveryRequest¶
-
String
passwordRecoveryRequest
(String email, boolean notify)¶ Creates password recovery for the user with the given email address, with an optional email notification.
Parameters: - email – address of the user
- notify – about the recovery
Throws: - UserNotFoundException – when no user for the given email exists
Returns: the recovery token that can be used for resetting the password
passwordRecoveryRequest¶
-
String
passwordRecoveryRequest
(String email, DateTime expiration)¶ Creates password recovery for the user with the given email address and sends a recovery email. The recovery will expire on the given date.
Parameters: - email – address of the user
- expiration – date of recovery, it shouldn’t be a past date
Throws: - UserNotFoundException – when no user for the given email exists
Returns: the recovery token that can be used for resetting the password
passwordRecoveryRequest¶
-
String
passwordRecoveryRequest
(String email, DateTime expiration, boolean notify)¶ Creates password recovery for the user with the given email address, with an optional email notification. The recovery will expire on the given date.
Parameters: - email – address of the user
- expiration – date of recovery, it shouldn’t be a past date
- notify – about the recovery
Throws: - UserNotFoundException – when no user for the given email exists
Returns: the recovery token that can be used for resetting the password
resetPassword¶
-
void
resetPassword
(String token, String password, String passwordConfirmation)¶ Sets new password for user from token
Parameters: - token – for
org.motechproject.security.domain.PasswordRecovery
- password – to be set for user
- passwordConfirmation – to check is password is correct
Throws: - InvalidTokenException – when
org.motechproject.security.domain.PasswordRecovery
as a null, recovery is already expired or when user for name from token doesn’t exists
- token – for
validateToken¶
-
boolean
validateToken
(String token)¶ Checks if there’s a not expired
org.motechproject.security.domain.PasswordRecovery
for given tokenParameters: - token – to validate
Returns: true if recovery exists, otherwise false
validateTokenAndLoginUser¶
-
void
validateTokenAndLoginUser
(String token, HttpServletRequest request, HttpServletResponse response)¶ Creates new openId Token for user from token as long as there’s a
org.motechproject.security.domain.PasswordRecovery
for that token and redirect to home page. If there’s no such recovery then redirect to login pageParameters: - token – for password recovery
- request – for session
- response – for session
Throws: - IOException – when response cannot redirect to given URL (home or login page)
SecurityRuleLoaderService¶
-
public interface
SecurityRuleLoaderService
¶ Service that scans an application context for security rules and re-initializes the MotechProxyManager security chain.
Methods¶
loadRules¶
-
void
loadRules
(ApplicationContext applicationContext)¶ Attempts to load rules from the application context, if rules are found, the security configuration is updated.
org.motechproject.security.validator¶
PasswordValidator¶
-
public interface
PasswordValidator
¶ Service interface that validates password
Methods¶
getName¶
getValidationError¶
-
String
getValidationError
(Locale locale)¶ Returns the error message for the validator. Should explain what is expected of the password. The message should be treated as a literal, meaning localization is left to the validator implementation.
Parameters: - locale – the locale for which the error message should be returned
Returns: the localized error message
validate¶
-
void
validate
(String password)¶ Validates password.
Parameters: - password – the password to check.
Throws: - org.motechproject.security.exception.PasswordValidatorException – signals an issue with the validation
org.motechproject.server.commons¶
org.motechproject.server.osgi.event¶
OsgiEventProxy¶
-
public interface
OsgiEventProxy
¶ This service allows sending Motech events without having a direct dependency on the event. This is achieved by sending OSGi events, which are then relayed as Motech events by the event module. This mechanism is used by MDS in order to avoid a dependency on the event module. In normal use, using this service should be avoided, as using the event system directly should be cleaner and more efficient.
Fields¶
Methods¶
broadcastEvent¶
-
void
broadcastEvent
(String subject, boolean proxyHandledEventInOSGi)¶ Calling this method will result in sending an OSGi event that will be then relayed by the event module as a Motech Event through the event topic - all Motech instances will receive the event. Note that broadcast events can be relayed as OSGi events upon being received - if that’s the case, their subject must conform to the rules for OSGi event topic (i.e. not contain dots).
Parameters: - subject – the subject of the event
- proxyHandledEventInOSGi – if true, the event will be also sent as an OSGi event upon being received by the event system
broadcastEvent¶
-
void
broadcastEvent
(String subject, Map<String, Object> parameters, boolean proxyHandledEventInOSGi)¶ Calling this method will result in sending an OSGi event that will be then relayed by the event module as a Motech Event through the event topic - all Motech instances will receive the event. Note that broadcast events can be relayed as OSGi events upon being received - if that’s the case, their subject must conform to the rules for OSGi event topic (i.e. not contain dots).
Parameters: - subject – the subject of the event
- parameters – the parameters map which will act as the payload of the event
- proxyHandledEventInOSGi – if true, the event will be also sent as an OSGi event upon being received by the event system
sendEvent¶
sendEvent¶
-
void
sendEvent
(String subject, Map<String, Object> parameters)¶ Calling this method will result in sending an OSGi event that will be then relayed by the event module as a Motech Event through the event queue - only one Motech instance will receive the event.
Parameters: - subject – the subject of the event
- parameters – the parameters map which will act as the payload of the event
org.motechproject.server.osgi.status¶
PlatformStatus¶
-
public class
PlatformStatus
implements Serializable¶ Represents the status of the platform startup. It contains information about which bundles were started by Gemini Blueprint, it also carries information about both OSGi level and Spring context level errors that occurred in the system.
Methods¶
errorsOccurred¶
-
public boolean
errorsOccurred
()¶ Returns true if we faced any errors context/bundle. This doesn’t necessarily mean a startup failure.
Returns: true if errors occurred, false otherwise
getBundleErrorsByBundle¶
-
public Map<String, String>
getBundleErrorsByBundle
()¶ Returns bundles errors that occurred in the system in a form of a map. The keys in the map are bundle symbolic names. The values are error messages. Bundle errors are errors that occurred on the OSGi level, and prevented the bundle itself from starting.
Returns: bundle errors that occurred in the system
getContextErrorsByBundle¶
-
public Map<String, String>
getContextErrorsByBundle
()¶ Returns context errors that occurred in the system in a form of a map. The keys in the map are bundle symbolic names. The values are error messages. Context errors are errors that occurred during the creation of the Blueprint context.
Returns: context errors that occurred in the system
getOsgiStartedBundles¶
getStartedBundles¶
getStartupProgressPercentage¶
-
public int
getStartupProgressPercentage
()¶ Returns the startup progress in percent. The startup progress represents the number of started bundles in relation to the number of bundles that is required for the server to be fully started. This is capped at 100%.
Returns: the startup progress in percent
inFatalError¶
-
public boolean
inFatalError
()¶ Returns true if we faced a fatal error during startup, meaning a platform bundle failed to start. This means a startup failure.
Returns: true if we occurred such an error, false otherwise
setBundleErrorsByBundle¶
-
public void
setBundleErrorsByBundle
(Map<String, String> bundleErrorsByBundle)¶ Sets the bundles errors that occurred in the system in a form of a map. The keys in the map are bundle symbolic names. The values are error messages. Bundle errors are errors that occurred on the OSGi level, and prevented the bundle itself from starting. Failed bundles will be removed from the started bundle list.
Parameters: - bundleErrorsByBundle – bundle errors that occurred in the system
setContextErrorsByBundle¶
-
public void
setContextErrorsByBundle
(Map<String, String> contextErrorsByBundle)¶ Sets the context errors that occurred in the system in a form of a map. The keys in the map are bundle symbolic names. The values are error messages. Context errors are errors that occurred during the creation of the Blueprint context. Failed bundles will be removed from the started bundle list.
Parameters: - contextErrorsByBundle – context errors that occurred in the system
setOsgiStartedBundles¶
setStartedBundles¶
PlatformStatusManager¶
-
public interface
PlatformStatusManager
¶ This is an interface for the manager of the platform status. The manager should keep track of the status and return it to callers.
Methods¶
getCurrentStatus¶
-
PlatformStatus
getCurrentStatus
()¶ Used to fetch the current status of the platform.
Returns: the current status of the platform, never null
PlatformStatusManagerImpl¶
-
public class
PlatformStatusManagerImpl
implements PlatformStatusManager, OsgiBundleApplicationContextListener, BundleListener¶ PlatformStatusManager implementation. Acts as an listener for Blueprint events to get notified about modules being started or failing. It also exposes a method used by PlatformActivator for notifying about OSGi (not blueprint) bundle errors. It also acts as an OSGi event listener for keeping track of bundles that were started by OSGi (includes all bundles in the system). It keeps a single platform status instance, that it keeps updating.
Constructors¶
Methods¶
bundleChanged¶
-
public void
bundleChanged
(BundleEvent bundleEvent)¶
getCurrentStatus¶
-
public PlatformStatus
getCurrentStatus
()¶
onOsgiApplicationEvent¶
-
public void
onOsgiApplicationEvent
(OsgiBundleApplicationContextEvent event)¶
registerBundleError¶
setOsgiEventProxy¶
-
public void
setOsgiEventProxy
(OsgiEventProxy osgiEventProxy)¶
org.motechproject.server.osgi.util¶
BundleType¶
-
public enum
BundleType
¶ Represents a logical bundle type. Used for determining startup order.
Enum Constants¶
FRAGMENT_BUNDLE¶
-
public static final BundleType
FRAGMENT_BUNDLE
¶ A fragment bundle, this should not be started(per OSGi spec), they attach themselves to the host.
FRAMEWORK_BUNDLE¶
-
public static final BundleType
FRAMEWORK_BUNDLE
¶ The OSGi framework bundle
HTTP_BUNDLE¶
-
public static final BundleType
HTTP_BUNDLE
¶ The HTTP bridge bundle, required for HTTP access to MOTECH.
MDS_BUNDLE¶
-
public static final BundleType
MDS_BUNDLE
¶ The Motech DataServices bundle. Required special treatment due to its nature of changing class definitions on the fly.
MOTECH_MODULE¶
-
public static final BundleType
MOTECH_MODULE
¶ A regular Motech module, starts after the platform.
PLATFORM_BUNDLE_POST_WS¶
-
public static final BundleType
PLATFORM_BUNDLE_POST_WS
¶ All platform bundles not included in the other platform bundle types.
PLATFORM_BUNDLE_PRE_MDS¶
-
public static final BundleType
PLATFORM_BUNDLE_PRE_MDS
¶ Bundles that MDS depends on - commons bundles, osgi-web-util, server-api and config-core.
PLATFORM_BUNDLE_PRE_WS¶
-
public static final BundleType
PLATFORM_BUNDLE_PRE_WS
¶ Bundles required for Web-security to start. These are event and server-config.
THIRD_PARTY_BUNDLE¶
-
public static final BundleType
THIRD_PARTY_BUNDLE
¶ This a 3rd party bundle, a library.
WS_BUNDLE¶
-
public static final BundleType
WS_BUNDLE
¶ The web-security bundle. Gets special treatment due to its crucial nature.
PlatformConstants¶
-
public final class
PlatformConstants
¶ Collection of constants related to the Platform startup and bundle management.
Fields¶
ValidationWeavingHook¶
-
public class
ValidationWeavingHook
implements WeavingHook¶ This weaving hook is in charge of making sure that the META-INF.services package is imported by bundles. The reason for this is the introduction of support for javax.validation in Spring 3.2. Because of this each module that used Spring MVC would have to contain/import a META-INF services file that would define the validation provider. This hook was introduced in order to allow compatibility with old bundles
Methods¶
weave¶
-
public void
weave
(WovenClass wovenClass)¶
org.motechproject.server.service¶
org.motechproject.server.startup¶
MotechPlatformState¶
-
public enum
MotechPlatformState
¶ Defines the different states of the MOTECH system.
Enum Constants¶
DB_ERROR¶
-
public static final MotechPlatformState
DB_ERROR
¶
FIRST_RUN¶
-
public static final MotechPlatformState
FIRST_RUN
¶
NEED_BOOTSTRAP_CONFIG¶
-
public static final MotechPlatformState
NEED_BOOTSTRAP_CONFIG
¶
NEED_CONFIG¶
-
public static final MotechPlatformState
NEED_CONFIG
¶
NORMAL_RUN¶
-
public static final MotechPlatformState
NORMAL_RUN
¶
NO_DB¶
-
public static final MotechPlatformState
NO_DB
¶
STARTUP¶
-
public static final MotechPlatformState
STARTUP
¶
StartupManager¶
-
public class
StartupManager
¶ StartupManager controlling and managing the application loading
Methods¶
getDefaultSettings¶
-
public MotechSettings
getDefaultSettings
()¶ This function is only called when the default configuration is loaded and is no config in the database or external files
org.motechproject.server.ui.ex¶
org.motechproject.server.web.controller¶
AvailabilityController¶
-
public class
AvailabilityController
¶ Controller class responsible for determining available UI tabs for modules where UI tabs availability depends on different user permissions.
DashboardController¶
-
public class
DashboardController
¶ Main application controller. Responsible for retrieving information shared across the UI of different modules. The view returned by this controller will embed the UI of the currently requested module.
Methods¶
accessdenied¶
-
public ModelAndView
accessdenied
(HttpServletRequest request)¶
getUser¶
-
public UserInfo
getUser
(HttpServletRequest request)¶
index¶
-
public ModelAndView
index
(HttpServletRequest request)¶
setEventConsumerInfo¶
-
public void
setEventConsumerInfo
(EventConsumerInfo eventConsumerInfo)¶
setLocaleService¶
-
public void
setLocaleService
(LocaleService localeService)¶
setStartupManager¶
-
public void
setStartupManager
(StartupManager startupManager)¶
ForgotController¶
-
public class
ForgotController
¶ Forgot Controller for reset password.
Methods¶
getForgotViewData¶
-
public ForgotViewData
getForgotViewData
(HttpServletRequest request)¶
login¶
-
public ModelAndView
login
(HttpServletRequest request)¶
LocaleController¶
-
public class
LocaleController
¶ The
LocaleController
class is responsible for handling requests connected with internationalization
Methods¶
getSupportedLanguages¶
-
public NavigableMap<String, String>
getSupportedLanguages
()¶
getUserLang¶
-
public String
getUserLang
(HttpServletRequest request)¶
setSessionLang¶
-
public void
setSessionLang
(HttpServletRequest request, HttpServletResponse response, LocaleDto localeDto)¶
setUserLang¶
-
public void
setUserLang
(HttpServletRequest request, HttpServletResponse response, LocaleDto localeDto)¶
LoginController¶
-
public class
LoginController
¶ Login Controller for user authentication.
Methods¶
getLoginViewData¶
-
public LoginViewData
getLoginViewData
(HttpServletRequest request)¶
login¶
-
public ModelAndView
login
(HttpServletResponse response)¶
ModuleController¶
-
public class
ModuleController
¶
Methods¶
getBundleIcon¶
-
public void
getBundleIcon
(Long bundleId, String bundleName, String defaultIcon, HttpServletResponse response)¶ Returns the icon associated with the given bundle. Bundles that do not have their own icons will get a default icon.
Parameters: - bundleId – the id of the bundle for which the icon should be retrieved
- bundleName – the name of the bundle for which the icon should be retrieved
- defaultIcon – the name of the default icon which be provided if any standard icon couldn’t be searched
- response – the HttpServletResponse, used for writing the icon in its output
Throws: - IOException – if there were failures writing the icon to the output
getRestDocsUrl¶
getUser¶
-
public UserInfo
getUser
(HttpServletRequest request)¶
setBundleContext¶
-
public void
setBundleContext
(BundleContext bundleContext)¶
setLocaleService¶
-
public void
setLocaleService
(LocaleService localeService)¶
setUiFrameworkService¶
-
public void
setUiFrameworkService
(UIFrameworkService uiFrameworkService)¶
ResetController¶
-
public class
ResetController
¶ Controller for resetting and changing user password.
Methods¶
changePassword¶
-
public ChangePasswordViewData
changePassword
(ChangePasswordForm form)¶
changePasswordView¶
-
public ModelAndView
changePasswordView
(HttpServletRequest request)¶
getResetViewData¶
-
public ResetViewData
getResetViewData
(HttpServletRequest request)¶
reset¶
-
public ResetViewData
reset
(ResetForm form, HttpServletRequest request)¶
resetView¶
-
public ModelAndView
resetView
(HttpServletRequest request)¶
StartupController¶
-
public class
StartupController
¶ StartupController that manages the platform system start up and captures the platform core settings and user information.
Methods¶
getStartupViewData¶
-
public StartupViewData
getStartupViewData
(HttpServletRequest request)¶
setStartupFormValidatorFactory¶
-
public void
setStartupFormValidatorFactory
(StartupFormValidatorFactory validatorFactory)¶
startup¶
-
public ModelAndView
startup
()¶
submitForm¶
-
public List<String>
submitForm
(StartupForm startupSettings)¶
org.motechproject.server.web.form¶
ChangePasswordForm¶
-
public class
ChangePasswordForm
¶ Represents data from the change password form from the UI.
org.motechproject.server.web.helper¶
org.motechproject.server.web.validator¶
AbstractValidator¶
-
public interface
AbstractValidator
¶ Basic interface which startup settings validators implement
Methods¶
validate¶
-
void
validate
(StartupForm target, List<String> errors, ConfigSource configSource)¶
ChangePasswordFormValidator¶
-
public class
ChangePasswordFormValidator
¶ Validates the change password form.
OpenIdUserValidator¶
-
public class
OpenIdUserValidator
implements AbstractValidator¶ Validates presence of OpenId related field values Also validates provider URL
Constructors¶
OpenIdUserValidator¶
-
public
OpenIdUserValidator
(UrlValidator urlValidator)¶
Methods¶
validate¶
-
public void
validate
(StartupForm target, List<String> errors, ConfigSource configSource)¶
PersistedUserValidator¶
-
public class
PersistedUserValidator
implements AbstractValidator¶ Validates presence of admin registration fields. Checks existence of user with identical name Checks existence of user with identical email Checks that password and confirmed password field are same.
Constructors¶
PersistedUserValidator¶
-
public
PersistedUserValidator
(MotechUserService userService)¶
Methods¶
validate¶
-
public void
validate
(StartupForm target, List<String> errors, ConfigSource configSource)¶
RequiredFieldValidator¶
-
public class
RequiredFieldValidator
implements AbstractValidator¶ Generic validator class that validates presence of a given field
Constructors¶
StartupFormValidator¶
-
public class
StartupFormValidator
¶ StartupFormValidator validates user information during registration process
Methods¶
add¶
-
public void
add
(AbstractValidator validator)¶
getValidators¶
-
public List<AbstractValidator>
getValidators
()¶
validate¶
-
public List<String>
validate
(StartupForm target, ConfigSource configSource)¶
StartupFormValidatorFactory¶
-
public class
StartupFormValidatorFactory
¶ Factory to create startUpFormValidator with requisite validators. If Admin User exists,the admin user is not created so the relevant validators are not added.
Methods¶
getStartupFormValidator¶
-
public StartupFormValidator
getStartupFormValidator
(StartupForm startupSettings, MotechUserService userService)¶
UserRegistrationValidator¶
-
public class
UserRegistrationValidator
implements AbstractValidator¶ Validator to validate user registration details. Delegates to either @OpenIdUserValidator or @UserRegistrationValidator depending on login mode preference.
Constructors¶
UserRegistrationValidator¶
-
public
UserRegistrationValidator
(PersistedUserValidator persistedUserValidator, OpenIdUserValidator openIdUserValidator)¶
Methods¶
validate¶
-
public void
validate
(StartupForm target, List<String> errors, ConfigSource configSource)¶
org.motechproject.tasks.annotations¶
TaskAction¶
-
public @interface
TaskAction
¶ Marks methods that should be treated as task actions. Methods marked with this annotation must be placed in a class annotated with
@TaskChannel
annotation.
TaskActionParam¶
-
public @interface
TaskActionParam
¶ Marks method parameter to be treated as action parameter.
Each parameter in the given method has to have this annotation otherwise it will be a problem with the proper execution of the channel action.
See also:
TaskAction
,TaskChannel
TaskChannel¶
-
public @interface
TaskChannel
¶ Marks classes destined to represent module task channels. Methods annotated with
@TaskAction
annotation should be placed in class annotated with this annotation.
TaskPostActionParam¶
-
public @interface
TaskPostActionParam
¶ Marks method parameter to be treated as post action parameter.
Each parameter in the given method has to have this annotation otherwise it will be a problem with the proper execution of the channel action.
See also:
TaskAction
,TaskChannel
org.motechproject.tasks.contract¶
ActionEventRequest¶
-
public class
ActionEventRequest
¶ Service layer object denoting a
ActionEvent
. It is a part of theorg.motechproject.tasks.contract.ChannelRequest
and is used byorg.motechproject.tasks.service.ChannelService
for adding new or updating already existent action events.
Constructors¶
ActionEventRequest¶
ActionEventRequest¶
-
public
ActionEventRequest
(String name, String displayName, String subject, String description, String serviceInterface, String serviceMethod, String serviceMethodCallManner, SortedSet<ActionParameterRequest> actionParameters, SortedSet<ActionParameterRequest> postActionParameters)¶ Constructor.
Parameters: - name – the event name
- displayName – the event display name
- subject – the event subject
- description – the event description
- serviceInterface – the event service interface
- serviceMethod – the event service method
- serviceMethodCallManner – the event service method call manner, for supported values check {@see org.motechproject.tasks.domain.enums.MethodCallManner}
- actionParameters – the action parameters
Methods¶
addParameter¶
-
public void
addParameter
(ActionParameterRequest parameter, boolean changeOrder)¶ Adds the given parameter request to the list of stored parameter requests.
Parameters: - parameter – the action parameter request
- changeOrder – defines if order of the given parameter should continue numeration of the stored list
addPostActionParameter¶
-
public void
addPostActionParameter
(ActionParameterRequest parameter, boolean changeOrder)¶ Adds the given parameter request to the list of stored post action parameter requests.
Parameters: - parameter – the post action parameter request
- changeOrder – defines if order of the given parameter should continue numeration of the stored list
getActionParameters¶
-
public SortedSet<ActionParameterRequest>
getActionParameters
()¶ Returns the action parameters.
Returns: the action parameters
getDescription¶
getDisplayName¶
getName¶
getPostActionParameters¶
-
public SortedSet<ActionParameterRequest>
getPostActionParameters
()¶ Returns the post action parameters.
Returns: the post action parameters
getServiceInterface¶
getServiceMethod¶
getServiceMethodCallManner¶
getSubject¶
hasService¶
-
public boolean
hasService
()¶ Checks if this action event request has service interface and method specified.
Returns: true if action has service interface and method specified, false otherwise
hasSubject¶
-
public boolean
hasSubject
()¶ Checks if this action event request has subject.
Returns: true if action event has subject, false otherwise
ActionParameterRequest¶
-
public class
ActionParameterRequest
implements Comparable<ActionParameterRequest>¶ Object representation of a parameter in the channel action request definition.
See also:
ActionEventRequest
Constructors¶
ActionParameterRequest¶
-
public
ActionParameterRequest
(Integer order, String key, String value, String displayName, String type, boolean required, boolean hidden, SortedSet<String> options)¶ Constructor.
Parameters: - order – the parameter order
- key – the parameter key
- value – the parameter value
- displayName – the parameter display name
- type – the parameter type
- required – defines if the parameter is required
- hidden – defines if the parameter is hidden on the UI
- options – the parameter options for select parameter type
Methods¶
compareTo¶
-
public int
compareTo
(ActionParameterRequest o)¶
getDisplayName¶
getOptions¶
getOrder¶
isRequired¶
-
public boolean
isRequired
()¶ Returns whether this action parameter is required.
Returns: true if this action parameter is required, false otherwise
setOptions¶
ChannelRequest¶
-
public class
ChannelRequest
¶ Service layer object denoting a
Channel
. Used byorg.motechproject.tasks.service.ChannelService
. It is used for registering new and updating already existent channels.
Constructors¶
ChannelRequest¶
-
public
ChannelRequest
(String displayName, String moduleName, String moduleVersion, String description, List<TriggerEventRequest> triggerTaskEvents, List<ActionEventRequest> actionTaskEvents)¶ Constructor.
Parameters: - displayName – the channel display name
- moduleName – the module symbolic name
- moduleVersion – the module version
- description – the channel description
- triggerTaskEvents – the triggers definitions
- actionTaskEvents – the actions definitions
Methods¶
getActionTaskEvents¶
-
public List<ActionEventRequest>
getActionTaskEvents
()¶ Returns the task action events for this channel.
Returns: the task action events
getDescription¶
getDisplayName¶
getModuleName¶
getModuleVersion¶
getTriggerTaskEvents¶
-
public List<TriggerEventRequest>
getTriggerTaskEvents
()¶ Returns the task trigger events for this channel.
Returns: the task trigger events
setModuleName¶
setModuleVersion¶
EventParameterRequest¶
-
public class
EventParameterRequest
¶ Service layer object denoting a
EventParameter
. It is a part of theorg.motechproject.tasks.contract.TriggerEventRequest
and is used byorg.motechproject.tasks.service.ChannelService
for adding new or updating already existent trigger event parameters.
TriggerEventRequest¶
-
public class
TriggerEventRequest
¶ Service layer object denoting a
TriggerEvent
. It is a part of theorg.motechproject.tasks.contract.ChannelRequest
and is used byorg.motechproject.tasks.service.ChannelService
for adding new or updating already existent trigger events.
Constructors¶
TriggerEventRequest¶
-
public
TriggerEventRequest
(String displayName, String subject, String description, List<EventParameterRequest> eventParameters)¶ Constructor. The given subject will be used as the actual subject the listener will listen for.
Parameters: - displayName – the trigger event display name
- subject – the event subject
- description – the event description
- eventParameters – the trigger event parameters
TriggerEventRequest¶
-
public
TriggerEventRequest
(String displayName, String subject, String description, List<EventParameterRequest> eventParameters, String triggerListenerSubject)¶ Constructor. The given
triggerListenerSubject
will be used as the actual subject the listener will listen for. If it is not specified subject will be used instead.Parameters: - displayName – the trigger event display name
- subject – the event subject
- description – the event description
- eventParameters – the trigger event parameters
- triggerListenerSubject – the listener event subject
org.motechproject.tasks.contract.builder¶
ActionEventRequestBuilder¶
-
public class
ActionEventRequestBuilder
¶ The
ActionEventRequestBuilder
class provides methods for constructing action event requests.See also:
org.motechproject.tasks.contract.ActionEventRequest
Methods¶
createActionEventRequest¶
-
public ActionEventRequest
createActionEventRequest
()¶ Builds an object of the
ActionEventRequest
class.Returns: the created instance
setActionParameters¶
-
public ActionEventRequestBuilder
setActionParameters
(SortedSet<ActionParameterRequest> actionParameters)¶ Sets the parameters of the action event to be built.
Parameters: - actionParameters – the action event parameter
Returns: the reference to this object
setDescription¶
-
public ActionEventRequestBuilder
setDescription
(String description)¶ Sets the description of the action event to be built.
Parameters: - description – the action event description
Returns: the reference to this object
setDisplayName¶
-
public ActionEventRequestBuilder
setDisplayName
(String displayName)¶ Sets the display name of the action event to be built.
Parameters: - displayName – the action event display name
Returns: the reference to this object
setName¶
-
public ActionEventRequestBuilder
setName
(String name)¶ Sets the name of the action event to be built.
Parameters: - name – the action event name
Returns: the reference to this object
setPostActionParameters¶
-
public ActionEventRequestBuilder
setPostActionParameters
(SortedSet<ActionParameterRequest> postActionParameters)¶ Sets the post action parameters of the action event to be built.
Parameters: - postActionParameters – the post action event parameter
Returns: the reference to this object
setServiceInterface¶
-
public ActionEventRequestBuilder
setServiceInterface
(String serviceInterface)¶ Sets the service interface of the action event to be built.
Parameters: - serviceInterface – the action event service interface
Returns: the reference to this object
setServiceMethod¶
-
public ActionEventRequestBuilder
setServiceMethod
(String serviceMethod)¶ Sets the service method of the action event to be built.
Parameters: - serviceMethod – the action event service method
Returns: the reference to this object
setServiceMethodCallManner¶
-
public ActionEventRequestBuilder
setServiceMethodCallManner
(String serviceMethodCallManner)¶ Sets the service method call manner of the action event to be built.
Parameters: - serviceMethodCallManner – the action event service method call manner, for supported values see {@see org.motechproject.tasks.domain.enums.MethodCallManner}
Returns: the reference to this object
setSubject¶
-
public ActionEventRequestBuilder
setSubject
(String subject)¶ Sets the subject of the action event to be built.
Parameters: - subject – the action event subject
Returns: the reference to this object
ActionParameterRequestBuilder¶
-
public class
ActionParameterRequestBuilder
¶ The
ActionParameterRequestBuilder
class provides methods for constructing action parameter requests.See also:
org.motechproject.tasks.contract.ActionParameterRequest
Methods¶
createActionParameterRequest¶
-
public ActionParameterRequest
createActionParameterRequest
()¶ Builds an object of the
ActionParameterRequest
class.Returns: the created instance
setDisplayName¶
-
public ActionParameterRequestBuilder
setDisplayName
(String displayName)¶ Sets the display name of the action parameter to build the request for.
Parameters: - displayName – the action parameter display name
Returns: the reference to this object
setKey¶
-
public ActionParameterRequestBuilder
setKey
(String key)¶ Sets the key of the action parameter to build the request for.
Parameters: - key – the action parameter key
Returns: the reference to this object
setOptions¶
-
public ActionParameterRequestBuilder
setOptions
(SortedSet<String> options)¶ Sets the options of the action parameter to build the request for.
Parameters: - options – the action parameter options
Returns: the reference to this object
setOrder¶
-
public ActionParameterRequestBuilder
setOrder
(Integer order)¶ Sets the order of the action parameter to build the request for.
Parameters: - order – the action parameter order
Returns: the reference to this object
setRequired¶
-
public ActionParameterRequestBuilder
setRequired
(boolean required)¶ Defines whether the action parameter, that request will be build for, should be required.
Parameters: - required – defines if the action parameter should be required
Returns: the reference to this object
setType¶
-
public ActionParameterRequestBuilder
setType
(String type)¶ Sets the type of the action parameter to build the request for.
Parameters: - type – the action parameter type
Returns: the reference to this object
setValue¶
-
public ActionParameterRequestBuilder
setValue
(String value)¶ Sets the value of the action parameter to build the request for.
Parameters: - value – the action parameter value
Returns: the reference to this object
org.motechproject.tasks.contract.json¶
ActionEventRequestDeserializer¶
-
public class
ActionEventRequestDeserializer
implements JsonDeserializer<ActionEventRequest>¶ JsonDeserializer
for theActionEventRequest
class.
Fields¶
Methods¶
deserialize¶
-
public ActionEventRequest
deserialize
(JsonElement element, Type type, JsonDeserializationContext context)¶
org.motechproject.tasks.domain¶
ChannelRegisterEvent¶
-
public class
ChannelRegisterEvent
¶ A wrapper over a
MotechEvent
with subject {@value EventSubjects#CHANNEL_REGISTER_SUBJECT}. Raised when a channel is registered with the tasks module
Constructors¶
ChannelRegisterEvent¶
ChannelRegisterEvent¶
-
public
ChannelRegisterEvent
(MotechEvent motechEvent)¶ Constructor.
Parameters: - motechEvent – the motech event
KeyInformation¶
-
public final class
KeyInformation
¶ Object representation of dragged field from trigger or data source.
This class represents a single dragged field from trigger or data source. This class does not expose a public constructor. You have to use
parse(String)
method if you want to parse single field orparseAll(String)
if you want ot get all fields from a given string.
Methods¶
fromAdditionalData¶
-
public boolean
fromAdditionalData
()¶ Check if the field is from the data source.
Returns: true if the field is from the data source otherwise false
fromPostActionParameter¶
-
public boolean
fromPostActionParameter
()¶ Check if the field is from the post action parameter.
Returns: true if the field is from the post action parameter otherwise false
fromTrigger¶
-
public boolean
fromTrigger
()¶ Check if the field is from the trigger.
Returns: true if the field is from the trigger otherwise false
getManipulations¶
getOriginalKey¶
hasManipulations¶
-
public boolean
hasManipulations
()¶ Check if the field has any manipulations.
Returns: true if the field has manipulations otherwise false
parse¶
-
public static KeyInformation
parse
(String input)¶ Parse given string to instance of
KeyInformation
.This method should be used to convert string representation of dragged field to instance of
KeyInformation
.Argument has adhere to one of the following format:
- trigger field format: trigger.eventKey
- data source format: ad.dataProviderId.objectType#objectId.fieldKey
- post action parameter format: pa.objectId.fieldKey
Argument can also contain list of manipulation which should be executed on field before it will be used by
TaskTriggerHandler
class. Manipulations should be connected together by the ? character.Example of input argument:
- ad.279f5fdf60700d9717270b1ae3011eb1.CaseInfo#0.fieldValues.phu_id
- trigger.message?format(Ala,cat)?capitalize
Parameters: - input – string representation of a dragged field from trigger or data source
Throws: - IllegalArgumentException – exception is thrown if format for data source field is incorrect or if the dragged field is not from trigger or data source.
Returns: Object representation of a dragged field
parseAll¶
-
public static List<KeyInformation>
parseAll
(String input)¶ Find all fields from given input and convert them to the instance of
KeyInformation
.This method should be used to find and convert all of string representation of the field from trigger and/or data sources. Fields in input have to adhere to one of the following formats:
- trigger field format: {{trigger.eventKey}}
- data source format: {{ad.dataProviderId.objectType#objectId.fieldKey}}
- post action parameter format: pa.fieldKey
To find fields in the input argument this method uses regular expression. When field is found it is converted to an instance of
KeyInformation
by using theparse(String)
method.Fields are found by the following regular expression: {{((.*?))(}})(?![^(]*)). The expression searches for strings that start with {{ and end with }} and are not within ( and ). Because of manipulations which contain additional data in (...) needed to execute manipulation on the field (e.g.: join needs to have the join character) and the text in (...) can be another string representation of the dragged field, the expression has to check if the field has this kind of manipulation.
Example of input argument:
- {{trigger.message?format(Ala,cat)?capitalize}}
- You get the following message: {{trigger.message}}
Parameters: - input – string with one or more string representation of dragged fields from trigger and/or data sources
Throws: - IllegalArgumentException – in the same situations as the
parse(String)
method.
Returns: list of object representation of dragged fields.
ManipulationTarget¶
-
public enum
ManipulationTarget
¶ Defines the target of various manipulations used in a task for both triggers and data sources.
Enum Constants¶
ALL¶
-
public static final ManipulationTarget
ALL
¶
DATE¶
-
public static final ManipulationTarget
DATE
¶
STRING¶
-
public static final ManipulationTarget
STRING
¶
ManipulationType¶
-
public enum
ManipulationType
¶ Defines the type of various manipulations used in a task for both triggers and data sources.
Enum Constants¶
BEGINNINGOFMONTH¶
-
public static final ManipulationType
BEGINNINGOFMONTH
¶
CAPITALIZE¶
-
public static final ManipulationType
CAPITALIZE
¶
DATETIME¶
-
public static final ManipulationType
DATETIME
¶
ENDOFMONTH¶
-
public static final ManipulationType
ENDOFMONTH
¶
FORMAT¶
-
public static final ManipulationType
FORMAT
¶
JOIN¶
-
public static final ManipulationType
JOIN
¶
MINUSDAYS¶
-
public static final ManipulationType
MINUSDAYS
¶
MINUSHOURS¶
-
public static final ManipulationType
MINUSHOURS
¶
MINUSMINUTES¶
-
public static final ManipulationType
MINUSMINUTES
¶
MINUSMONTHS¶
-
public static final ManipulationType
MINUSMONTHS
¶
PARSEDATE¶
-
public static final ManipulationType
PARSEDATE
¶
PLUSDAYS¶
-
public static final ManipulationType
PLUSDAYS
¶
PLUSHOURS¶
-
public static final ManipulationType
PLUSHOURS
¶
PLUSMINUTES¶
-
public static final ManipulationType
PLUSMINUTES
¶
PLUSMONTHS¶
-
public static final ManipulationType
PLUSMONTHS
¶
QUARTER¶
-
public static final ManipulationType
QUARTER
¶
SPLIT¶
-
public static final ManipulationType
SPLIT
¶
SUBSTRING¶
-
public static final ManipulationType
SUBSTRING
¶
TOLOWER¶
-
public static final ManipulationType
TOLOWER
¶
TOUPPER¶
-
public static final ManipulationType
TOUPPER
¶
UNKNOWN¶
-
public static final ManipulationType
UNKNOWN
¶
URLENCODE¶
-
public static final ManipulationType
URLENCODE
¶
org.motechproject.tasks.domain.enums¶
LogicalOperator¶
-
public enum
LogicalOperator
¶ Enumerates logical operators that can be used on
Filter
s in the taskFilterSet
s.
Enum Constants¶
AND¶
-
public static final LogicalOperator
AND
¶
OR¶
-
public static final LogicalOperator
OR
¶
MethodCallManner¶
-
public enum
MethodCallManner
¶ The
MethodCallManner
enumerates possible call manners of anActionEvent
service method. It also implies expected signature of this method.See also:
ActionEvent
Enum Constants¶
MAP¶
-
public static final MethodCallManner
MAP
¶ When using this call manner, the parameters are evaluated, casted to appropriate types and then wrapped with a Map in which keys corresponds to parameters names and values corresponds to parameters values. Map in this form gets passed to the service method.
NAMED_PARAMETERS¶
-
public static final MethodCallManner
NAMED_PARAMETERS
¶ When using this call manner, the parameters are evaluated, casted to appropriate types and then passed to the service method in specified order as a regular java method parameters.
ParameterType¶
-
public enum
ParameterType
¶ Defines the type of various values used in a task including trigger parameters, action parameters and data source object fields.
Enum Constants¶
BOOLEAN¶
-
public static final ParameterType
BOOLEAN
¶
DATE¶
-
public static final ParameterType
DATE
¶
DOUBLE¶
-
public static final ParameterType
DOUBLE
¶
INTEGER¶
-
public static final ParameterType
INTEGER
¶
LIST¶
-
public static final ParameterType
LIST
¶
LONG¶
-
public static final ParameterType
LONG
¶
MAP¶
-
public static final ParameterType
MAP
¶
PERIOD¶
-
public static final ParameterType
PERIOD
¶
SELECT¶
-
public static final ParameterType
SELECT
¶
TEXTAREA¶
-
public static final ParameterType
TEXTAREA
¶
TIME¶
-
public static final ParameterType
TIME
¶
UNICODE¶
-
public static final ParameterType
UNICODE
¶
UNKNOWN¶
-
public static final ParameterType
UNKNOWN
¶
TaskActivityType¶
-
public enum
TaskActivityType
¶ Enumerates all types of task activities.
Enum Constants¶
ERROR¶
-
public static final TaskActivityType
ERROR
¶
FILTERED¶
-
public static final TaskActivityType
FILTERED
¶
IN_PROGRESS¶
-
public static final TaskActivityType
IN_PROGRESS
¶
SUCCESS¶
-
public static final TaskActivityType
SUCCESS
¶
WARNING¶
-
public static final TaskActivityType
WARNING
¶
TaskErrorType¶
-
public enum
TaskErrorType
¶ Enumerates all possible causes of task failures.
Enum Constants¶
BLANK¶
-
public static final TaskErrorType
BLANK
¶
EMPTY_COLLECTION¶
-
public static final TaskErrorType
EMPTY_COLLECTION
¶
NULL¶
-
public static final TaskErrorType
NULL
¶
VERSION¶
-
public static final TaskErrorType
VERSION
¶
org.motechproject.tasks.domain.mds¶
Parameter¶
-
public abstract class
Parameter
implements Serializable¶ Abstract class that stores common information about a single parameter. Serves as a base class for
FieldParameter
,ActionParameter
andEventParameter
classes. It is a part of the channel model.
Constructors¶
Parameter¶
-
protected
Parameter
(String displayName, ParameterType type)¶ Constructor.
Parameters: - displayName – the parameter display name
- type – the parameter type
Methods¶
getType¶
-
public ParameterType
getType
()¶
setType¶
-
public void
setType
(ParameterType type)¶
toDto¶
-
public abstract ParameterDto
toDto
()¶
org.motechproject.tasks.domain.mds.channel¶
ActionEvent¶
-
public class
ActionEvent
extends TaskEvent¶ Represents an action from a channel. An action is taken once a task is triggered. This class is the representation of the definition from the channel, not the representation of an usage within task. An action can be represented as an event, but also as a direct OSGi message(or both - a service call with the event acting as a fallback way of executing the action).
Constructors¶
ActionEvent¶
-
public
ActionEvent
(String name, String description, String displayName, String subject, String serviceInterface, String serviceMethod, MethodCallManner serviceMethodCallManner, SortedSet<ActionParameter> actionParameters)¶ Constructor.
ActionEvent¶
-
public
ActionEvent
(String name, String description, String displayName, String subject, String serviceInterface, String serviceMethod, MethodCallManner serviceMethodCallManner, SortedSet<ActionParameter> actionParameters, SortedSet<ActionParameter> postActionParameters)¶ Constructor.
Parameters: - name – the action name
- description – the action description
- displayName – the action display name
- subject – the action event subject
- serviceInterface – the event service interface
- serviceMethod – the event service method
- serviceMethodCallManner – the event service call manner, for supported values see {@see MethodCallManner}
- actionParameters – the action parameters
- postActionParameters – the post action parameters
ActionEvent¶
-
public
ActionEvent
(ActionEvent actionEvent)¶
Methods¶
accept¶
-
public boolean
accept
(TaskActionInformation info)¶
addParameter¶
-
public void
addParameter
(ActionParameter parameter, boolean changeOrder)¶
getActionParameters¶
-
public SortedSet<ActionParameter>
getActionParameters
()¶
getPostActionParameters¶
-
public SortedSet<ActionParameter>
getPostActionParameters
()¶
getServiceMethodCallManner¶
-
public MethodCallManner
getServiceMethodCallManner
()¶
setActionParameters¶
-
public void
setActionParameters
(SortedSet<ActionParameter> actionParameters)¶
setPostActionParameters¶
-
public void
setPostActionParameters
(SortedSet<ActionParameter> postActionParameters)¶
setServiceMethodCallManner¶
-
public void
setServiceMethodCallManner
(MethodCallManner serviceMethodCallManner)¶
toDto¶
-
public ActionEventDto
toDto
()¶
ActionParameter¶
-
public class
ActionParameter
extends Parameter implements Comparable<ActionParameter>¶ Represents a single parameter of an action in the channel definition.
Constructors¶
ActionParameter¶
-
public
ActionParameter
(String displayName, ParameterType type, Integer order, String key, String value, Boolean required, Boolean hidden, SortedSet<String> options)¶ Constructor.
Parameters: - displayName – the parameter display name
- type – the parameter type
- order – the parameter order
- key – the parameter key
- value – the parameter value
- required – defines whether the parameter is required
- hidden – defines whether the parameter is hidden
- options – the parameter options for select parameter type
ActionParameter¶
-
public
ActionParameter
(ActionParameter actionParameter)¶
Methods¶
compareTo¶
-
public int
compareTo
(ActionParameter o)¶
toDto¶
-
public ActionParameterDto
toDto
()¶
Channel¶
-
public class
Channel
¶ Represents a single task channel. Channel contains the list of triggers from the given module and the list of actions that can be taken by that module.
Constructors¶
Channel¶
Channel¶
-
public
Channel
(String displayName, String moduleName, String moduleVersion, String description, List<TriggerEvent> triggerTaskEvents, List<ActionEvent> actionTaskEvents)¶ Constructor.
Parameters: - displayName – the channel display name
- moduleName – the channel module name
- moduleVersion – the module version
- description – the channel description
- triggerTaskEvents – the list of events for provided triggers
- actionTaskEvents – the list of events for provided actions
Methods¶
addActionTaskEvent¶
-
public void
addActionTaskEvent
(ActionEvent actionEvent)¶
containsAction¶
-
public boolean
containsAction
(TaskActionInformation actionInformation)¶
getAction¶
-
public ActionEvent
getAction
(TaskActionInformation actionInformation)¶
getActionTaskEvents¶
-
public List<ActionEvent>
getActionTaskEvents
()¶
getTriggerTaskEvents¶
-
public List<TriggerEvent>
getTriggerTaskEvents
()¶
setActionTaskEvents¶
-
public void
setActionTaskEvents
(List<ActionEvent> actionTaskEvents)¶
setTriggerTaskEvents¶
-
public void
setTriggerTaskEvents
(List<TriggerEvent> triggerTaskEvents)¶
toDto¶
-
public ChannelDto
toDto
()¶
EventParameter¶
-
public class
EventParameter
extends Parameter¶ Represents a parameter of a trigger event. These parameters can be dragged and dropped within tasks. This class is part of the channel model.
Constructors¶
EventParameter¶
EventParameter¶
-
public
EventParameter
(String displayName, String eventKey, ParameterType type)¶ Constructor.
Parameters: - displayName – the parameter display name
- eventKey – the event key
- type – the parameter type
EventParameter¶
-
public
EventParameter
(EventParameter eventParameter)¶
Methods¶
getTriggerEvent¶
-
public TriggerEvent
getTriggerEvent
()¶
setTriggerEvent¶
-
public void
setTriggerEvent
(TriggerEvent triggerEvent)¶
toDto¶
-
public EventParameterDto
toDto
()¶
TaskEvent¶
-
public abstract class
TaskEvent
implements Serializable¶ Represents a single task event. Task event is an abstract base for events utilized in the task module. It serves as a base for both
ActionEvent
s andTriggerEvent
s. It is a part of the channel model.
Methods¶
TriggerEvent¶
-
public class
TriggerEvent
extends TaskEvent¶ Represents a single trigger event. Trigger event is an event that triggers executions of a task. It is a part of the channel model.
Constructors¶
TriggerEvent¶
-
public
TriggerEvent
(String displayName, String subject, String description, List<EventParameter> eventParameters, String triggerListenerSubject)¶ Class constructor.
Parameters: - displayName – the event display name
- subject – the event subject
- description – the event description
- eventParameters – the event parameters
- triggerListenerSubject – the subject that is wrapped by this trigger, in a simple case it is identical to the subject above, so it can be omitted
TriggerEvent¶
-
public
TriggerEvent
(TriggerEvent triggerEvent)¶ Copy constructor.
Parameters: - triggerEvent – the object to be copied
Methods¶
getEventParameters¶
-
public List<EventParameter>
getEventParameters
()¶
setEventParameters¶
-
public void
setEventParameters
(List<EventParameter> eventParameters)¶
toDto¶
-
public TriggerEventDto
toDto
()¶
org.motechproject.tasks.domain.mds.channel.builder¶
ActionEventBuilder¶
-
public class
ActionEventBuilder
¶ The
ActionEventBuilder
class provides methods for constructing action events.See also:
ActionEvent
Methods¶
build¶
-
public ActionEvent
build
()¶ Builds an object of the
ActionEvent
class.Returns: the created instance
fromActionEventRequest¶
-
public static ActionEventBuilder
fromActionEventRequest
(ActionEventRequest actionEventRequest)¶ Builds an object of the
ActionEventBuilder
class based on the passedActionEventRequest
instance.Parameters: - actionEventRequest – the action event request, not null
Returns: the instance of the
ActionEventBuilder
class ready to build instance of theActionEvent
class
setActionParameters¶
-
public ActionEventBuilder
setActionParameters
(SortedSet<ActionParameter> actionParameters)¶
setDescription¶
-
public ActionEventBuilder
setDescription
(String description)¶
setDisplayName¶
-
public ActionEventBuilder
setDisplayName
(String displayName)¶
setName¶
-
public ActionEventBuilder
setName
(String name)¶
setPostActionParameters¶
-
public ActionEventBuilder
setPostActionParameters
(SortedSet<ActionParameter> postActionParameters)¶
setServiceInterface¶
-
public ActionEventBuilder
setServiceInterface
(String serviceInterface)¶
setServiceMethod¶
-
public ActionEventBuilder
setServiceMethod
(String serviceMethod)¶
setServiceMethodCallManner¶
-
public ActionEventBuilder
setServiceMethodCallManner
(MethodCallManner serviceMethodCallManner)¶
setSubject¶
-
public ActionEventBuilder
setSubject
(String subject)¶
ActionParameterBuilder¶
-
public class
ActionParameterBuilder
¶ The
ActionParameterBuilder
class provides methods for constructing action parameters.See also:
ActionParameter
Methods¶
build¶
-
public ActionParameter
build
()¶ Builds an object of the
ActionParameter
class.Returns: the created instance
fromActionParameterRequest¶
-
public static ActionParameterBuilder
fromActionParameterRequest
(ActionParameterRequest actionParameterRequest)¶ Builds an object of the
ActionParameterBuilder
class based on the passedActionParameterRequest
instance.Parameters: - actionParameterRequest – the action parameter request, not null
Returns: a builder ready to build a new instance of the
ActionParameter
class
setDisplayName¶
-
public ActionParameterBuilder
setDisplayName
(String displayName)¶
setKey¶
-
public ActionParameterBuilder
setKey
(String key)¶
setOptions¶
-
public ActionParameterBuilder
setOptions
(SortedSet<String> options)¶
setOrder¶
-
public ActionParameterBuilder
setOrder
(Integer order)¶
setRequired¶
-
public ActionParameterBuilder
setRequired
(boolean required)¶
setType¶
-
public ActionParameterBuilder
setType
(ParameterType type)¶
setValue¶
-
public ActionParameterBuilder
setValue
(String value)¶
ChannelBuilder¶
-
public class
ChannelBuilder
¶ Provides methods for constructing channels.
Methods¶
fromChannelRequest¶
-
public static ChannelBuilder
fromChannelRequest
(ChannelRequest channelRequest)¶ Creates a builder, which allows building Channels based on the given
channelRequest
.Parameters: - channelRequest – the channel request
Returns: the created builder
setActionTaskEvents¶
-
public ChannelBuilder
setActionTaskEvents
(List<ActionEvent> actionTaskEvents)¶
setDescription¶
-
public ChannelBuilder
setDescription
(String description)¶
setDisplayName¶
-
public ChannelBuilder
setDisplayName
(String displayName)¶
setModuleName¶
-
public ChannelBuilder
setModuleName
(String moduleName)¶
setModuleVersion¶
-
public ChannelBuilder
setModuleVersion
(String moduleVersion)¶
setTriggerTaskEvents¶
-
public ChannelBuilder
setTriggerTaskEvents
(List<TriggerEvent> triggerTaskEvents)¶
EventParameterBuilder¶
-
public class
EventParameterBuilder
¶ Provides methods for constructing event parameters.
Methods¶
build¶
-
public EventParameter
build
()¶ Builds an object of
EventParameter
class.Returns: the created instance
fromEventParameterRequest¶
-
public static EventParameterBuilder
fromEventParameterRequest
(EventParameterRequest eventParameterRequest)¶ Creates a builder, which allows building event parameters based on the given
eventParameterRequest
.Parameters: - eventParameterRequest – the event parameter request
Returns: the created builder
setDisplayName¶
-
public EventParameterBuilder
setDisplayName
(String displayName)¶
setEventKey¶
-
public EventParameterBuilder
setEventKey
(String eventKey)¶
setParameterType¶
-
public EventParameterBuilder
setParameterType
(String type)¶
TriggerEventBuilder¶
-
public class
TriggerEventBuilder
¶ Provides methods for constructing trigger events.
Methods¶
build¶
-
public TriggerEvent
build
()¶ Builds an object of
TriggerEvent
class.Returns: the created instance
fromTriggerEventRequest¶
-
public static TriggerEventBuilder
fromTriggerEventRequest
(TriggerEventRequest triggerEventRequest)¶ Creates a builder, which allows building trigger events based on the given
triggerEventRequest
.Parameters: - triggerEventRequest – the trigger event request
Returns: the created builder
setDescription¶
-
public TriggerEventBuilder
setDescription
(String description)¶
setDisplayName¶
-
public TriggerEventBuilder
setDisplayName
(String displayName)¶
setEventParameters¶
-
public TriggerEventBuilder
setEventParameters
(List<EventParameter> eventParameters)¶
setSubject¶
-
public TriggerEventBuilder
setSubject
(String subject)¶
setTriggerListenerSubject¶
-
public TriggerEventBuilder
setTriggerListenerSubject
(String triggerListenerSubject)¶
org.motechproject.tasks.domain.mds.task¶
DataSource¶
-
public class
DataSource
extends TaskConfigStep¶ Represents a single data source object used by a task. This class is part of the task itself and does not describe the data source itself. This object translates to retrieving a data source object during task execution.
Constructors¶
DataSource¶
-
public
DataSource
(DataSourceDto dto)¶ Constructor.
Parameters: - dto – DataSource data transfer object
DataSource¶
-
public
DataSource
(String providerName, Long providerId, Long objectId, String type, String name, List<Lookup> lookup, boolean failIfDataNotFound)¶ Constructor.
Parameters: - providerName – the provider name
- providerId – the provider ID
- objectId – the object ID
- type – the data source type
- name – the data source name
- lookup – the lookup name
- failIfDataNotFound – defines if task should fail if no data was found
DataSource¶
Methods¶
toDto¶
-
public DataSourceDto
toDto
()¶
FieldParameter¶
-
public class
FieldParameter
extends Parameter¶ Represents a single field of the
TaskDataProviderObject
that is part of theTaskDataProvider
.
Filter¶
-
public class
Filter
implements Serializable¶ Represents a single filter. A filter is a part of the
FilterSet
and represents a single condition that task must meet before being executed. If that condition is not met the task execution will be stopped. It is an optional part of a task.
Constructors¶
Filter¶
-
public
Filter
(String displayName, String key, ParameterType type, boolean negationOperator, String operator, String expression, List<String> manipulations)¶ Constructor.
Parameters: - displayName – the filter display name
- key – the filter key
- type – the filter type
- negationOperator – defines if the represented operator should be negated
- operator – the filter operator
- expression – the filter exception
FilterSet¶
-
public class
FilterSet
extends TaskConfigStep¶ Represents a set of
Filter
s. Those are conditions that task must meet before being executed. If the conditions are not met the task execution will be stopped. Joining those conditions can be done by using logical “and” or logical “or” as an operator and can be set bysetOperator(LogicalOperator)
method.
Constructors¶
FilterSet¶
-
public
FilterSet
(FilterSetDto dto)¶ Constructor.
Parameters: - dto – FilterSet data transfer object
FilterSet¶
Methods¶
getOperator¶
-
public LogicalOperator
getOperator
()¶
setOperator¶
-
public void
setOperator
(LogicalOperator operator)¶
toDto¶
-
public FilterSetDto
toDto
()¶
Lookup¶
-
public class
Lookup
implements Serializable¶ Represents a single lookup. Lookup is a method of retrieving an object from a data provider. It is a part of a task model.
Constructors¶
Methods¶
LookupFieldsParameter¶
-
public class
LookupFieldsParameter
¶ Represents a lookup fields. It is part of the
TaskDataProviderObject
and describes a single lookup with its display name and fields that are used by that lookup.
Constructors¶
Methods¶
toDto¶
-
public LookupFieldsParameterDto
toDto
()¶
OperatorType¶
-
public enum
OperatorType
¶ Object representation of available operators in filter definition.
Enum Constants¶
AFTER¶
-
public static final OperatorType
AFTER
¶
AFTER_NOW¶
-
public static final OperatorType
AFTER_NOW
¶
AND¶
-
public static final OperatorType
AND
¶
BEFORE¶
-
public static final OperatorType
BEFORE
¶
BEFORE_NOW¶
-
public static final OperatorType
BEFORE_NOW
¶
CONTAINS¶
-
public static final OperatorType
CONTAINS
¶
ENDSWITH¶
-
public static final OperatorType
ENDSWITH
¶
EQUALS¶
-
public static final OperatorType
EQUALS
¶
EQUALS_IGNORE_CASE¶
-
public static final OperatorType
EQUALS_IGNORE_CASE
¶
EQ_NUMBER¶
-
public static final OperatorType
EQ_NUMBER
¶
EXIST¶
-
public static final OperatorType
EXIST
¶
GT¶
-
public static final OperatorType
GT
¶
IS_TRUE¶
-
public static final OperatorType
IS_TRUE
¶
LESS_DAYS_FROM_NOW¶
-
public static final OperatorType
LESS_DAYS_FROM_NOW
¶
LESS_MONTHS_FROM_NOW¶
-
public static final OperatorType
LESS_MONTHS_FROM_NOW
¶
LT¶
-
public static final OperatorType
LT
¶
MORE_DAYS_FROM_NOW¶
-
public static final OperatorType
MORE_DAYS_FROM_NOW
¶
MORE_MONTHS_FROM_NOW¶
-
public static final OperatorType
MORE_MONTHS_FROM_NOW
¶
OR¶
-
public static final OperatorType
OR
¶
STARTSWITH¶
-
public static final OperatorType
STARTSWITH
¶
PostActionParameter¶
-
public class
PostActionParameter
¶ Represents a single post action parameter used by a task. This class is part of the task itself and does not describe the parameter itself. This object translates to retrieving a parameter object during task execution.
Constructors¶
Methods¶
Task¶
-
public class
Task
¶ A task is set of actions that are executed in response to a trigger. The actions and the trigger are defined by their respective
Channel
s.
Constructors¶
Task¶
-
public
Task
(String name, TaskTriggerInformation trigger, List<TaskActionInformation> actions)¶ Constructor.
Parameters: - name – the task name
- trigger – the task trigger
- actions – the list of related actions
Task¶
-
public
Task
(String name, TaskTriggerInformation trigger, List<TaskActionInformation> actions, TaskConfig taskConfig, boolean enabled, boolean hasRegisteredChannel)¶
Task¶
-
public
Task
(String name, TaskTriggerInformation trigger, List<TaskActionInformation> actions, TaskConfig taskConfig, boolean enabled, boolean hasRegisteredChannel, List<String> days)¶ Constructor.
Parameters: - name – the task name
- trigger – the task trigger
- actions – the list of related actions
- taskConfig – the task configuration
- enabled – defines if this task is enabled
- hasRegisteredChannel – defines if this task has a registered channel
Methods¶
addAction¶
-
public void
addAction
(TaskActionInformation action)¶ Stores the given action.
Parameters: - action – the action
getActions¶
-
public List<TaskActionInformation>
getActions
()¶
getTaskConfig¶
-
public TaskConfig
getTaskConfig
()¶
getTrigger¶
-
public TaskTriggerInformation
getTrigger
()¶
incrementFailuresInRow¶
-
public void
incrementFailuresInRow
()¶ Increases the counter of task execution failures that occurred since the last successful execution of this task or since the task was enabled.
resetFailuresInRow¶
-
public void
resetFailuresInRow
()¶ Resets the counter of task execution failures that occurred since the last successful execution of this task or since the task was enabled.
setActions¶
-
public void
setActions
(List<TaskActionInformation> actions)¶
setRetryIntervalInMilliseconds¶
-
public void
setRetryIntervalInMilliseconds
(int retryIntervalInMilliseconds)¶
setTaskConfig¶
-
public void
setTaskConfig
(TaskConfig taskConfig)¶
setTrigger¶
-
public void
setTrigger
(TaskTriggerInformation trigger)¶
TaskActionInformation¶
-
public class
TaskActionInformation
extends TaskEventInformation¶ Represents an action from a channel. An action is taken upon a task trigger. This class is the representation of the definition from the channel, not the representation of an usage within a task. An action can be represented as an event, but also as a direct OSGi message(or both - a service call with fallback event). It is part of the tasks model.
Constructors¶
TaskActionInformation¶
-
public
TaskActionInformation
(String displayName, String channelName, String moduleName, String moduleVersion, String subject)¶ Constructor.
Parameters: - displayName – the task display name
- channelName – the channel name
- moduleName – the module name
- moduleVersion – the module version
- subject – the task subject
TaskActionInformation¶
-
public
TaskActionInformation
(String displayName, String channelName, String moduleName, String moduleVersion, String subject, Map<String, String> values)¶ Constructor for an action that is an event sent by the task module.
Parameters: - displayName – the task display name
- channelName – the channel name
- moduleName – the module name
- moduleVersion – the module version
- subject – the task subject
- values – the map of values
TaskActionInformation¶
-
public
TaskActionInformation
(String displayName, String channelName, String moduleName, String moduleVersion, String serviceInterface, String serviceMethod)¶ Constructor for an action that is an OSGi service method call from the tasks module.
Parameters: - displayName – the task display name
- channelName – the channel name
- moduleName – the module name
- moduleVersion – the module version
- serviceInterface – the task service interface
- serviceMethod – the task service method
TaskActionInformation¶
-
public
TaskActionInformation
(String name, String displayName, String channelName, String moduleName, String moduleVersion, String serviceInterface, String serviceMethod)¶ Constructor.
Parameters: - name – the task name
- displayName – the task display name
- channelName – the channel name
- moduleName – the module name
- moduleVersion – the module version
- serviceInterface – the task service interface
- serviceMethod – the task service method
TaskActionInformation¶
-
public
TaskActionInformation
(String name, String specifiedName, String displayName, String channelName, String moduleName, String moduleVersion, String subject, String serviceInterface, String serviceMethod, Map<String, String> values)¶ Constructor for a task that is an OSGi service call from the tasks module, but falls back to sending an event if the service is not present
Parameters: - name – the task name
- specifiedName – the task action specified name
- displayName – the task display name
- channelName – the channel name
- moduleName – the module name
- moduleVersion – the module version
- subject – the task subject
- serviceInterface – the task service interface
- serviceMethod – the task service method
- values – the map of values
Methods¶
toDto¶
-
public TaskActionInformationDto
toDto
()¶
TaskActivity¶
-
public class
TaskActivity
implements Comparable<TaskActivity>¶ Represents a single task activity. Task activity is a historical entry about a task execution.
Constructors¶
TaskActivity¶
-
public
TaskActivity
(String message, Long task, TaskActivityType activityType)¶ Constructor.
Parameters: - message – the activity message
- task – the activity task ID
- activityType – the activity type
TaskActivity¶
-
public
TaskActivity
(String message, String field, Long task, TaskActivityType activityType)¶ Constructor.
Parameters: - message – the activity message
- field – the field name
- task – the activity task ID
- activityType – the activity type
TaskActivity¶
-
public
TaskActivity
(String message, List<String> fields, Long task, TaskActivityType activityType, TaskExecutionProgress executionProgress)¶ Constructor.
Parameters: - message – the activity message
- fields – the field names
- task – the activity task ID
- activityType – the activity type
- executionProgress – the progress of task action executions
TaskActivity¶
-
public
TaskActivity
(String message, List<String> fields, Long task, TaskActivityType activityType, String stackTraceElement)¶ Constructor.
Parameters: - message – the activity message
- fields – the field names
- task – the activity ID
- activityType – the activity type
- stackTraceElement – the stack trace that caused the task failure
TaskActivity¶
-
public
TaskActivity
(String message, List<String> fields, Long task, TaskActivityType activityType, String stackTraceElement, Map<String, Object> parameters, TaskExecutionProgress executionProgress)¶ Constructor.
Parameters: - message – the activity message
- fields – the field names
- task – the task ID
- activityType – the activity type
- stackTraceElement – the stack trace that caused the task failure
- parameters – the parameters used by the task in this execution
- executionProgress – the progress of task action executions
TaskActivity¶
-
public
TaskActivity
(String message, List<String> fields, Long task, String triggerName, TaskActivityType activityType, String stackTraceElement, Map<String, Object> parameters, TaskExecutionProgress executionProgress)¶ Constructor.
Parameters: - message – the activity message
- fields – the field names
- task – the task ID
- triggerName – the task trigger name
- activityType – the activity type
- stackTraceElement – the stack trace that caused the task failure
- parameters – the parameters used by the task in this execution
- executionProgress – the progress of task action executions
Methods¶
compareTo¶
-
public int
compareTo
(TaskActivity o)¶
getActivityType¶
-
public TaskActivityType
getActivityType
()¶
getTaskExecutionProgress¶
-
public TaskExecutionProgress
getTaskExecutionProgress
()¶
setActivityType¶
-
public void
setActivityType
(TaskActivityType activityType)¶
setTaskExecutionProgress¶
-
public void
setTaskExecutionProgress
(TaskExecutionProgress executionProgress)¶
toDto¶
-
public TaskActivityDto
toDto
()¶
TaskConfig¶
-
public class
TaskConfig
implements Serializable¶ Represents a single task configuration. Task configuration is a list of
TaskConfigStep
s that are taken during task execution. A single step can be a filter(whose conditions must be meet) or a data store that must be fetched in order to execute the task successfully.
Methods¶
add¶
-
public TaskConfig
add
(TaskConfigStepDto step)¶
add¶
-
public TaskConfig
add
(TaskConfigStep... configSteps)¶ Stores the given configuration steps.
Parameters: - configSteps – the configuration steps, not null
Returns: this object
addAll¶
-
public TaskConfig
addAll
(SortedSet<TaskConfigStep> set)¶ Stores the given configuration steps
Parameters: - set – the configuration steps
Returns: this object
getDataSource¶
-
public DataSource
getDataSource
(String providerName, Long objectId, String objectType)¶ Returns the data source for the given information.
Parameters: - providerName – the provider name
- objectId – the object ID
- objectType – the object type
Returns: the object matching the given data.
getDataSources¶
-
public List<DataSource>
getDataSources
()¶
getDataSources¶
-
public SortedSet<DataSource>
getDataSources
(String providerName)¶
getPostActionParameters¶
-
public List<PostActionParameter>
getPostActionParameters
()¶
getSteps¶
-
public SortedSet<TaskConfigStep>
getSteps
()¶
removeAll¶
-
public TaskConfig
removeAll
()¶ Clears filter sets and data sources for this object.
Returns: this object
removeDataSources¶
-
public TaskConfig
removeDataSources
()¶ Clears data sources for this object.
Returns: this object
removeFilterSets¶
-
public TaskConfig
removeFilterSets
()¶ Clears filter sets for this object.
Returns: this object
setDataSources¶
-
public void
setDataSources
(List<DataSource> dataSources)¶
setPostActionParameters¶
-
public void
setPostActionParameters
(List<PostActionParameter> postActionParameters)¶
toDto¶
-
public TaskConfigDto
toDto
()¶
TaskConfigStep¶
-
public abstract class
TaskConfigStep
implements Comparable<TaskConfigStep>, Serializable¶ Represents a single task configuration step. Task configuration step is an abstract class that should be extended by all steps that are taken during task execution. Currently it serves as a base class for
Filter
s andDataSource
s.
Constructors¶
Methods¶
compareTo¶
-
public int
compareTo
(TaskConfigStep o)¶
toDto¶
-
public abstract TaskConfigStepDto
toDto
()¶
TaskDataProvider¶
-
public class
TaskDataProvider
¶ Represents a single data provider used by the task module. It provides provider objects used as data sources by the tasks.
Constructors¶
TaskDataProvider¶
-
public
TaskDataProvider
(String name, List<TaskDataProviderObject> objects)¶
Methods¶
containsProviderObjectField¶
containsProviderObjectLookup¶
getObjects¶
-
public List<TaskDataProviderObject>
getObjects
()¶
getProviderObject¶
-
public TaskDataProviderObject
getProviderObject
(String type)¶
setObjects¶
-
public void
setObjects
(List<TaskDataProviderObject> objects)¶
toDto¶
-
public TaskDataProviderDto
toDto
()¶
TaskDataProviderObject¶
-
public class
TaskDataProviderObject
implements Serializable¶ Represents a single object of the task data provider. It describes fields and lookups of an entity that is used as a data store in the task module.
Constructors¶
TaskDataProviderObject¶
-
public
TaskDataProviderObject
(String displayName, String type, List<LookupFieldsParameter> lookupFields, List<FieldParameter> fields)¶
Methods¶
getFields¶
-
public List<FieldParameter>
getFields
()¶
getLookupFields¶
-
public List<LookupFieldsParameter>
getLookupFields
()¶
setFields¶
-
public void
setFields
(List<FieldParameter> fields)¶
toDto¶
-
public TaskDataProviderObjectDto
toDto
()¶
TaskError¶
-
public class
TaskError
implements Serializable¶ Represents a single task error. Those error are encountered during validation of a channel if some of the required fields are blank or missing.
Constructors¶
TaskError¶
-
public
TaskError
(TaskErrorType type, String... args)¶ Constructor.
Parameters: - type – the error type, not null
- args – the arguments
Methods¶
toDto¶
-
public TaskErrorDto
toDto
()¶
TaskEventInformation¶
-
public abstract class
TaskEventInformation
implements Serializable¶ Represents information about single task event. Task event is an abstract base for events utilized in the task module. It serves as a base for both
TaskActionInformation
s andTaskTriggerInformation
s. It is a part of the task model.
Constructors¶
TaskEventInformation¶
-
public
TaskEventInformation
(String name, String displayName, String channelName, String moduleName, String moduleVersion, String subject)¶ Constructor.
Parameters: - name – the event name
- displayName – the event display name
- channelName – the event channel name
- moduleName – the event module name
- moduleVersion – the module version
- subject – the event subject
Methods¶
toDto¶
-
public abstract TaskEventInformationDto
toDto
()¶
TaskExecutionProgress¶
-
public class
TaskExecutionProgress
¶ A domain object that keeps track of the task execution progress.
Methods¶
TaskTriggerInformation¶
-
public class
TaskTriggerInformation
extends TaskEventInformation¶ Represents information about a single task trigger. A task trigger is an event that triggers execution of a task. It is a part of the task model.
Constructors¶
TaskTriggerInformation¶
-
public
TaskTriggerInformation
(String displayName, String channelName, String moduleName, String moduleVersion, String subject, String triggerListener)¶ Constructor.
Parameters: - displayName – the trigger display name
- channelName – the trigger channel name
- moduleName – the trigger module name
- moduleVersion – the module version
- subject – the trigger subject
- triggerListener – the trigger listener
TaskTriggerInformation¶
-
public
TaskTriggerInformation
(TaskTriggerInformation other)¶ The copy constructor.
Parameters: - other – the other
TaskTrigger
to copy, not null
- other – the other
Methods¶
getEffectiveListenerRetrySubject¶
getEffectiveListenerSubject¶
-
public String
getEffectiveListenerSubject
()¶ Convenient method for determining effective listener subject. For tasks created prior release 0.25 the trigger listener subject will not be set in the db, therefore we have to use subject.
Returns: triggerListenerSubject
if present. Otherwise returnssubject
toDto¶
-
public TaskTriggerInformationDto
toDto
()¶
org.motechproject.tasks.domain.mds.task.builder¶
TaskBuilder¶
-
public class
TaskBuilder
¶
Methods¶
addAction¶
-
public TaskBuilder
addAction
(TaskActionInformation action)¶
addDataSource¶
-
public TaskBuilder
addDataSource
(DataSource dataSource)¶
addFilterSet¶
-
public TaskBuilder
addFilterSet
(FilterSet filterSet)¶
clear¶
-
public TaskBuilder
clear
()¶
isEnabled¶
-
public TaskBuilder
isEnabled
(boolean enabled)¶
withDescription¶
-
public TaskBuilder
withDescription
(String description)¶
withId¶
-
public TaskBuilder
withId
(Long id)¶
withName¶
-
public TaskBuilder
withName
(String name)¶
withTaskConfig¶
-
public TaskBuilder
withTaskConfig
(TaskConfig taskConfig)¶
withTrigger¶
-
public TaskBuilder
withTrigger
(TaskTriggerInformation trigger)¶
org.motechproject.tasks.dto¶
ActionEventDto¶
-
public class
ActionEventDto
¶
Constructors¶
ActionEventDto¶
-
public
ActionEventDto
(String name, String description, String displayName, String subject, SortedSet<ActionParameterDto> actionParameters, String serviceInterface, String serviceMethod, MethodCallManner serviceMethodCallManner, SortedSet<ActionParameterDto> postActionParameters)¶
Methods¶
getActionParameters¶
-
public SortedSet<ActionParameterDto>
getActionParameters
()¶
getPostActionParameters¶
-
public SortedSet<ActionParameterDto>
getPostActionParameters
()¶
getServiceMethodCallManner¶
-
public MethodCallManner
getServiceMethodCallManner
()¶
setActionParameters¶
-
public void
setActionParameters
(SortedSet<ActionParameterDto> actionParameters)¶
setPostActionParameters¶
-
public void
setPostActionParameters
(SortedSet<ActionParameterDto> postActionParameters)¶
setServiceMethodCallManner¶
-
public void
setServiceMethodCallManner
(MethodCallManner serviceMethodCallManner)¶
ActionParameterDto¶
-
public class
ActionParameterDto
extends ParameterDto implements Comparable<ActionParameterDto>¶
Constructors¶
Methods¶
compareTo¶
-
public int
compareTo
(ActionParameterDto o)¶
ChannelDto¶
-
public class
ChannelDto
¶
Constructors¶
Methods¶
getActionTaskEvents¶
-
public List<ActionEventDto>
getActionTaskEvents
()¶
setActionTaskEvents¶
-
public void
setActionTaskEvents
(List<ActionEventDto> actionTaskEvents)¶
EventParameterDto¶
-
public class
EventParameterDto
extends ParameterDto¶
FieldParameterDto¶
-
public class
FieldParameterDto
extends ParameterDto¶
FilterDto¶
-
public class
FilterDto
¶
Constructors¶
FilterSetDto¶
-
public class
FilterSetDto
extends TaskConfigStepDto¶
Constructors¶
Methods¶
getOperator¶
-
public LogicalOperator
getOperator
()¶
setOperator¶
-
public void
setOperator
(LogicalOperator operator)¶
ParameterDto¶
-
public abstract class
ParameterDto
¶
Constructors¶
ParameterDto¶
-
protected
ParameterDto
(String displayName, ParameterType type)¶
TaskActionInformationDto¶
-
public class
TaskActionInformationDto
extends TaskEventInformationDto¶
Constructors¶
Methods¶
TaskActivityDto¶
-
public class
TaskActivityDto
¶
Constructors¶
TaskActivityDto¶
-
public
TaskActivityDto
(String message, Long task, TaskActivityType activityType)¶
TaskActivityDto¶
Methods¶
getActivityType¶
-
public TaskActivityType
getActivityType
()¶
setActivityType¶
-
public void
setActivityType
(TaskActivityType activityType)¶
TaskConfigDto¶
-
public class
TaskConfigDto
¶
Constructors¶
TaskConfigDto¶
-
public
TaskConfigDto
(SortedSet<TaskConfigStepDto> steps)¶
Methods¶
getSteps¶
-
public SortedSet<TaskConfigStepDto>
getSteps
()¶
setSteps¶
-
public void
setSteps
(SortedSet<TaskConfigStepDto> steps)¶
TaskConfigStepDto¶
-
public abstract class
TaskConfigStepDto
implements Comparable<TaskConfigStepDto>¶
TaskDataProviderObjectDto¶
-
public class
TaskDataProviderObjectDto
¶
Constructors¶
TaskDataProviderObjectDto¶
-
public
TaskDataProviderObjectDto
(String displayName, String type, List<LookupFieldsParameterDto> lookupFields, List<FieldParameterDto> fields)¶
Methods¶
getFields¶
-
public List<FieldParameterDto>
getFields
()¶
getLookupFields¶
-
public List<LookupFieldsParameterDto>
getLookupFields
()¶
setFields¶
-
public void
setFields
(List<FieldParameterDto> fields)¶
setLookupFields¶
-
public void
setLookupFields
(List<LookupFieldsParameterDto> lookupFields)¶
TaskDto¶
-
public class
TaskDto
¶
Constructors¶
TaskDto¶
-
public
TaskDto
(String name, TaskTriggerInformationDto trigger, List<TaskActionInformationDto> actions)¶
TaskDto¶
-
public
TaskDto
(Long id, String description, String name, int failuresInRow, List<TaskActionInformationDto> actions, TaskTriggerInformationDto trigger, boolean enabled, Set<TaskErrorDto> validationErrors, TaskConfigDto taskConfig, boolean hasRegisteredChannel, int numberOfRetries, int retryIntervalInMilliseconds, boolean retryTaskOnFailure, boolean useTimeWindow, String startTime, String endTime)¶
TaskDto¶
-
public
TaskDto
(Long id, String description, String name, int failuresInRow, List<TaskActionInformationDto> actions, TaskTriggerInformationDto trigger, boolean enabled, Set<TaskErrorDto> validationErrors, TaskConfigDto taskConfig, boolean hasRegisteredChannel, int numberOfRetries, int retryIntervalInMilliseconds, boolean retryTaskOnFailure, boolean useTimeWindow, String startTime, String endTime, List<String> days)¶
Methods¶
getActions¶
-
public List<TaskActionInformationDto>
getActions
()¶
getTaskConfig¶
-
public TaskConfigDto
getTaskConfig
()¶
getTrigger¶
-
public TaskTriggerInformationDto
getTrigger
()¶
getValidationErrors¶
-
public Set<TaskErrorDto>
getValidationErrors
()¶
setActions¶
-
public void
setActions
(List<TaskActionInformationDto> actions)¶
setRetryIntervalInMilliseconds¶
-
public void
setRetryIntervalInMilliseconds
(int retryIntervalInMilliseconds)¶
setTaskConfig¶
-
public void
setTaskConfig
(TaskConfigDto taskConfig)¶
setTrigger¶
-
public void
setTrigger
(TaskTriggerInformationDto trigger)¶
setValidationErrors¶
-
public void
setValidationErrors
(Set<TaskErrorDto> validationErrors)¶
TaskTriggerInformationDto¶
-
public class
TaskTriggerInformationDto
extends TaskEventInformationDto¶
Constructors¶
org.motechproject.tasks.exception¶
ActionNotFoundException¶
CustomParserNotFoundException¶
-
public class
CustomParserNotFoundException
extends IllegalArgumentException¶ Indicates an error, while looking for the Custom Event Parser in the context.
TaskHandlerException¶
TaskNameAlreadyExistsException¶
-
public class
TaskNameAlreadyExistsException
extends RuntimeException¶ Thrown when attempting to save task with already existing task name.
TaskNotFoundException¶
-
public class
TaskNotFoundException
extends IllegalArgumentException¶ Thrown when task with given ID doesn’t exists.
TriggerNotFoundException¶
TriggerRetrievalException¶
-
public class
TriggerRetrievalException
extends RuntimeException¶ Thrown when there were problems while retrieving trigger(s).
ValidationException¶
-
public class
ValidationException
extends IllegalArgumentException¶ Thrown when there were problems while validating
org.motechproject.tasks.json¶
TaskConfigDeserializer¶
-
public class
TaskConfigDeserializer
extends JsonDeserializer<TaskConfig>¶ JsonDeserializer
forTaskConfig
class.
Methods¶
deserialize¶
-
public TaskConfig
deserialize
(JsonParser parser, DeserializationContext context)¶
org.motechproject.tasks.repository¶
ChannelsDataService¶
-
public interface
ChannelsDataService
extends MotechDataService<Channel>¶ Data service for channels.
DataProviderDataService¶
-
public interface
DataProviderDataService
extends MotechDataService<TaskDataProvider>¶ Data Service for data providers.
Methods¶
findByName¶
-
TaskDataProvider
findByName
(String name)¶ Returns the data provider with the given name.
Parameters: - name – the name of the data provider
Returns: the provider with the given name
TaskActivitiesDataService¶
-
public interface
TaskActivitiesDataService
extends MotechDataService<TaskActivity>¶ Data service for task activities.
Fields¶
Methods¶
byActivityTypes¶
-
List<TaskActivity>
byActivityTypes
(Set<TaskActivityType> activityTypes, QueryParams queryParams)¶ Returns the list of activities of specified type and with QueryParams for pagination support.
Parameters: - activityTypes – the set of activity types
- queryParams – the query parameters to use
Returns: the list of matching task activities
byActivityTypesAndDate¶
-
List<TaskActivity>
byActivityTypesAndDate
(Set<TaskActivityType> activityTypes, Range<DateTime> dateRange, QueryParams queryParams)¶ Returns the list of activities of specified type, the given date range and with QueryParams for pagination support.
Parameters: - activityTypes – the set of activity types
- dateRange – the range of date
- queryParams – the query parameters to use
Returns: the list of matching task activities
byActivityTypesAndIds¶
-
List<TaskActivity>
byActivityTypesAndIds
(Set<TaskActivityType> activityTypes, Set<Long> activityIds, QueryParams queryParams)¶ Returns the list of activities of specified type, id and with QueryParams for pagination support.
Parameters: - activityTypes – the set of activity types
- activityIds – the set of activity ids
- queryParams – the query parameters to use
Returns: the list of matching task activities
byActivityTypesIdsAndDate¶
-
List<TaskActivity>
byActivityTypesIdsAndDate
(Set<TaskActivityType> activityTypes, Set<Long> activityIds, Range<DateTime> dateRange, QueryParams queryParams)¶ Returns the list of activities of specified type, id, the given date range and with QueryParams for pagination support.
Parameters: - activityTypes – the set of activity types
- activityIds – the set of activity ids
- dateRange – the range of date
- queryParams – the query parameters to use
Returns: the list of matching task activities
byTask¶
-
List<TaskActivity>
byTask
(Long task)¶ Returns the list of activities for the given task id.
Parameters: - task – the id of the task, null returns empty list
Returns: the list of matching task activities
byTaskAndActivityTypes¶
-
List<TaskActivity>
byTaskAndActivityTypes
(Long task, Set<TaskActivityType> activityTypes, QueryParams queryParams)¶ Returns the list of activities for the given task id, of specified type and with QueryParams for pagination support.
Parameters: - task – the id of the task
- activityTypes – the set of activity types
- queryParams – the query parameters to use
Returns: the list of matching task activities
byTaskAndActivityTypesAndDate¶
-
List<TaskActivity>
byTaskAndActivityTypesAndDate
(Long task, Set<TaskActivityType> activityTypes, Range<DateTime> dateRange, QueryParams queryParams)¶ Returns the list of activities for the given task id, of specified type, the given date range and with QueryParams for pagination support.
Parameters: - task – the id of the task
- activityTypes – the set of activity types
- dateRange – the range of date
- queryParams – the query parameters to use
Returns: the list of matching task activities
byTaskAndActivityTypesAndIds¶
-
List<TaskActivity>
byTaskAndActivityTypesAndIds
(Long task, Set<TaskActivityType> activityTypes, Set<Long> activityIds, QueryParams queryParams)¶ Returns the list of activities for the given task id, of specified type, id and with QueryParams for pagination support.
Parameters: - task – the id of the task
- activityTypes – the set of activity types
- activityIds – the set of activity ids
- queryParams – the query parameters to use
Returns: the list of matching task activities
byTaskAndActivityTypesIdsAndDate¶
-
List<TaskActivity>
byTaskAndActivityTypesIdsAndDate
(Long task, Set<TaskActivityType> activityTypes, Set<Long> activityIds, Range<DateTime> dateRange, QueryParams queryParams)¶ Returns the list of activities for the given task id, of specified type and id, the given date range and with QueryParams for pagination support.
Parameters: - task – the id of the task
- activityTypes – the set of activity types
- activityIds – the set of activity ids
- dateRange – the range of date
- queryParams – the query parameters to use
Returns: the list of matching task activities
countByActivityTypes¶
-
long
countByActivityTypes
(Set<TaskActivityType> activityTypes)¶ Returns the count of all the task activities
Returns: the count of all task activities
countByActivityTypesAndDate¶
-
long
countByActivityTypesAndDate
(Set<TaskActivityType> activityTypes, Range<DateTime> dateRange)¶ Returns the count of all the task activities based on the given activity types and the given date range
Returns: the count of task activities
countByActivityTypesAndIds¶
-
long
countByActivityTypesAndIds
(Set<TaskActivityType> activityTypes, Set<Long> activityIds)¶ Returns the count of all the task activities
Parameters: - activityTypes – the set of activity types
- activityIds – the set of activity ids
Returns: the count of all task activities
countByActivityTypesIdsAndDate¶
-
long
countByActivityTypesIdsAndDate
(Set<TaskActivityType> activityTypes, Set<Long> activityIds, Range<DateTime> dateRange)¶ Returns the count of all the task activities based on the given activity types, id and the given date range.
Parameters: - activityTypes – the set of activity types
- activityIds – the set of activity ids
- dateRange – the range of date
Returns: the count of task activities
countByTaskAndActivityTypes¶
-
long
countByTaskAndActivityTypes
(Long task, Set<TaskActivityType> activityTypes)¶ Returns the count of activities for the given task id and of specified type.
Parameters: - task – the id of the task
- activityTypes – the set of activity types
Returns: the count of matching task activities
countByTaskAndActivityTypesAndDate¶
-
long
countByTaskAndActivityTypesAndDate
(Long task, Set<TaskActivityType> activityTypes, Range<DateTime> dateRange)¶ Returns the count of activities for the given task id, of specified type and the given date range.
Parameters: - task – the id of the task
- activityTypes – the set of activity types
- dateRange – the range of date
Returns: the count of matching task activities
countByTaskAndActivityTypesAndIds¶
-
long
countByTaskAndActivityTypesAndIds
(Long task, Set<TaskActivityType> activityTypes, Set<Long> activityIds)¶ Returns the count of activities for the given task id, specified activity type and id.
Parameters: - task – the id of the task
- activityTypes – the set of activity types
- activityIds – the set of activity ids
Returns: the count of matching task activities
countByTaskAndActivityTypesIdsAndDate¶
-
long
countByTaskAndActivityTypesIdsAndDate
(Long task, Set<TaskActivityType> activityTypes, Set<Long> activityIds, Range<DateTime> dateRange)¶ Returns the count of activities for the given task id, of specified type, id and the given date range.
Parameters: - task – the id of the task
- activityTypes – the set of activity types
- activityIds – the set of activity ids
- dateRange – the range of date
Returns: the count of matching task activities
TasksDataService¶
-
public interface
TasksDataService
extends MotechDataService<Task>¶ Data service for tasks.
TriggerEventsDataService¶
-
public interface
TriggerEventsDataService
extends MotechDataService<TriggerEvent>¶ Responsible for fetching and counting static triggers.
Methods¶
byChannelModuleName¶
-
List<TriggerEvent>
byChannelModuleName
(String moduleName, QueryParams queryParams)¶
byChannelModuleNameAndSubject¶
-
TriggerEvent
byChannelModuleNameAndSubject
(String moduleName, String subject)¶
bySubject¶
-
TriggerEvent
bySubject
(String subject)¶
org.motechproject.tasks.service¶
ChannelService¶
Methods¶
addOrUpdate¶
channelExists¶
delete¶
getAllChannels¶
getChannel¶
registerChannel¶
-
void
registerChannel
(ChannelRequest channelRequest)¶ Registers the given channel with the task module.
Parameters: - channelRequest – the channel request, not null
registerChannel¶
-
void
registerChannel
(InputStream stream, String moduleName, String moduleVersion)¶ Registers channel from the given stream for the given module. The input stream should contain the JSON definition of the channel.
Parameters: - stream – the channel JSON definition as a stream, not null
- moduleName – the name of the module
- moduleVersion – the version of the module
DynamicChannelLoader¶
-
public interface
DynamicChannelLoader
¶ Service responsible for loading dynamic triggers and action from modules which provides an instance of the
DynamicChannelProvider
.
Methods¶
channelExists¶
-
boolean
channelExists
(String moduleName)¶ Checks whether module with the given
moduleName
provides an implementation of theDynamicChannelProvider
.Parameters: - moduleName – the name of the module
Returns: true if module provides the implementation, false otherwise
countByChannelModuleName¶
getDynamicTriggers¶
-
List<TriggerEvent>
getDynamicTriggers
(String moduleName, int page, int pageSize)¶ Returns a list of triggers based on the given
moduleName
,page
andpageSize
.Parameters: - moduleName – the name of the module
- page – the number of the page
- pageSize – the size of the page
Returns: list of triggers
getTrigger¶
-
TriggerEvent
getTrigger
(TaskTriggerInformation triggerInformation)¶ Returns a trigger matching the information provided with the
triggerInformation
.Parameters: - triggerInformation – the information about the trigger
Returns: the matching trigger
providesDynamicTriggers¶
validateTrigger¶
DynamicChannelProvider¶
-
public interface
DynamicChannelProvider
¶ Responsible for providing dynamic triggers and actions for existing task channels.
Methods¶
countTriggers¶
-
long
countTriggers
()¶ Returns the amount of the provided triggers.
Returns: the number of provided triggers
getTrigger¶
-
TriggerEvent
getTrigger
(TaskTriggerInformation info)¶ Returns a trigger based on the given
info
.Parameters: - info – the information about the trigger
Returns: the trigger with the given subject if it exists, null otherwise
getTriggers¶
-
List<TriggerEvent>
getTriggers
(int page, int pageSize)¶ Returns a list of triggers based on the given
page
andpageSize
.Parameters: - page – the number of the page
- pageSize – the size of the page
Returns: the list of triggers
TaskActivityService¶
-
public interface
TaskActivityService
¶ Service for managing task activities. Task activities are used for storing information about current and past task executions.
Methods¶
addFailedExecution¶
addFilteredExecution¶
addSuccessfulExecution¶
addTaskDisabledWarning¶
addTaskFiltered¶
addTaskStarted¶
addWarning¶
addWarningWithException¶
deleteActivitiesForTask¶
getAllActivities¶
-
List<TaskActivity>
getAllActivities
(Set<TaskActivityType> activityTypeSet, QueryParams queryParams, boolean lastExecution)¶ Returns all the activities as a list.
Parameters: - activityTypeSet – the type of activities
- queryParams – query parameters to use while retrieving
- lastExecution –
Returns: the list of all activities
getAllActivities¶
-
List<TaskActivity>
getAllActivities
(Set<TaskActivityType> activityTypes, Range<DateTime> dateRange, QueryParams queryParams, boolean lastExecution)¶ Returns all the activities as a list.
Parameters: - activityTypes – the type of activities
- dateRange – the date range
- queryParams – query parameters to use while retrieving
- lastExecution –
Returns: the list of all activities
getAllTaskActivitiesCount¶
-
long
getAllTaskActivitiesCount
(Set<TaskActivityType> activityTypes, boolean lastExecution)¶ Returns the count of all activities.
Parameters: - activityTypes – the type of activities to include in count
- lastExecution –
Returns: the count of matching activities
getAllTaskActivitiesCount¶
-
long
getAllTaskActivitiesCount
(Set<TaskActivityType> activityTypes, Range<DateTime> dateRange, boolean lastExecution)¶ Returns the count of all activities.
Parameters: - activityTypes – the type of activities to include in count
- dateRange – the date range
- lastExecution –
Returns: the count of matching activities
getLatestActivities¶
-
List<TaskActivity>
getLatestActivities
()¶ Returns 10 most recent activities as a list, ordered by date.
Returns: the list of all activities
getTaskActivities¶
-
List<TaskActivity>
getTaskActivities
(Long taskId, Set<TaskActivityType> activityTypeSet, QueryParams queryParams, boolean lastExecution)¶ Returns list of all activities for task with the given ID.
Parameters: - taskId – the task ID, null returns null
- activityTypeSet – the type of activities
- queryParams – query parameters to use while retrieving
- lastExecution –
Returns: the list of all activities for task with given ID
getTaskActivities¶
-
List<TaskActivity>
getTaskActivities
(Long taskId, Set<TaskActivityType> activityTypeSet, Range<DateTime> dateRange, QueryParams queryParams, boolean lastExecution)¶ Returns list of all activities for task with the given ID, of specific activity type and the given date range.
Parameters: - taskId – the task ID, null returns null
- activityTypeSet – the type of activities
- dateRange – the range of datetime
- queryParams – query parameters to use while retrieving
- lastExecution –
Returns: the list of all activities for task with given ID
getTaskActivitiesCount¶
-
long
getTaskActivitiesCount
(Long taskId, Set<TaskActivityType> activityTypes, boolean lastExecution)¶ Returns the count of all activities for the given task, of the specified type.
Parameters: - taskId – the task ID
- activityTypes – the type of activities to include in count
- lastExecution –
Returns: the count of matching activities
getTaskActivitiesCount¶
-
long
getTaskActivitiesCount
(Long taskId, TaskActivityType type)¶ Returns the count of all activities for the given task, of the specified type.
Parameters: - taskId – the task ID
- type – the type of activity to include in count
Returns: the count of matching activities
getTaskActivitiesCount¶
-
long
getTaskActivitiesCount
(Long taskId, Set<TaskActivityType> activityTypes, Range<DateTime> dateRange, boolean lastExecution)¶ Returns the count of all activities for the given task, of the specified type and the given date range.
Parameters: - taskId – the task ID
- activityTypes – the type of activities to include in count
- dateRange – the range of datetime
- lastExecution –
Returns: the count of matching activities
getTaskActivityById¶
-
TaskActivity
getTaskActivityById
(Long activityId)¶ Returns single TaskActivity with given activity ID.
Parameters: - activityId – the ID of activity instance to be retrieved
Returns: TaskActivity with the given ID
TaskDataProviderService¶
-
public interface
TaskDataProviderService
¶ Service for managing data providers.
Methods¶
getProvider¶
-
TaskDataProvider
getProvider
(String name)¶ Returns the data provider with the given name.
Parameters: - name – the name of the data provider, null returns null
Returns: the data provider with the given name, null if
name
was null
getProviderById¶
-
TaskDataProvider
getProviderById
(Long providerId)¶ Returns the data provider with the given ID.
Parameters: - providerId – the ID of the data provider, null returns null
Returns: the data provider with the given ID, null if
name
was null
getProviders¶
-
List<TaskDataProvider>
getProviders
()¶ Returns all data providers.
Returns: the list of all data providers
registerProvider¶
registerProvider¶
-
void
registerProvider
(InputStream stream)¶ Registers the data provider defined by the JSON represented by the given stream.
Parameters: - stream – the data provider as stream, not null
TaskService¶
-
public interface
TaskService
¶ Service interface for managing tasks.
Methods¶
deleteTask¶
exportTask¶
findActiveTasksForTrigger¶
-
List<Task>
findActiveTasksForTrigger
(TriggerEvent trigger)¶ Returns the list of active tasks with the given trigger. Used for retrieving tasks to execute when a given trigger fires.
Parameters: - trigger – the trigger, null returns empty list
Returns: the list of active tasks
findActiveTasksForTriggerSubject¶
findCustomParser¶
-
TasksEventParser
findCustomParser
(String name)¶ Looks for implementations of the
org.motechproject.commons.api.TasksEventParser
that have been exposed as OSGi services by bundles. For all found implementations, this method will match names returned by thegetName()
method of theTasksEventParser
and passed as parameter to this method. If a match is found, the implementation is returned.Parameters: - name – A name of the parser, that will be matched with
getName()
of the implementations
Returns: Implementation of the
org.motechproject.commons.api.TasksEventParser
that returns the same name viagetName()
method as the name passed to the method- name – A name of the parser, that will be matched with
findTasksByName¶
findTasksDependentOnModule¶
getActionEventFor¶
-
ActionEvent
getActionEventFor
(TaskActionInformation taskActionInformation)¶ Returns the action event that matches the given information about the task action.
Parameters: - taskActionInformation – the action information, not null
Throws: - ActionNotFoundException – when action was not found
Returns: the action event matching the given information
getTask¶
importTask¶
save¶
TaskWebService¶
-
public interface
TaskWebService
¶ This interface is used by task controllers to work with dto objects.
Methods¶
getAllActivities¶
-
List<TaskActivityDto>
getAllActivities
(Set<TaskActivityType> activityTypeSet, QueryParams queryParams, boolean lastExecution)¶ See also:
TaskActivityService.getAllActivities(Set,QueryParams,boolean)
getAllActivities¶
-
List<TaskActivityDto>
getAllActivities
(Set<TaskActivityType> activityTypeSet, Range<DateTime> dateRange, QueryParams queryParams, boolean lastExecution)¶ See also:
TaskActivityService.getAllActivities(Set,Range,QueryParams,boolean)
getAllChannels¶
-
List<ChannelDto>
getAllChannels
()¶ See also:
ChannelService.getAllChannels()
getAllTasks¶
-
List<TaskDto>
getAllTasks
()¶ See also:
TaskService.getAllTasks()
getDynamicTriggers¶
-
List<TriggerEventDto>
getDynamicTriggers
(String moduleName, int page, int pageSize)¶ See also:
TriggerEventService.getDynamicTriggers(String,int,int)
getLatestActivities¶
-
List<TaskActivityDto>
getLatestActivities
()¶
getProviders¶
-
List<TaskDataProviderDto>
getProviders
()¶ See also:
TaskDataProviderService.getProviders()
getStaticTriggers¶
-
List<TriggerEventDto>
getStaticTriggers
(String moduleName, int page, int pageSize)¶ See also:
TriggerEventService.getStaticTriggers(String,int,int)
getTask¶
-
TaskDto
getTask
(Long taskId)¶ See also:
TaskService.getTask(Long)
getTaskActivities¶
-
List<TaskActivityDto>
getTaskActivities
(Long taskId, Set<TaskActivityType> activityTypeSet, QueryParams queryParams, boolean lastExecution)¶ See also:
TaskActivityService.getTaskActivities(Long,Set,QueryParams,boolean)
getTaskActivities¶
-
List<TaskActivityDto>
getTaskActivities
(Long taskId, Set<TaskActivityType> activityTypeSet, Range<DateTime> dateRange, QueryParams queryParams, boolean lastExecution)¶ See also:
TaskActivityService.getTaskActivities(Long,Set,Range,QueryParams,boolean)
getTrigger¶
-
TriggerEventDto
getTrigger
(TaskTriggerInformation triggerInformation)¶ See also:
TriggerEventService.getTrigger(TaskTriggerInformation)
save¶
-
Set<TaskErrorDto>
save
(Task task)¶ See also:
TaskService.save(Task)
setEnabledOrDisabled¶
-
void
setEnabledOrDisabled
(Task task)¶ See also:
TaskService.setEnabledOrDisabled(Task)
TriggerEventService¶
-
public interface
TriggerEventService
¶ Service responsible for retrieving, counting and validating triggers.
Methods¶
countDynamicTriggers¶
countStaticTriggers¶
getDynamicTriggers¶
-
List<TriggerEvent>
getDynamicTriggers
(String moduleName, int page, int pageSize)¶ Returns a list of dynamic triggers currently provided by the channel with the given
moduleName
based on the given page and page size.Parameters: - moduleName – the name of the channel module
- page – the number of the page
- pageSize – the size of the page
Returns: list of dynamic triggers
getStaticTriggers¶
-
List<TriggerEvent>
getStaticTriggers
(String moduleName, int page, int pageSize)¶ Returns a list of static triggers currently provided by the channel with the given
moduleName
based on the given page and page size.Parameters: - moduleName – the name of the channel module
- page – the number of the page
- pageSize – the size of the page
Returns: list of static triggers
getTrigger¶
-
TriggerEvent
getTrigger
(TaskTriggerInformation triggerInformation)¶ Returns a trigger based on the information given in the
triggerInformation
.Parameters: - triggerInformation – the information about a trigger
Returns: the trigger it exists, null otherwise
providesDynamicTriggers¶
triggerExists¶
-
boolean
triggerExists
(TaskTriggerInformation triggerInformation)¶ Checks whether trigger matching the given information exists.
Parameters: - triggerInformation – the information about a trigger
Returns: true if matching trigger exists, false otherwise
validateTrigger¶
-
Set<TaskError>
validateTrigger
(TaskTriggerInformation triggerInformation)¶ Checks if the given trigger is valid by checking if related channel exists and if it provides a trigger matching the given
triggerInformation
.Parameters: - triggerInformation – the information about a trigger
Returns: list of error related with the trigger validation
TriggerHandler¶
-
public interface
TriggerHandler
¶ Service responsible for handling triggers. When registered for an event with a specific subject, it will act as MotechEvent listener for it. That means, when the event with the subject handled by this handler is fired, the handler will retrieve all active tasks with triggers corresponding to this event and execute them.
Methods¶
addDataProvider¶
-
void
addDataProvider
(DataProvider provider)¶ Adds
org.motechproject.commons.api.DataProvider
for this handler.Parameters: - provider – DataProvider to be added
handle¶
-
void
handle
(MotechEvent event)¶ Handles the given event. This method is responsible for retrieving active tasks with triggers corresponding to this event and then executing them. It is called by the event system.
Parameters: - event – the event, not null
Throws: - TriggerNotFoundException – if the trigger for the given event wasn’t found
handleRetry¶
-
void
handleRetry
(MotechEvent event)¶ Handles the given event. This method is responsible for handling task retry.
Parameters: - event – the event, not null
registerHandlerFor¶
-
void
registerHandlerFor
(String subject)¶ Registers this handler to listen for events with the given subject. This handler will now act as a MotechEvent listener for the given subject and will get called by the event system when an event with the given subject is fired.
Parameters: - subject – the event subject, not null
registerHandlerFor¶
-
void
registerHandlerFor
(String subject, boolean isRetryHandler)¶ Registers this handler to listen for events with the given subject. This handler will now act as a MotechEvent listener for the given subject and will get called by the event system when an event with the given subject is fired. If a task is using retry system, the additional retry handler should be registered. The flag isRetryHandler should be use to choose what kind of handler will be registered.
Parameters: - subject – the event subject, not null
- isRetryHandler – true if handler is for task retry system; false otherwise
removeDataProvider¶
-
void
removeDataProvider
(String taskDataProviderId)¶ Removes
org.motechproject.commons.api.DataProvider
from this handler.Parameters: - taskDataProviderId – ID of the DataProvider to be removed, passed as a String
org.motechproject.tasks.service.osgi¶
DataProviderManager¶
-
public class
DataProviderManager
implements OsgiServiceLifecycleListener¶ Service for managing data providers.
Constructors¶
DataProviderManager¶
-
public
DataProviderManager
(TaskDataProviderService taskDataProviderService)¶
DataProviderManager¶
-
public
DataProviderManager
(TriggerHandler handler, TaskDataProviderService taskDataProviderService)¶ Service constructor.
Parameters: - handler – the task trigger handler
- taskDataProviderService – the task data provider service, not null
Acknowledgements¶
The MOTECH team would like to acknowledge the following companies for providing free software.
Balsamiq¶
Balsamiq Mockups is a rapid wireframing tool that helps you Work Faster & Smarter. It reproduces the experience of sketching on a whiteboard, but using a computer.
GitHub¶
GitHub. Build software better, together. Powerful collaboration, code review, and code management for open source and private projects.
JetBrains¶
Intellij IDEA. The Most Intelligent Java IDE. Excel at enterprise, mobile and web development with Java, Scala and Groovy, with all the latest modern technologies and frameworks available out of the box.
PyCharm. The Most Intelligent Python IDE. Enjoy productive Python, Django, and Web development with PyCharm, an intelligent Python IDE offering unique coding experience.
YourKit¶
YourKit supports open source projects with its full-featured Java Profiler.
YourKit, LLC is the creator of YourKit Java Profiler and YourKit .NET Profiler, innovative and intelligent tools for profiling Java and .NET applications.
Frequently Asked Questions¶
This page contains frequently asked questions about MOTECH with short answers to them.
Contents
- Frequently Asked Questions
- Can MOTECH run on Windows?
- Is MDS using any caching? How does that affect a cluster deployment?
- How to use SSL for database connections in MOTECH?
- MOTECH is not working as expected, how can I check what’s wrong?
- I am getting blueprint timeout error - what does it mean?
- I am getting IllegalArgumentException (object is not an instance of declaring class) - what does it mean?
- How to create a web-service with MOTECH?
- I’m unable to build docker containers because of missing packages in Ubuntu repositories.
- How to debug the T7 plugin instance of Tomcat during integration tests? (in platform/server for example)
- Why am I not seeing anything in “Admin Queues and Topics”?
Can MOTECH run on Windows?¶
MOTECH is available and can be deployed on Windows, but Windows is not actively supported as a platform.
Is MDS using any caching? How does that affect a cluster deployment?¶
MDS is using the DataNucleus persistence framework, which by default uses level1 and level2 cache. It can cause data inconsistency
across multiple server nodes in cluster deployment. To resolve this issue you can turn off level2 cache by setting
datanucleus.cache.level2.type
property to none
. There may be slight performance drop per server in result of
turning off level2 cache. Level1 cache should be kept as it works within one transaction, therefore not affecting
cluster deployment.
More information about the DataNucleus can be found on it project page (link). There is also available caching doc.
How to use SSL for database connections in MOTECH?¶
First generate and install your SSL certificates. After this is done you will need to configure your database to use SSL. For MySQL you can follow instructions from official MySQL page. Next step is to point JVM variables to your SSL certificates. Look at the Oracle documentation for more information about these variables.
In order to establish a secure SSL connection the JDBC URL needs to be updated with the JDBC driver property 'useSSL'=true'
eg. if you are using mySQL at localhost the JDBC URL should be jdbc:mysql://localhost:3306/dbname?useSSL=true
. As the URL
entered on the MOTECH bootstrap page is only the base for actual database connections urls, you should provide SSL parameter
to appropriate config files.
For MDS it can be set by editing ~/.motech/config/datanucleus_data.properties
and ~/.motech/config/datanucleus_schema.properties
files and changing the property javax.jdo.option.ConnectionURL
. For quartz you have to edit the variable
org.quartz.dataSource.motechDS.URL
in quartz.properties
. If your config source is FILE, then you have to edit the
file in scheduler directory in ~/.motech/config
. If your source is UI, you have to change the quartz configuration
through the manage modules section in the Admin UI.
MOTECH is not working as expected, how can I check what’s wrong?¶
All the problems that MOTECH encounters are logged. The logs can be checked in two ways. If MOTECH is working you can
access logs by choosing Server Log
from the Admin
panel on the UI. There you can also specify logging levels for
specific packages - this is done by selecting the desired log level in Server Log -> Log options
panel.
If access to UI is not possible, for standard MOTECH installations on Tomcat, logs can be also found in catalina.out
file located in the logs folder in the Tomcat installation. For example for MOTECH deployed on Tomcat 7.0.62 the catalina.out
is located in ~/apache-tomcat-7.0.62/logs
folder. The content of the log file can be displayed by any text editor.
I am getting blueprint timeout error - what does it mean?¶
Blueprint timeout errors are encountered when one of the modules has a reference to a service from another module defined in
blueprint.xml
file and that service has not been made available. By default blueprint extender waits 5 minutes for a required service,
if in this time service won’t be delivered the timeout error will be thrown. First step in resolving blueprint timeout
errors should be checking if the problematic service is correctly registered as an OSGi service. Below you can see an example
of a properly defined OSGi service:
<osgi:service ref="subscriptionService"
interface="org.motechproject.hub.service.SubscriptionService"
auto-export="interfaces" />
and importing it:
<osgi:reference id="hubTopicMDSService"
interface="org.motechproject.hub.mds.service.HubTopicMDSService" />
If the service is defined correctly and a blueprint timeout error is still encountered, it probably means that the module which should deliver the service didn’t start and further investigation for origin of the error should conducted. The real error will very often be printed in the logs above the timeout error.
I am getting IllegalArgumentException (object is not an instance of declaring class) - what does it mean?¶
The cause is probably that you have different versions of bundles running at the same time. To solve this issue clean up your
bundles directory and WAR file. For standard MOTECH installations on Tomcat the bundles directory is ~/.motech/bundles
and deployed WAR file can be found in ~/apache-tomcat-<version>/webapps
.
How to create a web-service with MOTECH?¶
Creating a web-service with MOTECH can be done using Spring Web Services framework, which is the suggested approach. First add all required dependencies. The most important dependencies that you need to use are:
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-core</artifactId>
<version>2.0.4.RELEASE</version>
</dependency>
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.6</version>
</dependency>
<dependency>
<groupId>org.apache.servicemix.bundles</groupId>
<artifactId>org.apache.servicemix.bundles.saaj-impl</artifactId>
<version>1.3.9_2</version>
</dependency>
After adding all required dependencies for Spring Web Services you should provide a contract definition as XSD file and endpoint classes for your exposed services. For example if you want to expose a simple service returning information about books, your XSD file could look like this:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="urn:books">
<xs:element name="getBook">
<xs:complexType>
<xs:sequence>
<xs:element name="author" type="xs:string"/>
<xs:element name="year" type="xs:int"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Then you should define an endpoint class for handling the getBook element, which could look like this:
@Endpoint
public class BookEndpoint {
private BookService bookservice;
//constructors
@PayloadRoot(namespace = "urn:books", localPart = "getBook")
@ResponsePayload
public GetBookResponse getBook(@RequestPayload GetBookRequest request) {
GetBookResponse response = new GetBookResponse();
response.setBook(bookservice.getBook());
return response;
}
}
More details about Spring Web Services can be found at it project page.
I’m unable to build docker containers because of missing packages in Ubuntu repositories.¶
Try building the container with --no-cache
.
How to debug the T7 plugin instance of Tomcat during integration tests? (in platform/server for example)¶
First export the CATALINA_OPTS variable with a value that will enable debugging, for example:
export CATALINA_OPTS=-agentlib:jdwp=transport=dt_socket,address=8000,server=y,suspend=n
Next, run the integration tests as you would normally do, for example:
mvn clean install -PIT
Then connect to Tomcat using a remote debugger on port 8000, same as when normally debugging Tomcat.
Why am I not seeing anything in “Admin Queues and Topics”?¶
Edit ActiveMQ broker configuration, which is in the file /etc/activemq/instances-enabled/main/activemq.xml
.
Change or add the following attribute to the broker element:
<broker useJmx="true">
The next step is to restart ActiveMQ. To restart ActiveMQ use
sudo service activemq restart
If the issue still appears, restart MOTECH (Tomcat).