Programmer’s Guide to `profilegrid-app` ======================================= Martin Stein <> v1.0, February, 3rd 2020 The `profilegrid-app` resources ------------------------------- ### Git based Source Code You can find the source code for the `profilegrid-app` here: ### Logging (would like to see Graylog link and good filtering options here) Things to know when facing problems with the `profilegrid-app` -------------------------------------------------------------- ### Reading the logs might not helping a lot Inside the `profilegrid-app` logging is done in many places (quantity) but the quality is often not sufficient for taking immediately the right conclusions. In most cases further analysis is needed. The main reason for this is, that the exception handling is very basic, does normally not provide messages with a higher level of (abstraction) information than the underlying JAPC exceptions. **NOTE!** This is something which should be improved in the future (more reasons why this is still in a insufficient state could be given here, eg. 90 % of problems are caused by the devices). ### Check the state of the involved devices > **Important** > > To the time of writing the usual entry point of analysis is the status > check of the involved devices (from outside the profilegrid-app). Checking the status of the involved devices is usually done by calling the devices with the help of external applications. The involved devices are the profile grids **and** their actuators. They can be checked by tools like `devstatus`, `prophelper` or `pdex`. You can execute these programs in a terminal on the `asl-cluster`. On the `asl-cluster` tools like `devstatus`, `prophelper` or `pdex` are located in `/common/usr/cscofe/bin/`. Here you can see as an example a `pdex` call in [Screenshot 1](#anchor-1). Please note the `-d` after the command to specify the device, here `gts1dg5`. **Screenshot 1. pdex command.** ![pdex](./pdex01.png) With the `pdex` call you are able to check the general status bits and easily check if the device is powered on (Bit 0) or if there are interlocks or errors (Bit 5-7). If the device is an `offline` state you will see a message like shown in [Screenshot 2](#anchor-2) on the command prompt. Here the example shows the `devstatus` application, best suited for the `offline` check. You specify the device to analyse right after the `devstatus` command. **Screenshot 2. devicestatus command.** ![pdex](./devstatus01.png) **NOTE!** In the future it should be possible the check the state of the involved devices inside the profilegrid-app. The way a profile grid is represented in the `profilegrid-app` is always a combination (unit) of two devices, the profile grid device itself and its acutator. In [Screenshot 3](#anchor-3) you can see which parts of the control panel of a profile grid in the `profilegrid-app` belong to its actuator. **Screenshot 3. `profilegrid-app` panel actuator controls.** ![pdex](./profilegrid_one_control_panel_actuator.png) > **Important** > > Check device status of both devices, the profile grid itself and its > actuator. To be able to check the status of an actuator of a profile grid you need to know how the nomenclature of the actuator is called. One way to get nomenclature is by using a wildcard \* with the `devstatus` tool on the `asl-cluster` like shown in [Screenshot 4](#anchor-4). A typical command would be eg. `devstatus GTE1DG1*`. `GTE1DG1` is the nomenclature for the profile grid in question. The result would give you the nomenclature `GTE1DG1_P`, the pneumatic actuator the profile grid `GTE1DG1` is mounted on. **Screenshot 4. Using wildcard syntax in `devstatus`.** ![devstatus with wildcard](./devstatus02.png) The given example of profile grid `GTE1DG1` and its actuator `GTE1DG1_P` showcases the most common combination in the means that the actuator is from type pneumatic. More examples are given in the following table including profile grid `GTS1DG5` which has two corresponding actuators, where at the time of writing `GTS1DG5_S` is the actual one.
Typical Actuator Nomeclatures
Profile Grid Name Corresponding Actuator Name Actuator Type

GHTADG2G

GHTADG2GP

Pneumatic

GTS1DG5

GTS1DG5_P, GTS1DG5_S

Pneumatic, Stepping (Stepping is the right)

GTS2DG2

GTS2DG2_S

Stepping

Which actions to consider if status messages indicate problems with a profile grid ---------------------------------------------------------------------------------- > **Important** > > 1. If a profile grid or its actuator creates **error** or **offline** > messages, check again with the operators or the shift leader if > the device should really be in functional state. > > 2. If 1. is confirmed and a profile grid or its actuator is > **offline** ask for Beam Diagnostics On Call support. > > 3. If 1. is confirmed and a profile grid or its actuator shows an > **error** message ask for Frontend On Call and/or Beam Diagnostics > On Call support. > Software development insights ----------------------------- ### Starting `profilegrid-app` with `Maven` From the command line start the application with `mvn -Prun,pro-3tier`. Starting the application provokes a `Warning` because of the use of two frameworks: 1. the `CERN JavaFX Application Framework` (interface classes are `FxmlView` and `ApplicationBase`) 2. and `Griffon`, further details see below The `Warning` looks like this: java.lang.ClassCastException: class griffon.javafx.JavaFXGriffonApplication cannot be cast to class cern.accsoft.gui.application.ApplicationBase (griffon.javafx.JavaFXGriffonApplication and cern.accsoft.gui.application.ApplicationBase are in unnamed module of loader java.net.URLClassLoader and is not critical to the time of writing. ### Update, Upgrade or Release Procedures and `Maven POM` file editing The `profilegrid-app` uses two (2!) `Maven POM` files to profit from a `Parent POM` the `Griffon framework` provides. Additionally it uses is the normal `Parent POM`, the artifact `csco-parent-java-bundle`. > **Important** > > 1. `profilegrid-app/pom.xml` is the usual place for dependency > declarations like e.g. artifact `common-context-widget` but not > for the normal `Parent POM`, artifact `csco-parent-java-bundle`. > > 2. `profilegrid-app/griffon-app/pom.xml` is where the `Parent POM` > `csco-parent-java-bundle` belongs to and nothing else. > To see the two `POM’S` in the directory tree, see the [full directory](#anchor-5) of the`profilegrid-app`. ### `profilegrid-app` uses application framework `Griffon` The [Griffon framework](http://griffon-framework.org/guide/2.15.1) is the reference implementation of the [JSR-377](https://jcp.org/en/jsr/detail?id=377) of the Java Community Program (JCP). The [JSR-377](https://jcp.org/en/jsr/detail?id=377) has the goal to define an API for common behavior shared by many desktop and mobile applications. Most applications require the following features: - **dependency injection via [JSR-330](https://github.com/javax-inject/javax-inject).** - **common application structure.** - **application life-cycle.** - localized resources. - resource injection. - localized configuration. - **decouple state from UI (binding).** - persistence session state (preferences). - **action management.** - **component life-cycle.** - light-weight event bus. - honor threading concerns (specific to UI toolkit). - application extensibility via plugins (implies modularity). The `profilegrid-app` is using the **bold** features with the help of the `Griffon` framework. Another set of the advantages using `Griffon` --------------------------------------------- - Convention over Configuration - Don’t Repeat Yourself (DRY) - **Pervasive MVC** - Testing supported "out of the box" ### The 'common application structure used' by the `profilegrid-app` **Full directory tree, pom files not mandatory.** ├── griffon-app │ ├── conf │ ├── controllers │ ├── i18n │ ├── lifecycle │ ├── models │ ├── resources │ ├── services │ ├── views │ └── pom.xml ├── pom.xml └── src ├── functional-test │ └── java ├── integration-test │ └── java ├── main │ ├── java │ └── resources └── test ├── java └── resources **Directories supporting directly the Griffon framework.** ├── griffon-app │ ├── conf │ ├── controllers │ ├── models | ├── resources │ ├── services │ ├── views Further abstraction of the `Griffon framework` is the Griffon `MVCGroup`, a composition of a view, a model and a controller. These three members of a `MVCGroup` (here named sample) are stored in the directories like this: **Files involved in one `MVCGroup`.** ├── griffon-app │ ├── conf ── Config.java │ ├── controllers ── SampleController.java │ ├── models ── SampleModel.java | ├── resources ── (sample.fxml) │ ├── services ── (AService.java) │ ├── views ── SampleView.java The file `Config.java` in directory `conf` serves the purpose to configure the `MVCGroup` in the framework. **Directory `conf` with this `Config.java` file for the `MVCGroup sample` configuration:.** public class Config extends AbstractMapResourceBundle { @Override protected void initialize(@Nonnull final Map entries) { map(entries) .e("application", map().e("name", "Profile Grid Application").e("title", "app-profilegrid") .e("startupGroups", asList("sample")).e("autoShutdown", true)) .e("mvcGroups", map().e("sample", map().e("model", "SampleModel") .e("view", "SampleView") .e("controller", "SampleController")) } } MVC Pattern used in the `profilegrid-app` ----------------------------------------- The `PresentationModel View Controller` (PMVC) pattern used in the `profilegrid-app` is a variation of the MVC. The `PresentationModel` is responsible for holding the information needed to display the application’s data and cares how data should be visualized, such as colors, fonts, etc. The `View` benefits from the `FX Bindings` that tie the data from the `PresentationModel` to the `View’s` UI elements. In the `profilegrid-app` the `View` can also directly provoke visual results and manipulate view aspects to optimize the visual user experience. Nonetheless the `View` must delegate all data input or output to its `Controller`. The `Controller` is the only one to manipulate the `PresentationModel` directly, completely oblivious about a specific `View`. This leads to a much more testable component, as the `PresentationModel` and `Controller` are completely separated from the `View`. [Figure 1](#anchor-6) shows visually how `PresentationModel`, `View` and `Controller` interact. **Figure 1. PMVC Pattern.** ![PMVC Pattern](./pmvc.png) MVC Pattern realizations and `Model`, `Controller`, `Service` injections without `Griffon` ------------------------------------------------------------------------------------------ Finally I want to remember, that G. Krug, O. Alves, J. Molinari and E. Roux with there CERN JavaFX work gave us everything in our hands to use eg. a (PMVC) pattern with injection of a Controller. By naming convention they resolve an existing half-developed controller and generate and add automatically fields and event handlers. See the article [Best practices for efficient development of JavaFX applications](https://cds.cern.ch/record/2305503/files/thapl02.pdf) of them to remember the features we already own in our codebase.