abas Software AG

This is the technical documentation for abas Essentials SDK⁺. It is written by developers for developers. For a more abstract view of the product visit https://abas-essentials-sdk.com.

Introduction

abas Essentials SDK⁺ is a software development kit intended to be used for customizing abas Essentials⁺.

abas Essentials SDK⁺ enables developers to handle all parts of an abas Essentials customization in one project. As abas Essentials SDK⁺ uses the technology of JFOP server Apps for code deployment in abas Essentials, abas Essentials SDK⁺ projects are called ESDK App⁺s.

The following abas Essentials customizations can be automated using abas Essentials SDK⁺:

  • Add logic and automated tests to the project using abas Java Objects (AJO) or other programming languages

  • Create/update data objects, enumerations and/or named types in abas Essentials

  • Add/update/delete variables from tables of variables

  • Create new additional tables of variables

  • Import customized database screens

  • Import Infosystems and Infosystem screens

  • Copy any files to $MANDANTDIR or sub-directories

  • Add/update lines to/in fop.txt

  • Add lines to mandantdir.env

  • Add lines to logging.custom.properties

ESDK Gradle Plugin

The core component of the ESDK⁺ toolset is the ESDK Gradle Plugin. It is the development tool for creating ESDK App⁺s.

As a Gradle Plugin it is easily integrable into IDEs such as abas Tools, Eclipse and Intellij Idea. All components of your ESDK App⁺ are exported from the abas ERP client into your project in the IDE and can be either modified directly in the IDE or re-installed in the abas ERP client, edited and re-exported.

This way all components of your ESDK App⁺ App are part of your local project and can be managed by version control.

As it is based on Gradle - a modern build automation tool - it is not only standardized in a way that makes it possible to use it in different infrastructures (IDE and platform independent) but can also be adapted by the ESDK App developer him- or herself.

ESDK App Installer

The ESDK App Installer⁺ is the deployment tool for ESDK App⁺.

It can be used by any abas Customer to install an ESDK App⁺ in any of his abas Essentials clients.

This way an ESDK App⁺ is developed once and can be distributed to any abas Customer. Using the ESDK App Installer⁺ so straight-forward that the Customer’s system administrator run the installation of the favored ESDK App⁺ without the help of the app’s developer or any other party.

1. Project setup

Setting up a new ESDK App Project⁺ for development.

1.1. Prerequisites

For development with abas Essentials SDK⁺ we recommend the following software and tools:

1.1.1. Software on your development machine

To develop an app, the following technologies must already be installed on your development machine:

  • JDK8, Java Development Kit

  • Gradle, a build automation tool

  • Docker, a software containerization platform

For further information take a look at the appropriate homepages.

1.1.2. Develpoment tools

  • an IDE (e.g. Eclipse, IntelliJ IDEA, abas Tools)

  • a commandline interface (bash, PowerShell, Terminal)

  • an abas Essentials client

  • a Nexus Artifact Server

You can use a dockerized abas Essentials client and Nexus Artifact Server or one or both as a self-hosted and self-administered instance.

1.1.3. abas Essentials and Nexus Artifact Server as Docker Containers

We recommend to develop with Docker containers.

download admonition To download the docker images and start the erp and nexus containers you can download the docker-compose.yml file and run

docker-compose up -d
The ESDK Project Builder generates a docker-compose.yml file for the abas Essentials version you have chosen as "Development Version".

Alternatively you can run the following two commands and do the naming and port mapping manually:

docker run --init -d --name erp -p 2205:22 -p 8001:80 -p 6560:6550 -p 48592:48392 -e ABAS_GUI_PORT=48592 -h dockerbau sdp.registry.abas.sh/abas/test:<version> run (1)

docker run -d --name nexus -p 8081:8081 sonatype/nexus:oss
1 Replace <version> with the version of abas Essentials you want to develop against, e.g. 2017r4n16p27.
For version 2016r4n13 you don’t need the option run
Using docker logs erp -f you can see all log messages during container start up.

1.1.4. Self-hosted and self-administered instances

If you already have an abas Essentials installation and/or a Nexus Artifact Server and want to use them for development, you can do so, too.

You need to make sure that your abas Essentials installation can access the Nexus Artifact Server. Otherwise the publishHomeDirJars and publishClientDirJars tasks will not work. Often when using an existing abas Essentials installation it does not have access to your local computer. If you want to use a dockerized Nexus Artifact Server you can also start it on the server your abas Essentials installation runs on.

2. Setup ESDK development environment

Set up a development environment for a new or an existing ESDK App⁺.

Overview abas ESDK development environment

2.1. Setup abas Essentials client and Nexus Artifact Server

2.1.1. Log in to the abas Partner Docker Registry

To access the abas Essentials Docker images you have to log in to the abas Partner Docker Registry.

docker login sdp.registry.abas.sh

Use your extranet credentials for authentication.

In order to be able to pull Docker images from the abas Partner Docker Registry you need to accept the License Agreement.

2.1.2. Start the containers

Start abas Essentials and Nexus Artifact Server containers as described in the Docker chapter.

2.2. Download and configure the mini-GUI

When the abas Essentials container is ready, open the following URL in the browser of your choice: http://<your-ip-address>:8001 Download abasgui-mini-erp.tgz and wineks-erp.ini. Unpack the abasgui-mini-erp.tgz archive, rename the wineks-erp.ini file to wineks.ini and copy it into the unpacked mini-GUI directory. Edit the wineks.ini file to look like this:

[wineks]
server   = erp
sprachen = Deutsch Englisch

[erp]
host=<your ip address> (1)
useEksd=true
portEksd=48592 (2)
client=/abas/erp
text=abasERP in Docker
1 Enter your IP address, your IP address can be determined by executing ifconfig (Linux/Mac) or ipconfig (Windows) in your preferred command line interface.
2 Enter the abas GUI port here, the port mapping is done in the docker run command you executed earlier, or is configured in the docker.compose.yml file.

2.3. Start abas Essentials

Start abas Essentials by running wineks.exe, or for newer abas Essentials clients abasgui.exe.

You can only run wineks.exe, or abasgui.exe on Windows. If you are on another operating system, you need to use a virtual machine to use the abas Essentials user interface (not for ESDK App⁺ development in general).

3. Create your ESDK App

3.1. Register your App ID

Go to the ESDK Developer Portal. After logging in with your extranet credentials, you will see a list of all App ID⁺s already registered by your company. To add a new App ID⁺ press the red plus button in the upper right corner. Enter your desired App ID⁺ and click the Create button.

App ID⁺ creation is free of charge. To ensure every ESDK App⁺ uses a unique App ID⁺ we require App ID⁺ registration for all ESDK App⁺s (no matter whether you plan to publish your App to the abas Marketplace or not). If you do not register your App ID⁺, you cannot install your ESDK App⁺ using the ESDK App Installer⁺. Since another App can register and use your App ID⁺, your App’s additional variables might be overridden.

3.2. Create your components in abas Essentials

You can create for example infosystems, additional databases, variables, database screens, data objects, translations, keys and enumerations.

3.3. Create a new ESDK project

After you finished creating your components in abas Essentials, you need to create a new ESDK App Project⁺. You can use the commandline tool Project Initializer, or the web interface Project Builder.

3.3.1. Project Initializer

Use the Project Initializer to generate the initial project structure. external link

3.3.2. Project Builder

Go to the ESDK Project Builder and fill in the appropriate data, such as connection data and the name and dependencies of your app. Reference all the components you previously created in the abas Essentials client, generate and download the project Zip file. Unzip the project to a directory of your choice.

Extranet credentials are required to login and access the ESDK Project Builder. If you do not have extranet credentials you can contact us.

3.4. Configure your project settings

There is a predefined template available to connect to the abas Essentials client and Nexus Artifact Server in a Docker container. Generate the settings on your development machine by running: ./initGradleProperties.sh in your preferred command line interface to create the gradle.properties file.

Make sure that after you run initGradleProperties.sh every host value (nexus, edp and ssh) in the gradle.properties file is set to your IP or the IP of the machine the erp runs on. Using localhost will not work!

3.5. Import the project in your IDE

Import the project as a Gradle project in your IDE. In Eclipse for instance, this enables you to execute Gradle tasks directly from an Eclipse View.

When using abas Tools please make sure to use the latest version, at least version 1.4.0.

3.6. Export your abas Essentials components

Use the Gradle task "exportAll" from our ESDK Gradle Plugin⁺ to export all of your new components from the abas Essentials client to your project. You can either run the task right from your IDE or in your preferred command line interface. To run it on the command line: change to the directory where your app is located and execute the following Gradle command: ./gradlew exportAll

To get an overview about all available tasks, you can run ./gradlew tasks on your command line interface. The ESDK Gradle Plugin⁺ tasks are listed in the groups abas Basic tasks, abas Help and Support tasks and abas Professional tasks.

3.7. Add logic

Once the exportAll step is finished, your abas Essentials components are copied to your project and you can start to add some logic.

3.7.1. Regenerate the AJO classes

To include classes for your newly created components run the installAjo task.

3.7.2. Provide abas specific dependencies

In order for your project to know about the abas specific dependencies, needed for development with JEDP and AJO, run the publishAllJars tasks and refresh the Gradle project in your IDE.

3.7.3. Use additional dependencies

To add dependencies to your project they have to be in a Maven repository. This can either be a publicly available Maven repository like Maven Central or a private one that runs locally or in your company’s internal infrastructure.

You have to first add the repository to the repositories block in your build.gradle, then add the dependency to your dependencies block. Specify the Maven group, module name and version. E.g. to add Google’s Gson Library to your app add the following to your build.gradle:

build.gradle
repositories {
    ...
    mavenCentral()
    ...
}
...
dependencies {
    ...
    implementation 'com.google.code.gson:gson:2.8.5'
    ...
}

For more information regarding dependency management refer to the Gradle Documentation.

How the shared option influences additional dependencies

In your build.gradle you can use the shared option to specify what configuration you want to use for parent.delegation of your JFOP server app. You can use parent.delegation=true or parent.delegation=false.

For ESDK App⁺s the default value for parent.delegation is false. If you set shared = true, parent.delegation is set true and the default value for parent is set to DEFAULT_SHARED automatically if nothing else is specified.

For simple EventHandler classes that only use the jar files in abas Essentials standard delivery, this is fine. You can specify an alternative value for your parent classpath by setting parent=<YourClasspathName> in your build.gradle file like in the following example:

esdk {
	app {
		...
        shared = true
        parent = "DEFAULT"
		...
	}
	...
}

The parent option also allows you to create a dependency structure between multiple apps that are interdependent:

esdk {
	app {
		...
        shared = true
        parent = "<YourAppId>"
		...
	}
	...
}

You should only change parent.delegation to true by setting shared=true in your build.gradle, if you explicitly need to share dependencies provided by another JFOP server app (the jar files in $HOMDIR/java/lib are provided with the JFOP server app named DEFAULT).

If you are using third-party libraries, we highly recommend to let shared set to false and specify the app’s dependencies explicitly. This keeps its classpath clean and avoids version collisions between third-party libraries that come with your app and the abas Essentials standard delivery.

How to explicitly use a dependency

There are three configurations that define which dependencies the app needs when and how they are provided:

  • provided dependencies are needed to compile the app but are provided at runtime by the s3jfopserver_bootstrap.classpath and thus not packaged with the app. They must not be listed in the app’s classpath file. The ESDK Gradle Plugin⁺ checks that they are not used in the other dependency configurations.

  • implementation dependencies are needed to compile the app and are explicitly listed in the app’s classpath file. If they do not belong to group de.abas.homedir or de.abas.clientdir, they are packaged with the app and get installed in the JFOP server app’s lib directory.

  • runtime dependencies are not needed to compile the app but to execute it at runtime. Examples are logging frameworks, Apache Commons Collections or abas-jfop-base.

An example

If you want or have to explicitly use a JAR provided in $HOMEDIR/java/lib you can reference it in your build.gradle's dependency block using the provided, implementation or runtime configuration. All libraries in $HOMEDIR/java/lib are uploaded to the Nexus server and can be referenced as following:

build.gradle
dependencies {
        provided "de.abas.homedir:abas-db-base:1.0.0"
        provided "de.abas.homedir:jedp:1.0.0"
        provided "de.abas.homedir:abas-jfop-runtime-api:1.0.0"
        provided "de.abas.homedir:abas-erp-common:1.0.0"
        provided "de.abas.homedir:abas-enums:1.0.0"

        implementation "de.abas.homedir:abas-axi2:1.0.0"
        implementation "de.abas.homedir:abas-axi:1.0.0"
        implementation "de.abas.homedir:abas-db-internal:1.0.0"
        implementation "de.abas.clientdir:abas-db:1.0.0-SNAPSHOT"
        implementation "de.abas.clientdir:abas-db-infosys:1.0.0-SNAPSHOT"

        runtime "de.abas.homedir:commons-collections:1.0.0"
        runtime "de.abas.homedir:abas-jfop-base:1.0.0"
        runtime "de.abas.homedir:jcl-over-slf4j:1.0.0"
        runtime "de.abas.homedir:slf4j-api:1.0.0"

        testImplementation "junit:junit:4.12"
        testImplementation "org.hamcrest:hamcrest-all:1.3"

        integTestImplementation "de.abas.homedir:abas-db-util:1.0.0"
}

All provided dependencies are automatically added to the implementation classpath (and thus to the deprecated compile classpath).

While missing provided and implementation dependencies get reported by the compiler or your IDE, missing runtime dependencies stand out when executing the app. A ClassNotFoundException is thrown, mentioning the missing class. The shell script jarversion.sh, provided by abas Essentials standard delivery, helps to find the right jar file:

jarversion.sh -c <fully-qualified class name>
jarversion.sh Example
$ jarversion.sh -c de.abas.erp.db.DbContext
Class: de.abas.erp.db.DbContext
Path: file:/abas/s3/java/lib/abas-db-base.jar!/de/abas/erp/db/DbContext.class

3.8. Use the esdk-client-api

The esdk-client-api enables you to use common functionality in your ESDK App⁺'s code, such as checking the abas Essentials has a valid license for your ESDK App⁺, or getting properties such as your app’s name or App ID⁺ during runtime.

3.8.1. Getting the esdk-client-api

To use the esdk-client-api add the following dependency to the build.gradle file of your ESDK App⁺:

dependencies {
    ...
    licensing "de.abas.esdk:client-api:0.0.13:all"
    ...
}

In order to resolve the esdk-client-api dependency you need to add the following repository:

repositories {
    ...
    maven { url "https://registry.abas.sh/artifactory/abas.maven-public/" }
    ...
}

For additional help refer to the esdk-client-api’s Javadoc.

3.8.2. Add license checks

To ensure, only abas Essentials clients with a valid license for your ESDK App⁺ can execute your app’s logic, you should add license checks.

At any point in your ESDK App⁺'s code you can check the license using the validate method provided by the LicenseChecker class from the esdk-client-api.

The validate method returns true for a valid license and false for an invalid license. You can then choose by yourself, whether, in case of an invalid license, you want to just display a warning, notify someone or abort the execution of your app’s logic.

In order for the license check to pass, the following conditions must be met:

  • A full-cloud or hybrid installation, i.e. Cloud Connect's License Controller, is set up and installed.

  • Your ESDK App⁺ needs to be registered on the abas Marketplace.

  • The abas Essentials client your ESDK App⁺ is installed in also needs to have a valid license for your app. Raise a request if you need a development license for an abas Essentials installation in one of our Docker images.

Do not overuse the license check, since every license check reduces the overall performance of your ESDK App⁺.

3.9. Synchronizing your changes

Transferring changes between your abas Essentials development client and your local ESDK App Project⁺ The ESDK Gradle Plugin⁺ offers a range of Gradle tasks for transferring changes between your abas Essentials development client and your local ESDK App Project⁺.

Tasks to transfer changes from your abas Essentials development client into you project are export tasks. Tasks to transfer changes from your local project to your abas Essentials development client are import or install tasks.

All ESDK App⁺ development specific tasks are grouped in either abas basic or abas professional.

The abas basic group contains all tasks necessary to get you started with ESDK App⁺ development:

  • checkPreconditions: Check if your connection settings are correct.

  • publishAllJars: Make home dir and client dir Jars available on the Nexus Artifact Server.

  • exportAll: Export all configured components from your abas Essentials client to your project.

  • syncCode: Synchronize code changes.

  • fullInstall: Install all your app components and code in an abas Essentials client.

If you are a more advanced user of the ESDK Gradle Plugin⁺, you can also use the tasks in abas professional to only install/import or export the components you changed. This saves you some time during development but since there are quite a view components, it is also a less structured view.

3.10. Create the ESDK App

Once your app is ready to be delivered, you can create a jar file containing all the components that belong to your app.

The Gradle task createEsdkAppJar will pack all necessary files and information in a jar file.

./gradlew createEsdkAppJar

3.11. Install your app in another abas Essentials client

Install your app from the cloud or locally using the ESDK App Installer.

4. Nexus

Once you start developing an ESDK App⁺, you need all AJO dependencies to be available in the Sonatype Nexus Artifact server, so that your IDE has access to these dependencies and you can develop logic for your ESDK App⁺ in AJO.

Previously samba shares where needed to access $MANDANTDIR/java/lib and $HOMEDIR/java/lib from your IDE. This is no longer necessary. All dependencies in $HOMEDIR/java/lib and $MANDANTDIR/java/lib are published to a repository on the Sonatype Nexus Artifact server.

Once the AJO artifacts are available on Sonatype Nexus, no connection to the client is needed at all for writing code and compiling against the AJO libraries.

4.1. Configuration

The Nexus Artifact Server can be run in a Docker container (as suggested in Setup ESDK development environment) or deployed and maintained by yourself.

Both Nexus Artifact Server versions, version 2 and 3, are supported. Nexus Server version 2 is the default.

The connection properties to your Nexus container need to be configured in the gradle.properties file in your project. For more details refer to Setup.

For your project to get the libraries from your Nexus, you will need to indicate two repositories. The first repository contains all the HOMEDIR libraries ($HOMEDIR/java/lib). The second repository contains the CLIENTDIR libraries, mainly abas-db.jar and abas-db-infosystem.jar ($MANDANTDIR/abasbase/java/lib).

For Sonatype Nexus version 2 specify:

repositories {
    maven { url "http://$NEXUS_HOST:$NEXUS_PORT/nexus/content/repositories/$NEXUS_NAME-SNAPSHOT" }
    maven { url "http://$NEXUS_HOST:$NEXUS_PORT/nexus/content/repositories/$NEXUS_NAME" }
}

In case of using the nexus url instead of nexus host and port, specify:

repositories {
    maven { url "$NEXUS_URL/nexus/content/repositories/$NEXUS_NAME-SNAPSHOT" }
    maven { url "$NEXUS_URL/nexus/content/repositories/$NEXUS_NAME" }
}
nexus {
    nexusUrl = NEXUS_URL
    nexusRepoName = NEXUS_NAME
    nexusPassword = NEXUS_PASSWORD
}

For Sonatype Nexus version 3 specify:

repositories {
    maven { url "http://$NEXUS_HOST:$NEXUS_PORT/repository/$NEXUS_NAME-SNAPSHOT" }
    maven { url "http://$NEXUS_HOST:$NEXUS_PORT/repository/$NEXUS_NAME" }
}

In case of using the nexus url instead of nexus host and port, specify:

repositories {
    maven { url "$NEXUS_URL/repository/$NEXUS_NAME-SNAPSHOT" }
    maven { url "$NEXUS_URL/repository/$NEXUS_NAME" }
}
nexus {
    nexusUrl = NEXUS_URL
    nexusRepoName = NEXUS_NAME
    nexusPassword = NEXUS_PASSWORD
}

Make sure the build.gradle file in your projects actually uses the NEXUS_VERSION property. It should contain the following line:

nexusVersion = NEXUS_VERSION

5. Project structure

The project resources can be found in the following directory and file structure.

yourAppProject
├── build.gradle (1)
├── docker-compose.yml (2)
├── gradle.properties (3)
├── gradle.properties.template (4)
├── gradlew (5)
├── gradlew.bat (6)
├── gradle (7)
├── README.md (8)
├── .gitignore (9)
├── Jenkinsfile (10)
└── src
    ├── integTest (11)
    ├── main (12)
    │   ├── java (13)
    │   └── resources (14)
    │       ├── advancedDbScreens (15)
    │       ├── base (16)
    │       ├── data (17)
    │       ├── dbscreens (18)
    │       ├── enums (19)
    │       ├── enumsAfterVarreorg (20)
    │       ├── IS (21)
    │       ├── keys (22)
    │       ├── namedTypes (23)
    │       ├── vartab (24)
    │       ├── fop.json (25)
    │       └── logging.custom.properties (26)
    └── test (27)
1 Project build configuration
2 ERP and Nexus as Docker containers internal link
3 Generated with initGradleProperties.sh and gradle.properties.template internal link
4 Template for your local gradle.properties file
5 Wrapper to execute Gradle tasks
6 Wrapper to execute Gradle tasks for windows
7 Directory for Gradle distribution
8 Introduction how to setup a project
9 Configuration file for Git to specify what files should be ignored.
10 Template for a Jenkins Job configuration.
11 Your integration tests
12 Project source code and resources
13 Your source code
14 Your project resources
15 DB screens to override standard screens completely when installed in the client internal link
16 Files to be transferred to the client internal link
17 Data to import to the client internal link
18 DB screens to be installed on the client internal link
19 Enumerations to be imported internal link
20 Enumerations to be imported after varreorg of imported vartabs internal link
21 Infosystems which will be installed on the client internal link
22 Keys which will be installed on the client internal link
23 Named types which will be installed on the client internal link
24 Variable table changes and custom databases internal link
25 fop.txt changes internal link
26 Specify your ESDK App⁺s log output internal link
27 Your tests (e.g.: JUnit tests)
All files need to be saved in UTF-8 encoding. The only exception are files in src/main/resources/base that are explicitly needed in s3 encoding in the abas Essentials client, such as FOPs.

6. Project components

You can specify all components belonging to your app in the app{ …​ } section of the build.gradle file.

6.1. Example for GeoLocation

This is an example how this look like for our Geolocation demo app.

esdk {
	app {
		name = "GeoLocation"
		vendorId = "ag"
		appId = "g30l0"
		shared = false
		infosystems = ["IS.OW1.GEOLOCATION"]
		tables = ["GeolocationConfig", "Kunde"]
		screens = ["Customer:Customer": ["A", "D"], "GeolocationConfig:GeolocationConfig": ["A"]]
		data = ["data.json"]
		languages = "DA"
		essentialsVersions = ["2017r1n00-2017r4n16", "2018r1n00-2018r4n16"]
	}
	...
}

You can find the complete app source here: GeoLocation

6.2. All projects components

esdk {
	app {
		name = "" (1)
		vendorId = "" (2)
		appId = "" (3)
		shared = false (4)
		infosystems = [""] (5)
		tables = [""] (6)
		data = [""] (7)
		keys = [""] (8)
		enums = [""] (9)
		namedTypes = [""] (10)
		screens = [""] (11)
		advancedScreens = [""] (12)
		essentialsVersions = [""] (13)
		preconditions = [""] (14)
		languages = "" (15)
		workdirs = [""] (16)
	}
	...
}
1 The name for your ESDK App⁺
2 Your vendor ID
3 Your App ID⁺
4 Whether your JFOP server app uses parentDelegation.
5 Infosystems belonging to the app internal link
6 Standard and additional tables internal link
7 Data files to be imported during the installation internal link
8 Keys internal link
9 Enumerations internal link
10 Named Types internal link
11 Customized standard and additional database screens internal link
12 Customized standard database screens to override screen completely internal link
13 Version rang(es) you ESDK App⁺ is compatible to internal link
14 Preconditions to be met prior to installation internal link
15 Languages internal link
16 Workdirs internal link

7. Task overview

The following picture gives an overview about the most relevant ESDK⁺ tasks.

Overview abas ESDK development environment

The tasks are grouped in basic, help and support, as well as professional ESDK⁺ tasks. Use the professional tasks if you want to make specific, selective changes. The basic tasks are a set of (professional) tasks to simplify the app development. The help and support tasks give information about the app project and its configuration.

8. abas Basic tasks

8.1. Publishing all JARs

The publishAllJars task executes both, publishHomeDirJars and publishClientDirJars to the Nexus server to get you ready for development.

8.2. Exporting all Components

The exportAll task runs all export tasks so that all project dependent components are exported at once.

For more information about the dependent tasks read each task’s documentation.

The export tasks run by exportAll are:

8.3. Checking Installation Preconditions

The checkPreconditions Gradle task checks the preconditions for installing an ESDK App⁺ in an abas Essentials client.

First, all connection settings are tested:

  • Is the abas Essentials client accessible via EDP and has a version supported by ESDK

  • Is the abas Essentials client accessible via SSH

  • Is the Nexus Artifact Server reachable

  • Is the abas environment set

  • Are the user rights sufficient

You can also configure additional checks for your ESDK App⁺:

  • Check for an abas Essentials version range. internal link

  • Check for specific working directories. internal link

8.4. Installing the ESDK App

The task fullInstall is the main installation routine for installing an ESDK App⁺ using the ESDK Gradle Plugin.

8.4.1. Setup

Before the installation can be started, there are a few prerequisites.

The abas Essentials client needs to be running and accessible via both SSH and EDP. Further the Sonatype Nexus Artifact server needs to be running and username and password of a user with read and write rights need to be available.

If the abas Essentials client and/or the Sonatype Nexus Artifact server are supposed to run in a Docker container, the Docker container(s) should be started and running before the ESDK App⁺ installation is started.

In every ESDK App⁺ a file named gradle.properties needs to be created right in the root folder of the project. In this file all properties regarding credentials and host names or ports must be defined.

You can use the shell script initGradleProperties.sh to generate that file from gradle.properties.template, both shipped with the project generated by the Project Initializer or the Project Builder.

gradle.properties
ABAS_HOMEDIR=/abas/s3 (1)
ABAS_CLIENTDIR=/abas/erp (2)
ABAS_CLIENTID=erp (3)

EDP_CLIENT=/abas/erp (4)
EDP_USER= (5)
EDP_PASSWORD=sy (6)
EDP_HOST=<abas IP address> (7)
EDP_PORT=6550 (8)

NEXUS_HOST=<nexus IP address> (9)
NEXUS_PORT=8081 (10)
NEXUS_URL=https://your-custom-url (11)
NEXUS_NAME=abas-essentials-libs (12)
NEXUS_USER_NAME=admin (13)
NEXUS_PASSWORD=admin123 (14)
NEXUS_VERSION=2 (15)

SSH_HOST=<abas IP address> (16)
SSH_PORT=22 (17)
SSH_USER=erp (18)
SSH_PASSWORD=none (19)
SSH_KEY= (20)

installType=SSH (21)

version=0.0.1 (22)
1 Absolute path to $HOMEDIR in the abas Essentials client
2 Absolute path to $MANDANTDIR in the abas Essentials client
3 Name of abas Essentials client as in the mandantdir.env
4 The EDP client (in most cases same as ABAS_CLIENTDIR)
5 When Linux logins are used for authentication in abas Essentials, the username has to be specified here
6 Password used for authentication in abas Essentials
7 Host name or IP address of the server abas Essentials is running on
8 EDP port (if it is not reconfigured, 6550 is the default port for EDP)
9 Host name or IP address of the server Sonatype Nexus is running on
10 Port the Sonatype Nexus Artifact server communicates on
11 Alternative to specifying NEXUS_HOST and NEXUS_PORT, if you are using a self-hosted Sonatype Nexus Artifact server you can specify its base URL with this property. If you use this feature, you have to update your build.gradle file manually. Please refer to Nexus.
12 Name of the repository the Java dependencies will be stored in on Sonatype Nexus
13 Username to authenticate to Sonatype Nexus (admin is the default username after Sonatype Nexus is installed in a Docker container)
14 Password to authenticate to Sonatype Nexus (admin123 is the default password after Sonatype Nexus is installed in a Docker container)
15 Version of Sonatype Nexus (2 is the default value, optionally you can configure to use Sonatype Nexus Version 3)
16 Host name or IP address of the server abas Essentials is running on
17 ssh port (if it is not reconfigured 22 is the default port for ssh)
18 Needs to be a Linux user known to abas Essentials (usually s3 or the login for a specific client of the abas Essentials instance)
19 Password required to sign in via ssh to the server abas Essentials is running on using the specified user (It can’t be empty. If no password is assigned just put any string here.)
20 Instead of a password an ssh key file can be used for authentication, the path to the file needs to be specified here
21 Installation type, only SSH and LOCAL are valid (usually one wants to use SSH)
22 Mandatory version of the ESDK App⁺ (must be a valid semantic version number)

8.4.2. Full Install

Once the $HOMEDIR/java/lib jars are uploaded successfully to an available Sonatype Nexus Artifact server, the task fullInstall can be run.

This task installs the ESDK App⁺ in the abas client specified during setup. The task fullInstall consists of (and therefore executes) the following tasks in the mentioned order:

After running ./gradlew fullInstall your app will be installed in the specified client and ready to use as configured by you.

8.5. Synchronizing the abas Client with Local Changes

The task syncCode bundles the execution of several tasks to generate and publish your app’s AJO classes.

These tasks (and, of course, their dependencies) are called: installAjo, publishClientDirJars and redeployJfopServerApp.

8.6. Creating the ESDK App JAR

The task createEsdkAppJar (deprecated name: createAppJar) creates the app JAR which can be installed in another abas Essentials client.

You can find the app JAR under the build directory: <yourAppDirectory>/build/libs/<appName>-<version>-standalone.jar

In abas Tools the build directory is not shown in the project view, use a file browser instead.

8.7. Submitting the ESDK App for abas Marketplace Approval

You need to use the packEsdkApp task in the abas basic task group or run ./gradlew packEsdkApp to create this ZIP archive.

The ZIP archive can then be found in <your-project-dir>/build/esdk-app/.

Make sure your project’s version is updated in the gradle.properties.template file (during development you might configure the version in your gradle.properties file only. However, this file is only for local development and will not be packed into the zip file).

Use this step in a Continuous Integration Pipeline to automatically build your project.

8.8. Installing the ESDK App using the ESDK App Installer

The installEsdkApp task installs the ESDK App⁺ on the client using the ESDK App Installer⁺.

The ESDK App⁺ needs to be available. It can be built from the ESDK App Project⁺ using the task createEsdkAppJar. The task installEsdkApp then performs the installation process with the ESDK App Installer⁺, that is likely to be used on a customer’s client.

It depends on the task installEsdkAppInstaller which installs the ESDK App Installer⁺ on the client.

9. abas Help and Support tasks

9.1. Information about the App Project

The task esdkProjectInfo prints version information about the app, Gradle, abas Essentials and the ESDK plugin, as well as the configuration data used to communicate to abas Essentials and Nexus. It also shows which docker image is used (if this information can be discovered).

9.2. esdkVersion

The Gradle task esdkVersion displays the version of the ESDK⁺ plugin.

9.3. Submitting the ESDK App to Receive Support

To submit your ESDK App for support, you need to create a ZIP archive from your ESDK App Project⁺.

We ask you to use the task packProjectForSupport in the help and support task group or run ./gradlew packProjectForSupport to create the ZIP archive.

The ZIP archive can then be found in <your-project-dir>/build/esdk-app/.

9.4. printDockerTags

The task printDockerTags will print all tags of the Docker image abas/test in sdp.registry.abas.sh that are applicable for the defined abas Essentials version ranges of your project.

In order to use these Docker images you need to have access to the sdp.registry.abas.sh Docker Registry. See Log in to the abas Partner Docker Registry on how to achieve this.

9.5. printVersion

The printVersion task prints the current version of your project. The version of your project can be stored in either one of the following files:

  • settings.gradle

  • gradle.properties

  • build.gradle

Regardless of which of these files you use to set the version, the printVersion task will print it to the console.

10. abas Professional tasks

The professional tasks do all the detailed work that is necessary to get the app up and running. While they are bundled up in abas Basic tasks, you, as an app developer, need to know the details for development. The following sections describe all professional tasks belonging to the ESDK Gradle Plugin⁺ and provide examples on how to achieve the given aspect in your app.

10.1. Transfer files

10.1.1. installBaseFiles

The Gradle task installBaseFiles tries to copy all the files and subfolders present in the base folder of your resources, into the target abas client directory.

The base folder can contain files at its root, and subfolders and their files.

You can use the base folder to store configuration files, FOPs, and other types of files which do not apply to the other tasks of the ESDK Gradle Plugin.

Configuration file

You can add a file named .config (case sensitive) at the root of the base and/or in any of the subfolders. In this file, you can specify a list of the files (present in the same folder the .config file is), with special things you would like to do to the files. The options supported are

  • ro : Make the file read only.

  • rw : Make the file readable & writable by everybody.

  • x : Make the file executable.

  • crlf : Apply crlf-. (Remove MS Windows carriage return character from each end of line. ONLY do this on text files, NEVER on binaries.)

  • nooverwrite : This will tell the program to not overwrite the file if it’s already present in the destination folder.

The option values must be separated by a comma.

Example:

config.properties=crlf,ro

This will make the file config.properties read only and will remove the carriage return character from every line of that file.

No export task

There is no export task for baseFiles, as they are all individual and need to be managed from the project itself.

10.2. Enumerations

10.2.1. exportEnums

Using the exportEnums task it is possible to export existing enumerations from the client specified in the gradle.properties file.

To export an existing enumeration you need to enter the enumeration’s classname in an enums list in the app section of the build.gradle as following:

esdk {
    app {
        ...
        enums = [ "ClientUsage", "AbcPriority" ]
    }
}

We recommend to use a unique classname for your enumeration, this can best be assured by using your App ID⁺ as namespace. E.g. for an App ID⁺ spare and an enumeration with search word FORMAT you could use SpareFormat as classname.

To export all enumerations specified in the build.gradle file to a file named enums.xml in src/main/resources/enums, run:

./gradlew exportEnums
Advanced enumerations

The task exportEnums only supports enums with enumeration elements of type ValueSet:Identifier (109:1) and ValueSet:ValueSetIdentifier (109:2) by default. Enumerations using other types of enumeration elements can also be exported, but you need to specify the according dependent selection. To do so, configure an enums.json file in src/main/resources/enums with dependent selections as needed. E.g. for a customer-dependent selection:

enums.json
{
  "dependents" : [
        {
          "dbnr" : 0,
          "grnr" : 1,
          "headfields" : ["id", "guid", "nummer", "such", "name"],
          "tablefields" : []
        }
  ]
}

For more information on data export and dependent selections refer to exportData.

10.2.2. importEnums

The Gradle task importEnums imports all XML files in the directory src/main/resources/enums of an ESDK App⁺.

Normally only one import file is needed, containing all necessary enumerations.

To identify an already existing enumeration, every enumeration exported with the exportEnums task gets a guid (if it does not already have one), a 38 digit number uniquely identifying the specific object among all other objects (regardless which database or group). The importEnums task then creates a new enumeration with that guid and updates exactly this if changes are necessary on further invocations.

To import all enumerations in src/main/resources/enums of an ESDK App Project⁺ run:

./gradlew importEnums

10.2.3. importEnumsAfterVarreorg

The Gradle task importEnumsAfterVarreorg imports vartab dependent enumerations after table of variables reorganization from XML files to the Essentials client.

10.2.4. enumReorg

After importing enumerations a reorganization is needed to be able to use the newly imported or updated enumerations.

To execute the enumerations reorganization run:

./gradlew enumReorg
Both namedTypesReorg and enumReorg run the same reorganization command on the client. Therefore, if your project consists of both, enumerations and named types, there is no need to run both reorganization tasks. After running both import tasks just run namedTypesReorg.

10.2.5. enumReorgAfterVarreorg

After importing enumerations a reorganization is needed to be able to use the newly imported or updated enumerations. The enumReorgAfterVarreorg task reorganizes the enumerations that were imported by importEnumsAfterVarreorg - just after a reorganization of the tables of variables has taken place.

To execute the enumerations reorganization run:

./gradlew enumReorgAfterVarreorg

10.3. Data

10.3.1. exportData

General Description

One or more JSON formatted files can be added to src/main/resources/data to describe what data should be exported.

This JSON file’s name needs to be added to the esdk section of the build.gradle file of an ESDK App Project⁺ like this:

esdk {
    app {
        ...
        data = [ "mydata.json" ]
    }
}

A JSON export data specification needs to contain at least one RootSelection, e.g.

{
  "roots" : [
    {
      "dbnr" : 0,
      "grnr" : 1,
      "headfields" : [ "id", "guid", "such", "name" ],
      "tablefields" : [],
      "criteria" : "id=(167,0,0)"
    }
  ]
}

Running the exportData task will check if there are undefined dependencies such as reference fields. E.g. the following JSON export data description won’t work with the exportData task as it contains the reference field staat.

{
  "roots" : [
    {
      "dbnr" : 0,
      "grnr" : 1,
      "headfields" : [ "id", "guid", "such", "name", "staat" ],
      "tablefields" : [],
      "criteria" : "id=(167,0,0)"
    }
  ]
}
./gradlew exportData

 You have to give a DependentSelection for 97:1
 To define it in your 'src/main/resources/enums/enums.json' data export file, add:
         "dependents" : [
                 {
                         "dbnr" : 97
                         "grnr" : 1
                         "headfields" : [ "id", "guid", such", "name" ]
                         "tablefields" : []
                 }
         ]

As indicated above, in case of exporting with reference fields, a DependentSelection is needed to define what to export from the object the reference field points to, e.g.:

{
  "roots" : [
    {
      "dbnr" : 0,
      "grnr" : 1,
      "headfields" : [ "id", "guid", "such", "name", "staat" ],
      "tablefields" : [],
      "criteria" : "id=(167,0,0)"
    }
  ],
  "dependents" : [
    {
      "dbnr" : 97,
      "grnr" : 1,
      "headfields" : [ "id", "guid", "such", "name" ],
      "tablefields" : []
    }
  ]
}
Object Identification

Each selection, no matter if root or dependent, needs to have at least id and the field used as identifier as head fields and, if any table fields are defined, zid must be one of them.

If the guid field is not filled in the object that is exported, it will be filled with a generated guid in the export file (not in the object that is exported).
Customized Object Identification

By default objects are identified by guid. Every object created by the data import gets a guid (the one that is generated by the data export) and if an object with the same guid in that database and group already exists it will be updated.

Object identification can be customized by using the "identifiers" option:

{
  "roots" : [
    {
      "dbnr" : 0,
      "grnr" : 1,
      "identifiers" : [ "such" ],
      "headfields" : [ "id", "guid", "such", "name", "staat" ],
      "tablefields" : [],
      "criteria" : "id=(167,0,0)"
    }
  ],
  "dependents" : [
    {
      "dbnr" : 97,
      "grnr" : 1,
      "identifiers" : [ "nummer" ],
      "headfields" : [ "id", "nummer", "guid", "such", "name" ],
      "tablefields" : []
    }
  ]
}

The identifier then shows up as an attribute to each RecordSet tag:

<RecordSet tableNumber="0:1" tableName="Kunde:Kunde" identifier="such" standard="false">
Referencing Standard Objects

Standard objects are objects that are part of the abas Essentials standard delivery. They already exist in the targeted installation and should be marked as such by adding the "standard" option to the selection:

{
  "roots" : [
    {
      "dbnr" : 88,
      "grnr" : 3,
      "identifiers" : [ "such" ],
      "headfields" : [ "id", "such", "name",  "aktiv", "kanal", "arb", "laytyp", "kontext", "layname", "genlayout", "genlayname" ],
      "tablefields" : [],
      "criteria" : "such==ISJASOW1AUO"
    }
  ],
  "dependents" : [
    {
      "dbnr" : 65,
      "grnr" : 1,
      "standard" : true,
      "identifiers" : [ "nummer" ],
      "headfields" : [ "id", "nummer" ],
      "tablefields" : []
    },
    {
      "dbnr" : 88,
      "grnr" : 6,
      "standard" : true,
      "identifiers" : [ "such" ],
      "headfields" : [ "id", "such" ],
      "tablefields" : []
    }
  ]
}

The standard option then shows up as an attribute to each RecordSet tag:

<RecordSet tableNumber="65:1" tableName="Infosystem:Infosystem" identifier="nummer" standard="true">
References to Objects created during the Installation

For data objects with dependencies on objects created during the installation process, such as Infosystems or additional tables of variables, a customized identifier combined with the standard option can be used to fill these fields during data import.

For example a call parameter with an additional table of variables as source context and an Infosystem as target context could be configured for export as follows:

{
  "roots" : [
    {
      "dbnr" : 87,
      "grnr" : 9,
      "headfields" : [ "id", "guid", "such", "zielobj", "kontexttyp", "aufrktxt" ],
      "tablefields" : [ "zid", "zielaktion", "zielvar", "aufrwtyp", "aufrwert" ],
      "criteria" : "nummer==100268"
    }
  ],
  "dependents" : [
    {
      "dbnr" : 12,
      "grnr" : 26,
      "identifiers" : [ "vgrtxt14" ],
      "standard" : true,
      "headfields" : [ "id", "vgrtxt14" ],
      "tablefields" : []
    },
    {
      "dbnr" : 65,
      "grnr" : 1,
      "standard" : true,
      "identifiers" : [ "classname" ],
      "headfields" : [ "id", "classname" ],
      "tablefields" : []
    }
  ]
}
Configuring the Import Behaviour

There are three additional configuration options. The first one is "importonce". With this option you can define that objects should only be imported once, and if already present should not be updated. Use the "importonce" option for the object that should only be imported once.

The second one is "importmode". With this option you can configure how to handle password and readonly fields. You can decide between "tolerant" and "normal" mode, where "normal" is the default. On "normal" mode password and readonly fields can successfully be exported (an empty field will be exported) but fail on import. On "tolerant" mode password, empty and readonly fields are ignored during export and import. In this case, a warning which contains the ignored field name is displayed. Use the "importmode" option for password or readonly fields if you want the export and import to behave different as usual.

The third one is "rowimportmode". When table fields are imported, it defines if

  • all existing rows get removed,

  • all new rows are added after the existing ones,

  • or existing rows are updated.

For reasons of backwards compatibility, the default value for "rowimportmode" is "clearBeforeImport". This means, when "rowimportmode" is not set explicitly, for matching objects all table rows get cleared on import - even if the import XML file doesn’t contain rows to import.
Set it to "alwaysAdd" if you want existing rows to be left untouched.
Table 1. Configuration Options for Import Behaviour
Option Purpose Possible Values Default Value

"importonce"

Import object on every app installation or only once.

true, false

false

"standard"

Objects marked as "standard" are assumed to be "already there" and not imported.

true, false

false

"importmode"

Whether to fail or not on importing fields whose values cannot be set.

"tolerant", "normal"

"normal"

"rowimportmode"

Start import of table rows with a cleaned table, simply add all new rows after the existing ones, or update existing rows.

"clearBeforeImport", "alwaysAdd", "updateMatching"

"clearBeforeImport"

Example JSON Snippet for Import Behaviour Options
{
  "roots" : [
    {
      "dbnr" : 2,
      "grnr" : 1,
      "identifiers" : [ "such", "name" ],
      "importonce" : true,
      "importmode" : "tolerant",
      "headfields" : [ "id", "guid", "such", "name" ],
      "tablefields" : [ "zid", "elem", "elanzahl" ],
      "criteria" : "such==DEMO",
      "rowimportmode" : "alwaysAdd"
    }
  ]
}

The importOnce, importMode and rowImportMode options then show up as attributes in the RecordSet tag:

Resulting XML Snippet as generated by exportData
<RecordSet tableNumber="2:1" tableName="Teil:Artikel" importOnce="true" importMode="tolerant" rowImportMode="alwaysAdd">

If the "rowImportMode" : "updateMatching" is set, you can define which tablefields will be used to identify the matching rows.

To define the fields used as identifiers for a row use the rowIdentifiers attribute.

The identifying fields cannot be updated during the import.
Example
{
  "roots" : [
    {
     "dbnr" : 2,
     "grnr" : 1,
     "importonce" : true,
     "importmode" : "normal",
     "headfields" : [ "id", "guid", "such", "name" ],
     "tablefields" : [ "zid", "elex", "such", "name", "anzahl" ],
     "rowimportmode" : "updateMatching",
     "rowIdentifiers" : ["elex", "such", "name"],
    }
  ],
  "dependents" : [
    {
    "dbnr" : 7,
    "grnr" : 0,
    "identifier" : "guid",
    "headfields" : [ "id", "guid", "such", "name" ],
    "tablefields" : []
    }
  ]
}

The rowIdentifiers then show up as attributes in the RecordSet tag:

<RecordSet tableNumber="2:1" tableName="Teil:Artikel" rowIdentifiers="elex,such,name" importOnce="true" importMode="normal" rowImportMode="updateMatching">

The row update behavior is as follows:

  • If a row already exists and can be identified uniquely: this row is updated

  • If importMode is tolerant: the first matching row is updated

  • If importMode is normal and there is more than one matching row the import will fail

  • If no matching row is found a new row gets appended at the end of the table

If a row is updated, the values will be updated for the fields provided in the xml source file. The values of other fields in this row won’t be changed.
Call Parameter Lists

Currently, it is not possible to fully automatically export call parameter list objects. To later successfully import call parameter lists, they need to be in a <RecordSet> with attribute tableNumber set to "87:21" and the <RecordSet> element needs to contain the <Head> and <Row> elements.

Also, the import needs the reference field aufruf to be present (for standard call parameter lists you can also reference the objects in aufruf as standard objects).

This is an example of a data.xml file containing call parameter list objects that can be imported successfully:

data.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ABASData>
    <RecordSet tableNumber="87:21" tableName="Datenexport:APListe" identifier="nummer" standard="false" importOnce="false" importMode="normal">
        <Record id="(1595,87,0)">
            <Head>
                <Field name="id" abasType="ID87">(1595,87,0)</Field>
                <Field name="nummer" abasType="NK87">60000</Field>
            </Head>
            <Row number="1">
                <Field name="zid" abasType="IDZ87:23">(1596,87,0)</Field>
                <Field name="aufruf" abasType="ID87:9">(1585,87,0)</Field>
                <Field name="aktiv" abasType="B1">1</Field>
            </Row>
            <Row number="2">
                <Field name="zid" abasType="IDZ87:23">(1597,87,0)</Field>
                <Field name="aufruf" abasType="ID87:9">(1588,87,0)</Field>
                <Field name="aktiv" abasType="B1">0</Field>
            </Row>
        </Record>
    </RecordSet>
    <RecordSet tableNumber="87:21" tableName="Datenexport:APListe" identifier="nummer" standard="false" importOnce="false" importMode="normal">
        <Record id="(1585,87,0)">
            <Head>
                <Field name="id" abasType="ID2">(1585,87,0)</Field>
                <Field name="nummer" abasType="NK2">60002</Field>
            </Head>
            <Row number="1">
                <Field name="zid" abasType="IDZ87:23">(1586,87,0)</Field>
                <Field name="aufruf" abasType="ID87:9">(1408,87,0)</Field>
                <Field name="aktiv" abasType="B1">0</Field>
            </Row>
        </Record>
    </RecordSet>
    <RecordSet tableNumber="87:21" tableName="Datenexport:APListe" identifier="nummer" standard="true" importOnce="false" importMode="normal">
        <Record id="(1588,87,0)">
            <Head>
                <Field name="id" abasType="ID2">(1588,87,0)</Field>
                <Field name="nummer" abasType="NK2">60003</Field>
            </Head>
        </Record>
    </RecordSet>
    <RecordSet tableNumber="87:9" tableName="Datenexport:Aufrufparameter" identifier="nummer" standard="true" importOnce="false" importMode="normal">
        <Record id="(1408,87,0)">
            <Head>
                <Field name="id" abasType="ID2">(1408,87,0)</Field>
                <Field name="nummer" abasType="NK2">52686</Field>
            </Head>
        </Record>
    </RecordSet>
</ABASData>

10.3.2. importData

The Gradle task importData tries to import all XML files in the directory src/main/resources/data of an ESDK App⁺.

Each XML import file needs to contain all object data required for the import, this includes all dependent objects (the objects' reference fields point to).

Within one XML import file the right import order is determined automatically.

If more than one XML import file is present, the object to import in each file should be independent from one another.

We recommend to use a unique identifier for your data objects, wherever possible. This can best be assured by using your App ID⁺ as namespace.

To import all XML files in src/main/resources/data of an ESDK App Project⁺ run:

./gradlew importData
Call Parameter Lists

To identify call parameter lists uniquely, more than a single attribute is necessary. In this case, provide all field names in the RecordSet XML node’s identifier attribute, separated by comma.

Example: identifier="aufrktxt,kontexttyp,aufrtab,buttonfeld,lieferumfang,nurkopf".

Then, in the Record.Head node, list Field nodes for these identifier fields with values that together identify the object uniquely.

10.4. Infosystems

10.4.1. exportIS

The task exportIS exports all infosystems that are referenced in the infosystems property in the esdk closure in your build.gradle file:

esdk {
    app {
        ...
        infosystems = ["IS.OW1.TESTINFO", "IS.OW1.REPLACEMENTCATALOGUE"]
    }
}

The infosystem(s) get exported to the isrein folder in your abas Essentials client using infosys_export.sh. They are then transferred to the IS folder in the source folder src/main/resources of your ESDK App Project⁺.

10.4.2. installIS

The task installIS installs all infosystems within the IS folder in the source folder src/main/resources of your ESDK App Project⁺.

The infosystem(s) get transferred to your client and installed using the shell scripts infosysimport.sh - if the infosystem does not exist yet - or infosys_upgrade.sh - if the infosystem does exist and needs to be updated.

The identity number used when exporting will be removed during the import, so the infosystem can be imported even if the identity number is already in use in the target client.

10.5. Keys

"Key" is the abas term for what is more commonly known as a "database index".

10.5.1. exportKeys

Using the exportKeys task it is possible to export existing keys from the client specified in the gradle.properties file.

To export an existing key you need to enter the key’s idno in a keys list in the app section of the build.gradle as following:

esdk {
    app {
        ...
        keys = [ "45678", "45679" ]
    }
}

To export all keys specified in the build.gradle file to a file named keys.xml in src/main/resources/keys run:

./gradlew exportKeys

10.5.2. importKeys

The Gradle task importKeys imports all XML files in the directory src/main/resources/keys of an ESDK App⁺.

Normally only one import file is needed, containing all necessary keys.

To identify an already existing key, every key exported with the exportKeys task gets a guid (if it does not already have one), a 38 digit number uniquely identifying the specific object among all other objects (regardless which database or group). The importKeys task then creates a new key with that guid and updates exactly this if changes are necessary on further invocations.

We recommend to use a unique key name (field schlname/keyName) for your key. This can best be assured by using your App ID⁺ as namespace. E.g. for an App ID⁺ spare and a key with search word CUSTCONT you could use SpareCustomerContact as key name.

If a similar key already exists in the target client a TODO: with the affected key is included in the installation log file. internal link

To import all keys in src/main/resources/keys of an ESDK App Project⁺ run:

./gradlew importKeys

10.5.3. keyReorg

The Gradle task keyReorg reorganizes the key table, thus makes the key available or updates it.

10.6. Named types

10.6.1. exportNamedTypes

By using the exportNamedTypes task it is possible to export existing named types from the client specified in the gradle.properties file.

To export an existing named type you need to enter the named type’s class name in the namedTypes list in the app section of the build.gradle as following:

esdk {
    app {
        ...
        namedTypes = [ "InstallationDate", "DisclaimerText" ]
    }
}

We recommend to use a unique class name for your named types. This can best be assured by using your App ID⁺ as namespace. E.g. for an App ID⁺ spare and an named type with search word INSTDATE you could use SpareInstallationDate as class name.

To export all named types specified in the build.gradle file to a file named namedTypes.xml in src/main/resources/namedTypes, run:

./gradlew exportNamedTypes

10.6.2. importNamedTypes

The Gradle task importNamedTypes imports all XML files in the directory src/main/resources/namedTypes of an ESDK App⁺.

Normally only one import file is needed, containing all necessary named types.

To identify an already existing named type, every named type exported with the exportNamedTypes task gets a guid (if it does not already have one), a 38 digit number uniquely identifying the specific object among all other objects (regardless which database or group). The importNamedTypes task then creates a new named type with that guid and updates exactly this if changes are necessary on further invocations.

To import all named types in src/main/resources/namedTypes of an ESDK App Project⁺ run:

./gradlew importNamedTypes

10.6.3. namedTypesReorg

After importing named types a reorganization is needed to be able to use the newly imported or updated named types.

To execute the named types reorganization run:

./gradlew namedTypesReorg
Both namedTypesReorg and enumReorg run the same reorganization command on the client. Therefore, if your project consists of both, enumerations and named types, there is no need to run both reorganization tasks. After running both import tasks just run namedTypesReorg.

10.7. Table of Variables (Vartab)

10.7.1. General

Importing and exporting tables of variables.

In abas Essentials, so called tables of variables define the schema of database groups.

Field types

Field types which contain special characters (for example colon in reference fields) must be in quotation marks.

Alias fields

Alias fields are only supported if they are alias fields of fields that belong to the app.
Alias fields of standard fields are currently not supported.

Shell Groups

If you export variables from a shell group, there will be a duplicate entry exported in the .schm file. One for the shell group and one for the origin of the shell. To use the .schm file for import please remove the entry for the shell group from the .schm file manually.

Umlauts / special characters

Umlauts or other special characters for database and group names are currently not supported.

10.7.2. installVartab

In a file with the suffix .schm in src/main/resources/vartab all changes for one table of variables can be defined. It is possible to add custom variables, as well as to update and delete them.

The .schm file needs to contain all variables of a table of variables relevant for the ESDK App⁺ this .schm file is for. There must be one .schm file for each table of variables that needs changes for the ESDK App⁺.

All variables belonging to an ESDK App⁺ have to be prefixed with the appId in the following fashion:

App Variable Namespace

The vendorId and appId of an ESDK App⁺ are defined in the build.gradle of the app project. They are stated in the esdk.app section as following:

build.gradle
esdk {
    app {
        name="myApp"
        vendorId="vv"
        appId="aaaaa"
    }
}

A variable for an ESDK App⁺ must have the following format in the table of variables:

<vendorId>y<appId><variable_name> (1) (2) (3)
1 The vendorId follows this formatting convention: [a-z][a-z0-9]
Note that technically the vendorId is not needed. It is just intended to be used for a better visual clustering of "your" fields in the table of variables. Currently, when importing variables, the prefix xx is always used, regardless what vendorId is specified.
2 The appId follows this formatting convention: [a-z0-9]{5}
It is the primary identifier of your app and defines the namespace for all of its individual variables.
3 The actual variable name can have the following format: [a-z0-9]{1,12}
From abas Essentials version 2019r4 on, names of individual variables are case sensitive and can be up to 72 places long. They can have the following format: [a-zA-Z0-9]{1,72}
Adding variables to tables of variables

In the .schm file only the actual variable name (<variable_name> above) has to be inserted. The prefix <vendorId>y<appId> is generated by ESDK automatically.

The .schm file needs to have the following format:

Kunde.schm
database Kunde {
        number 0
        classname Customer
        structure Kunde {
                groupNumber 1
                head {
                        field GL40 testhead {
                                label ""
                                heading ""
                                description "Test field head edited"
                                screen EDITABLE
                                showPriority A
                                changePriority A
                        }
                        field "P70:2" testref {
                                label ""
                                heading ""
                                description "Test reference field head"
                                screen EDITABLE
                                showPriority A
                                changePriority A
                        }
                }
        }
}

To define table variables follow this example of an additional database file:

TestDb.schm
database TestDb {
        number 25
        classname TestDb
        structure TestStructure {
                head {
                        field GL30 testhead {
                                label ""
                                heading ""
                                description "Test field head"
                                screen EDITABLE
                                showPriority A
                                changePriority A
                        }
                }
                table {
                        field GL30 testtable {
                                label ""
                                heading ""
                                description "Test field table"
                                screen EDITABLE
                                showPriority A
                                changePriority A
                        }
                }
        }
}

The value for groupNumber is 0 by default and is therefore left out in the second example.

Skip fields, especially buttons, need to have skip in the field definition:

field BU3 skip testbutton {
        label ""
        heading ""
        description "Test Button"
        screen VIEW_EDITABLE
        showPriority A
        changePriority A
}

To add an alias field for an app field use the following syntax:

field GL30 testhead {
        label ""
        heading ""
        description "Test field head"
        screen EDITABLE
        showPriority A
        changePriority A
        aliases {
                field GL40 testalias {
                        label ""
                        heading ""
                        description "Test field head alias"
                        screen EDITABLE
                        showPriority A
                        changePriority A
                }
        }
}

If the above examples are installed via the installVartab Gradle task, the variables are added to the according tables of variables, if they don’t already exist.

Edit existing variables in tables of variables

If a variable already exists, it is checked during installVartab whether there are any changes. Only if there are ones, the changes will be applied and result in one or more "VVAR" (prepared Vartab) records which will then require reorganization via varreorg.

For example, to change the testhead field in table of variables TestDb from type GL30 to GL40 run installVartab on the following file:

TestDb.schm
database TestDb {
        number 25
        classname TestDb
        structure TestStructure {
                head {
                        field GL40 testhead {
                                label ""
                                heading ""
                                description "Test field head"
                                screen EDITABLE
                                showPriority A
                                changePriority A
                        }
                }
                table {
                        field GL30 testtable {
                                label ""
                                heading ""
                                description "Test field table"
                                screen EDITABLE
                                showPriority A
                                changePriority A
                        }
                }
        }
}
Delete variables from tables of variables

A .schm file needs to contain all variables in that table of variables belonging to that ESDK App⁺.

Therefore, all variables in the App Variable Namespace, that are not defined in the .schm file for the table of variables, will be deleted.

For example, to delete the field testtable from the table of variables TestDb run installVartab on the following file:

TestDb.schm
database TestDb {
        number 25
        classname TestDb
        structure TestStructure {
                head {
                        field GL40 testhead {
                                label ""
                                heading ""
                                description "Test field head"
                                screen EDITABLE
                                showPriority A
                                changePriority A
                        }
                }
        }
}

Renaming variables with installVartab will lead to data loss without certain precautions. If you want to rename your variable in a productive system and don’t want to lose your data, you need to do it in two iterations (two versions):

  1. Add a new variable with the new name and write all data from the old variable to the new variable. At this point, data transfer from one field to the other is a manual step after app installation.

  2. Delete the old variable.

Just replacing the variable will lead to the old variable being deleted and a new variable being created. The deleted variable will lose all data.

Alternatively, if the type is compatible, you can use an alias field and keep the old variable.

10.7.3. exportVartab

The exportVartab task exports all custom tables of variables as .schm files, that are defined in the app section of the build.gradle file. exportVartab considers groups.

The groups can be specified using:

  • Standard databases: the German group name

  • Custom databases: the classname

If no groups are specified all groups containing fields that belong to the ESDK App are exported.

build.gradle
esdk {
    app {
        name = "sparePartsCatalogueApp"
        vendorId = "ag"
        appId = "spare"
        shared = false
        infosystems = [ "IS.OW1.REPLACEMENTCATALOGUE" ]
        tables = [ "Replacement", "Teil:Artikel,Fertigungsmittel" ] (1)
        data = [ "data.json" ]
    }
}
1 Add all table of variables names to the array named tables. For multiple tables of variables just add Strings separated by comma, e.g. [ "Replacement", "Teil:Artikel,Fertigungsmittel" ]. To separate the database from the groups use a colon and add the groups separated by commas.
Note that for standard databases, only their German names are supported, currently.

The exported .schm files can be found in src/main/resources/vartab in a directory named as the class name of the table of variables that was exported.

10.7.4. varreorg

The varrorg task checks if tables of variables prepared for reorganization exist (so-called "VVAR" objects). If VVAR objects exist, a table of variables reorganization is executed, else an appropriate message is displayed and the table of variables reorganization is skipped.

10.8. Screens

10.8.1. exportScreens

The exportScreens Gradle task exports screens from the abas Essentials client into the ESDK App Project⁺.

Additional Database Screens and App Tabs in Standard Database Screens

To specify what screens to export, add a screens attribute to your build.gradle's app section and specify the Database and Group class name of the table the screen is for as well as the priorities you want to export:

build.gradle
esdk {
        app {
                screens=["Customer:Customer": ["A", "D"], "TestDb:TestStructure": ["A"]]
        }
}

For customized screens for standard databases you can also specify the screen number instead of Database and Group class names:

build.gradle
esdk {
        app {
                screens=["77": ["A"]]
        }
}

For customized standard database screens only the app tab(s) and menu buttons of your app will be exported.

Add your app tab(s) to the first tab container in the main screen or the first tab container in the line zoom, depending on whether you want to add head or table fields. Use the Screen Designer which is bundled with abas Tools to do so.

Only menu buttons containing your App ID⁺ in their field name will be exported.

You cannot add tabs to inner tab pages:

Adding tabs to your screens

To identify your tab set the key attribute to <classname>$<appid>_<count>, e.g.: product$train_0. If you are using abas Tools to add a tab to your screen the key attribute will be generated as <classname>$<count>, e.g. product$0. So you just have to add <appid>_ there.

If no tab container exists in the main screen or line zoom, add a tab container around the outermost layout in the screen. Put all existing content in the first tab and add your app tab with your fields after that. When installing, a tab container with a general tab will be added automatically around the outermost layout and your app tab will be added after the general tab.
If no line zoom exists, add a line zoom and an app tab in that line zoom. When installing, a line zoom will be created and your app tab will be added to the tab container in that line zoom.

For customized additional database screens the complete screen is exported.

If there is no customized screen for your database or no key identifier is set for your app for standard databases the export will fail.
Overriding Standard Database Screens

If you want to override standard screens completely, you can use the advancedScreens attribute in the app section of your build.gradle file. Specify standard screens that should be overridden completely as follows:

build.gradle
esdk {
        app {
                advancedScreens=["77": ["A"], "Customer:Customer": ["A", "D"]]
        }
}
Using the advancedScreens configuration might lead to the loss of other changes in the previously already customized screen (such as changes made by other apps or the customer himself).
The advancedScreens configuration is not allowed for ESDK App⁺s meant to be published to the abas Marketplace and will lead to rejection.

10.8.2. installScreens

The installScreens Gradle task installs all customized screens that are part of the ESDK App⁺.

Additional Database Screens and App Tabs in Standard Database Screens

All screens to import must be present in src/main/resources/dbscreens in the .screen format.

Overriding Standard Database Screens

All advanced screens to import must be present in src/main/resources/advancedDbScreens in the .screen format.

The advancedScreens configuration is not allowed for ESDK App⁺s meant to be published to the abas Marketplace and will lead to rejection.

10.9. Language support

10.9.1. exportDictionaries

The Gradle task exportDictionaries exports all screen texts for all infosystems and tables of variables in the ESDK App Project⁺. The screen texts will be exported into msg.ma files per infosystem/table of variables in either src/main/resources/IS or src/main/resources/vartab.

To export all screen texts into msg.ma files run:

./gradlew exportDictionaries

The exported msg.ma files will include all languages specified in the app section of the build.gradle of the ESDK App Project⁺. All texts that are already available in one of the specified languages will be already included.

You can add all missing texts in all specified languages to the msg.ma files manually. These can then be imported using the importDictionaries task.

10.9.2. importDictionaries

The Gradle task importDictionaries imports all msg.ma files in the ESDK App Project⁺ into the dictionary of the abas Essentials client.

The msg.ma files containing translations are either found in src/main/resources/IS or src/main/resources/vartab as they either belong to an infosystem or to a table of variables.

The languages to import must be specified in the app section of the build.gradle of the ESDK App Project⁺ as following:

esdk {
        app {
                ...
                languages = "DA" (1)
        }
}
1 Specify all languages as found in the Configuration data object in the abas Essentials client e.g. D for German and A for American English.

To import all dictionaries for all specified languages run:

./gradlew importDictionaries
Only texts that are not already translated in the abas Essentials client the task is run for will be imported. Only languages that are installed in the abas Essentials client will be considered.

10.10. Working directories

10.10.1. createWorkdirs

The Gradle task createWorkdirs creates working directories if missing and activates inactive ones needed by the ESDK App⁺ for the user who runs the installation.

All needed working directories can be defined in the build.gradle:

esdk {
    app {
        ...
        workdirs = [ "ow1", "owdir" ]
    }
}
After installing, manual configuration of these working directories for additional users might be necessary.

10.11. Generate AJO classes

10.11.1. installAjo

The Gradle task installAjo runs ajo_install.sh on the abas Essentials client to generate AJO classes for all components that belong to the app project.

10.12. Change fop.txt

In an abas Essentials client, the file fop.txt (located in the client’s directory) contains all EventHandler registrations for database screens.

10.12.1. installFopTxt

The installFopTxt task adds all lines to fop.txt specified in the file fop.json.

The fop.json has to be added to your project here: <your project>/src/main/resources/fop.json. In this file, you can specify any entries you need to add to the fop.txt using the following JSON format:

fop.json Example for a Standard Database using AJO identifiers
[
  {
    "databaseName" : "(Sales)",
    "groupName" : "(PackingSlip)",
    "editorMode" : "neu",
    "event" : "maskende",
    "key" : "*",
    "field" : "*",
    "headOrTable" : "K",
    "isContinue" : "[C]",
    "handler" : "java:de.abas.example.YourClass@appid"
  }
]

Instead of specifying databaseName and groupName you can also use the screen number screenNumber. This is not recommended for additional tables, since additional tables are installed in the next free additional database. So the screen number changes depending on the client the app is installed in.

fop.json Example for a Standard Database using the screen number
[
  {
    "screenNumber": "35",
    "editorMode" : "*",
    "event" : "maskpruef",
    "key" : "*",
    "field" : "*",
    "headOrTable" : "K",
    "isContinue" : "[C]",
    "handler" : "java:de.abas.example.YourClass@appid"
  }
]
fop.json Example for an Additional Table
[
  {
    "databaseName" : "GermanDatabaseName",
    "groupName" : "GermanGroupName",
    "editorMode" : "neu",
    "event" : "maskende",
    "key" : "*",
    "field" : "*",
    "headOrTable" : "K",
    "isContinue" : "[C]",
    "handler" : "java:de.abas.example.YourClass@appid"
  }
]

If you want to add a fop.txt entry for every database and/or group, you can leave databaseName and/or groupName empty.

The fop.txt is extended by the app’s entries. A comment brace is factored around all fop.txt lines belonging to one app, to identify an app’s scope of lines, be able to add new lines for that app, update existing lines and delete old lines automatically.

fop.txt lines for an app that was installed with an ESDK version before 0.4.11 will not get updated or deleted automatically. These lines either have to be maintained manually or manually moved inside the comment brace for the app when installing the app with this or a newer version. The latter has only to be done once.

10.13. Configure logging

10.13.1. installLog

The installLog task adds a logging configuration to the abas Essentials client’s logging.custom.properties file in $MANDANTDIR/java/log/config/. All your ESDK App⁺s log output of the defined log level can then be found in the file specified in the logging.custom.properties file in your ESDK App Project⁺.

Updating the logging.custom.properties file is currently not supported. If you change lines and rerun installLog the changed lines will be imported but not replaced. Therefore changes to your log configuration have to be done manually, after installLog has run.

10.14. Change mandantdir.env

10.14.1. installMandantdirEnv

The task installMandantdirEnv inserts all properties of the mandantdir.env file in the source folder src/main/resources of your ESDK App Project⁺ to the mandantdir.env file in your development client. The custom properties will be inserted after the BEGIN section of your client.

Custom properties will be inserted if the properties key does not exist yet. To update a value of an existing properties key, you need to manually delete that key from the mandantdir.env file of your client, prior to running installMandantdirEnv.

10.15. Publish JARs

10.15.1. publishClientDirJars

The publishClientDirJars task publishes all java artifacts in $MANDANTDIR/abasbase/java/lib/ as SNAPSHOT versions into the defined Sonatype Nexus repository.

These artifacts contain the generated AJO classes and have to be re-published again after changes to the database schema (vartabs, enumerations, keys, infosystems) have been made and installAjo was executed.

10.15.2. publishHomeDirJars

The publishHomeDirJars task publishes all java artifacts in $HOMEDIR/java/lib/ as Release versions into the defined Sonatype Nexus repository.

These artifacts remain unchanged as long as the version of abas Essentials is not updated.

10.15.3. removeNexusFromClient

For publishing the java artifacts from home dir and client dir, a small Gradle project named nexus is copied to the client directory.

The task removeNexusFromClient removes the nexus project from the abas Essentials client directory. This is needed in case of changed connection data of the Nexus artifact server.

10.16. The JFOP server app

This is a jar artifact which contains all logic belonging to the ESDK App⁺. It also contains a descriptor for its classpath and an optional JFOP server app it depends on (the "parent" app). Its internal structure is described in the online help. However, you don’t need to handle this manually. The ESDK Gradle Plugin does it for you.

10.16.1. createJfopServerApp

The task createJfopServerApp (deprecated name: createApp) creates the JFOP server app. It bundles the app’s logic together with the app descriptors and creates the file and directory structure the JFOP server needs to identify it as a JFOP server app.

10.16.2. installJfopServerApp

The task installJfopServerApp (deprecated name: installApp) installs the JFOP server app on the abas Essentials client.

10.16.3. redeployJfopServerApp

The redeployJfopServerApp task (deprecated name: redeployApp) redeploys the JFOP server App and thus makes it accessible to the user. It creates and installs it, if it is not up-to-date.

10.17. Installing the ESDK App Installer

10.17.1. installEsdkAppInstaller

The installEsdkAppInstaller task installs the ESDK App Installer⁺ with the same version as the currently used ESDK Gradle Plugin⁺'s version on the client.

All versions of the ESDK App Installer⁺ installed using the task installEsdkAppInstaller are located in $MANDANTDIR/esdk-app-installers.

11. Documentation tasks

Adding documentation for your ESDK App⁺.

11.1. Writing ESDK App documentation

An app’s documentation is written in a plain text format called Asciidoctor.

To add documentation for your ESDK App⁺ create a documentation folder in your ESDK App Project⁺ directory. Within the documentation folder add a source folder src/main/asciidoc and create a file index.adoc within that source folder.

Add the following structure to the index.adoc file (The Project Builder and the Project Initializer already generate an example structure.):

index.adoc
:docinfo:
= <name of your app>
Documentation
:nofooter:

This document describes the <name of your app> app.

== About

<name of your app> +
(C) <name of your company>

https://your-website.com/

You write your ESDK App⁺'s documentation by adding .adoc files to the documentation/src/main/asciidoc folder and referencing them in your index.adoc file.

For example, add a file subpage.adoc with the following content:

subpage.adoc
== <Headline of your subpage>
This is a subpage about subcontent

Content goes here!

You can include this file in your index.adoc by adding include::subpage.adoc[] before == About:

index.adoc
...
This document describes the <name of your app> app.

include::subpage.adoc[]

== About
...

The documentation’s HTML5 rendering is provided by Asciidoctor. Refer to the Asciidoctor documentation for help on how to format your documentation with headings, lists, images, etc.

11.1.1. Rendering and viewing the ESDK App documentation

To render the documentation run

./gradlew esdkAppDocumentation

or execute the esdkAppDocumentation task from the documentation task group in your IDE. Afterwards you can view the documentation by opening <you-project-dir>/build/asciidoc/html5/index.html in a browser of your choice.

11.2. Packaging the ESDK App Documentation

You can create a ZIP archive from your rendered documentation by running

./gradlew packEsdkAppDocumentation

or executing the packEsdkAppDocumentation task from the documentation task group in your IDE.

The ZIP archive can then be found in <you-project-dir>/build/esdk-app/.

12. Verification tasks

12.1. verify

The task verify depends on the tasks that execute the unit tests (test) and the integration tests (integTest) and thus runs all tests.

In order to identify the scope a test is executed on, it is very advisable to make the distinction between unit tests and integration tests:

Unit Tests Integration Tests

Scope

small, local

wide, potentially involving all components of the system

Source Set

src/test/

src/integTest/

Gradle Task

test (comes with the Java Plugin, is a dependency of build)

integTest (added by the ESDK Gradle Plugin⁺)

Speed

fast, run by the programmer on every change

slow, only a subset is run by the programmer; the full set is run by a Continuous Integration server on every code check-in

Further Reading

UnitTest, Martin Fowler, 5 May 2014

IntegrationTest, Martin Fowler, 16 January 2018

12.2. integTest

The task integTest runs all integration tests.

You may use the ESDK testing utilities to setup integration tests easily.

12.3. addJacocoToAppClasspath

The task addJacocoToAppClasspath configures the JFOP server for Jacoco by adding the Jacoco agent to the ESDK App⁺'s classpath and configuring a JFOP server instance for the user who executes the task. The agent keeps track of the code that is executed on the server side while the integration tests are run.

12.4. instrumentJfopServer

The task instrumentJfopServer redeploys the ESDK App⁺ in the JFOP server and depends on the task addJacocoToAppClasspath.

12.5. retrieveServerSideCoverage

retrieveServerSideCoverage dumps the code coverage statistics (written by the Jacoco agent on an instrumented JFOP server instance) into a coverage-serverside.exec file in $MANDANTDIR/esdk/test-infrastructure/reports and copies it to the local ESDK App Project⁺.

12.6. calculateCodeCoverage

Code coverage means the percentage of production code that is covered by tests.

To calculate the overall code coverage for your ESDK App⁺ you need to execute the Gradle task calculateCodeCoverage.

It considers all .exec files in build/jacoco (some for the integration tests - downloaded from the JFOP Server by retrieveServerSideCoverage, some for the unit tests - generated locally) to calculate the code coverage and generates an HTML report.

The HTML code coverage report is generated and can be viewed by opening build/reports/jacoco/html/calculateCodeCoverage/html/index.html.

12.7. codeCoverageVerification

The task codeCoverageVerification verifies that the static code metrics of all tests together meets abas' requirements for the ESDK App⁺s to be published on the abas Marketplace.

The task passes if all static code metrics requirements are met. If one or more requirements are not met it will fail and display a message stating what is missed.

13. Other tasks

13.1. prepareVartab

The task prepareVartab prepares the vartab import file for installation.

13.2. processAppResources

processAppResources copies all resources files to ${project.buildDir}/abas/resources.

14. Gradle Plugin Settings

14.1. Configuring the SSH connection timeout

The default timeout for connecting to your abas Essentials client via SSH is 3 seconds.

To configure the timeout add the timeout property to your ssh closure in your build.gradle and set it to the desired value (e.g. 5000 for 5 seconds):

build.gradle
ssh {
        host = SSH_HOST
        port = SSH_PORT.toInteger()
        user = SSH_USER
        password = SSH_PASSWORD
        timeout = 5000
}

Alternatively, you can add it as a property to your gradle.properties and reference it in your build.gradle:

gradle.properties
SSH_HOST=yourhost
SSH_PORT=2205
SSH_USER=erp
SSH_PASSWORD=none
SSH_TIMEOUT=5000
build.gradle
ssh {
        host = SSH_HOST
        port = SSH_PORT.toInteger()
        user = SSH_USER
        password = SSH_PASSWORD
        timeout = SSH_TIMEOUT.toInteger()
}

14.2. EDP Log Files

By default the ESDK Gradle Plugin⁺ logs all EDP commands to build/logs/edp.log.

The logging directory can be changed by setting logFileLocation in the abas section of your build.gradle file:

build.gradle
abas {
    ...
    logFileLocation = "$buildDir/logging"
}

For example, you can redirect the EDP log output to a separate directory with the called task’s name within build/logs as follows:

build.gradle
abas {
    ...
    gradle.taskGraph.whenReady {
        logFileLocation = "$buildDir/logs/${gradle.taskGraph.getAllTasks().get(gradle.taskGraph.getAllTasks().size() - 1).name}"
    }
}

When calling ./gradlew checkPreconditions this would generate a log file build/logs/checkPreconditions/edp.log.

15. Compatible Essentials Versions

15.1. App Compatibility

To check for an abas Essentials version number, you need to add a version range to the essentialsVersions list in the app section of the build.gradle as following:

esdk {
    app {
        ...
        essentialsVersions = ["2017r1n00-2017r4n17"]
    }
}

Multiple version ranges are supported, e.g.: essentialsVersions = ["2017r4n13-2017r4n15", "2018r1n00-2018r4n17"]

These version ranges define your app’s compatibility with abas Essentials.

To create a new standalone app JAR using the createEsdkAppJar task you have to specify at least one abas Essentials version range. Otherwise the following error message will be displayed:

abas Essentials version compatibility check failed: no compatible abas Essentials versions specified

Installing existing standalone app JARs without abas Essentials version compatibility ranges are supported but will lead to the following warning:

abas Essentials version compatibility check failed: no 'essentialsVersions' compatibility specified in your 'build.gradle'

15.2. ESDK Compatibility

Currently the ESDK toolset is compatible with abas Essentials version 2017r2n00 and later. This minimum version is checked by the ESDK Gradle Plugin⁺ as well as the App Installer.

15.3. Overriding the Version Check

Sometimes it might be necessary to override the compatibility check.

Only override the minimum Essentials version check if you do exactly know what you are doing.

Installing an app on a too-old abas Essentials installation may have unintended side effects.

Installing an app on an abas Essentials installation the app was not built for, might lead to ClassCastExceptions and MethodNotFoundErrors at runtime.

15.3.1. App Installer

To override the version check on app installation, provide the app installer argument --skip-essentials-versioncheck. See Download and Usage for details.

15.3.2. Gradle Plugin

To override the version check when using the ESDK Gradle Plugin⁺ to develop an app for an abas Essentials version that is officially not supported, set the following property in your app project’s build.gradle:

esdk {
    ...
    allowUnsupportedEssentialsVersions = true
    ...
}

16. ESDK APIs and Libraries

To make common tasks less time-consuming and error-prone, we provide a set of some small APIs. All of them are available in the Maven repository https://registry.abas.sh/artifactory/abas.maven-public/.

Library Name Purpose How to use it Javadoc

client-api

de.abas.esdk:client-api:0.0.13:all

License checking, reading app properties

See Use the esdk-client-api for an example

Client API Javadoc

test-utils

de.abas.esdk.test.util:esdk-test-utils:0.0.3

Integration testing using the app project’s gradle.properties

See integTest and a newly generated project by the ESDK Developer Portal's project initializer

Testing Utilities Javadoc

versionchecker

de.abas.esdk.versionchecker:versionchecker:0.10.19

Reading abas Essentials versions, comparing them or check version matches

The Javadoc provides some examples

Version Checker Javadoc

17. ESDK App Installer

Using the ESDK App Installer⁺ to install ESDK App⁺s.

17.1. Preface

The ESDK App Installer⁺ is an application able to install an ESDK App⁺ fully automated. The ESDK App⁺ needs to be available as a standalone JAR file. This JAR file is created by executing the Gradle task createEsdkAppJar after the app was previously installed using the fullInstall task.

17.2. Download and Usage

download

The current version of the ESDK App Installer⁺ can be downloaded here as a ZIP file.

  • Choose the current version of the ESDK App Installer⁺ and download it.

  • Copy the downloaded ZIP file into the client directory of the abas Essentials client you want your app installed on.

  • Unzip the file.

  • Change into the unzipped folder.

  • Change into the bin folder.

The ESDK App Installer⁺ is ready to be used to install an ESDK App⁺ in this abas Essentials client.

From an ESDK App Project⁺ you can also use the ESDK Gradle Plugin⁺ task installEsdkApp to install you ESDK App⁺ using the ESDK App Installer⁺.
ESDK App Installer, Version 0.12.32

usage: ./esdk-app-installer [-a <artifact>] [--eapps-only] [-f] [-h] [-l <arg>] [--maven-repo-password <maven-repo-password>] [--maven-repo-user <maven-repo-user>] [-p <edp-password>] [-q] [-s]
       [--skip-essentials-versioncheck] [-u <edp-user>] [-v] [--version] [--yes-i-have-a-backup]
    -a,--artifact <artifact>                        Archive path or link to nexus artifact
       --eapps-only                                 Only installs the essentialsApps infosystem. All other installation actions will be ignored.
    -f,--force                                      Forces installation of given ESDK App, even if the same or a higher version is already installed.
    -h,--help                                       show usage
    -l,--languages <arg>                            App installation languages (e.g. English and French: EF)
       --maven-repo-password <maven-repo-password>  maven repository password
       --maven-repo-user <maven-repo-user>          maven repository user
    -p,--edp-password <edp-password>                EDP password
    -q,--quiet                                      quiet log output
    -s,--skip                                       do not install essentialsApps infosystem
       --skip-essentials-versioncheck               Skips the check if this ESDK App Installer and the App to be installed are compatible with the target abas Essentials version.
    -u,--edp-user <edp-user>                        EDP user
    -v,--verbose                                    verbose log output
       --version                                    display version of ESDK App Installer
       --yes-i-have-a-backup                        Backup of the ERP System was created

For more information visit: https://documentation.abas.cloud/en/esdk/#esdk-app-installer
The ESDK App Installer⁺ requires an Internet connection to install ESDK App⁺s.

To install an app that is available on an artifact server execute:

./esdk-app-installer -a <link to the app on an artifact server> [-u abasuser] -p abaspwd --maven-repo-user mavenRepoUser --maven-repo-password mavenRepoPwd

e.g.:

To install an app that is available locally execute:

./esdk-app-installer -a <path to local app JAR file> [-u abasuser] -p abaspwd

e.g.:

./esdk-app-installer -a /abas/erp/sparePartCatalogueApp-standalone-app.jar -p sy

The ESDK App Installer⁺ reads the abas Essentials client directory and some other values from the current environment. If the environment is not set right, it fails with messages complaining that MNAME is missing.
In this case, apply the ERP environment, first. In the Essentials client directory, call: eval $(sh ./denv.sh)

All non-optional arguments except for the path to the local app JAR file or link to the app on an artifact repository can also be supplied interactively. Executing

./esdk-app-installer -a <path to local app JAR/link to the app on an artifact server>

e.g.

./esdk-app-installer -a /abas/erp/sparePartCatalogueApp-standalone-app.jar

will prompt you for all other necessary arguments. All password inputs will be hidden.

The argument abasuser is optional, if not supplied it will be read from the environment.

To install the app in specific languages, use the -l / --languages argument with the language(s) to install:

./esdk-app-installer -a <path to local app JAR/link to app on an artifact server> -l <language(s)>

e.g.

./esdk-app-installer -a /abas/erp/sparePartCatalogueApp-standalone-app.jar -l A

Only languages contained in the app JAR will have texts, other languages will have no effect.

17.3. Use with abas Essentials as a Docker container

The Gradle task installEsdkAppInstaller automatically downloads and unpacks an ESDK App Installer to the container or server whose connection is specified in the gradle.properties file. The task installEsdkApp uses that to install the app.
  1. Download the installer to your local machine

  2. Copy the installer into the abas Essentials container
    docker cp <path to downloaded installer>/installer.0.12.32.zip erp:/abas/erp/

  3. Create your app JAR

  4. Copy the app JAR into the abas Essentials container
    docker cp <path to you App JAR>/<yourappname>.<version>-standalone.jar erp:/abas/erp/

  5. Run bash with the user erp inside the abas Essentials container (named erp)
    docker exec -u erp -it erp bash

  6. Set the client environment
    cd /abas/erp && eval $(sh denv.sh)

  7. Unzip the installer
    unzip installer-0.12.32.zip

  8. Run the installer with the required options
    esdk-app-installer-0.12.32/bin/esdk-app-installer -a <yourappname>.<version>-standalone.jar

To exit the container type exit.

Alternatively download the installer by executing the following command in your Docker container:

wget -qO- 'https://bintray.com/abas/abas-essentials-sdk/download_file?file_path=de%2Fabas%2Fesdk%2Finstaller%2F0.12.32%2Finstaller-0.12.32.zip' -O app-installer-tmp.zip && unzip -q app-installer-tmp.zip && rm app-installer-tmp.zip

17.4. Logging

The ESDK App Installer⁺ logs to the console and to a file. The log file can be found in $MANDANTDIR/esdk-installations/<appId>/<version> and is named installation.log. If the same version of an ESDK App⁺ is installed again, the previously existing installation.log is kept. It gets an index that is incremented each time a new installation.log is created in the same directory.

Additionally, the EDP communication is logged to edp.log within $MANDANTDIR/esdk-installations/<appId>/<version>.

For an ESDK App⁺ with App ID⁺ train and version 0.12.4 that was installed three times the log directory structure and files would look like this:

ls $MANDANTDIR/esdk-installations/train/0.12.4/
edp.log  installation-2.log  installation-1.log  installation.log

The default log level is INFO and informs about each step the installer is executing, e.g.:

Checking preconditions for train 0.12.4
Starting app installation for train 0.12.4
Installing JFOP server app trainingApp
Installing enumerations [/tmp/esdk4272199647961008308app/enums/enums.xml]
Running enum reorg
Installing vartabs CustomTestDb.schm
Running varreorg
Installing enumerations [/tmp/esdk4272199647961008308app/enumsAfterVarreorg/enum.xml]
Running enum reorg
Installing database screens 0_a.screen
Installing fop.txt changes
Installing logging.custom.properties changes
Installing files from base
Installing infosystems [[TESTINFO]]
Regenerating AJO classes for [[TESTINFO]] and enumerations
Installing data objects from [/tmp/esdk4272199647961008308app/data/data.xml]
Redeploying JFOP server app trainingApp
Installing keys [/tmp/esdk4272199647961008308app/keys/keys.xml]
Running key reorg
Installation of train 0.12.4 successfully completed

To only display warning and error messages, the installer can be run with the quiet option -q / --quiet:
./esdk-app-installer -a <path to local app JAR/link to app on an artifact server> -q

To get more detailed log messages, the installer can be run with the verbose option -v / --verbose:
./esdk-app-installer -a <path to local app JAR/link to app on an artifact server> -v

17.5. Installation of Infosystem ESSENTIALSAPPS

The Infosystem ESSENTIALSAPPS gives an overview of all installed apps in the abas Essentials client. It is an app itself and gets installed whenever the ESDK App Installer⁺ is used.

If installed, the Infosystem ESSENTIALSAPPS is used to determine, whether an ESDK App⁺ is already installed in the same or a higher version. By default, if the same or a higher version of the ESDK App⁺ is already installed, the installation is skipped.

The installation can be forced with the -f/--force option.

The installation of the infosystem ESSENTIALSAPPS app can be skipped with the -s/--skip option of the ESDK App Installer⁺.

./esdk-app-installer -a <path to local app JAR/link to app on artifact server> -s

e.g.

./esdk-app-installer -a /abas/erp/sparePartCatalogueApp-standalone-app.jar -s

17.6. Permissions

  • a shell user with abas environment matching the abas client the ESDK App⁺ is supposed to be installed in and

  • an abas user (i.e. a Password Definition record in abas Essentials⁺) with permissions to create and edit any object that is part of that ESDK App⁺.

We recommend to configure a dedicated abas user to install ESDK App⁺s on customers' live systems.

In the abas Docker images named test in the sdp registry, the abas user with password definition identity number 26 has sufficient rights for installing apps. The shell user erp should be used for running the ESDK App Installer⁺.

In detail, the following permissions are needed for ESDK App⁺ installation.

Usage Details Shell Permissions abas Essentials Permissions

General

Some precondition checks are executed to ensure basic permission needs are fulfilled.

The script edpexport.sh, command ls on files in $MANDANTDIR and subdirectories such as $MANDANTDIR/java/abasbase, $MANDANTDIR/isrein, $MANDANTDIR/java/apps, $GRADLE_USER_HOME, etc.

Access to the client’s version information via EDP.

Base Files

Creates the needed directory structure and transfers the files. It uses a temporary directory, which is created and deleted, and may do encoding changes.

The command mkdir for all directories that are to be created for the directory structure of the base files as well as temporary directories in $MANDANTDIR.
The command rm for deleting previously created temporary directories in $MANDANTDIR.
The command cp to copy files from the temporary directory to their target location.
The command chmod to change file permissions according to configuration in the .config file.
The command echo.
The script s3_conv for converting file encoding to s3.
The script crlf- to convert line endings.

Data

Data is created and updated via EDP in the abas database.

Permissions to create and edit any object that is contained in the app’s data XML file(s).

Enumerations

Enumerations are created and updated via EDP.

Permissions to create and edit enumerations and objects that are referenced in the enumerations.

Named Types

Named Types are created and updated via EDP.

Permissions to create and edit Named Types and objects that may be referenced in each Named Type.

Keys

Keys are created and updated via EDP.

Permissions to create and edit Keys and objects that may be referenced in each Key.

Infosystems

Infosystems are imported via shell commands.

Permissions to run the scripts edpexport.sh, infosysimport.sh and infosys_upgrade.sh and permission to create the directory structure in $MANDANTDIR/isrein

Variable tables

EDP is used for altering the tables. The Table of Variables reorganization is triggered via a shell command.

Permission to run the script varreorg

Permissions to edit Tables of Variables, to add, change and remove custom fields from the table. Permissions to register Additional Tables of Variables in the Company Data object.

AJO Generation

AJO Generation is triggered via a shell command.

Permissions to run the script ajo_install.sh.

JFOP server app deployment

JFOP server app deployment is triggered via a shell command.

Permissions to run the script jfopserver_cmds.sh and to create the JFOP server app’s directory structure in $MANDANTDIR/java/apps.

Screens

Screens are identified via EDP queries and regenerated upon import.

Permissions to regenerate screens.

Permissions to query Tables of Variables to determine table names and screen numbers.

Working Directories

Working Directories are registered via EDP.

Permissions to edit the installing users' Password Definition and the referenced Working Directory Permission object.

Dictionaries

Dictionary files are extended and the dictionaries are regenerated via shell commands.

Permissions to run mkdir and rm to create and delete a temporary directory in $MANDANTDIR and cp to copy from the temporary directory into the target directory.
Permissions to run commands s3_conv and crlf-.
Permissions to run the scripts edpexport.sh, trans_tool.sh, trans_smart_do.sh and trans.sh.

fop.txt

Changes to the fop.txt file are transferred via shell commands.

Permissions to run mkdir and rm to create and delete a temporary directory in $MANDANTDIR and cp to copy from the temporary directory into the target directory. Permission to run commands awk, sed, cat and grep to alter the temporary fop.txt files. Permission to run command echo.

Logging

Permissions to alter $MANDANTDIR/java/log/config/logging.custom.properties

mandantdir.env

Permissions to edit the file $HOMEDIR/mandantdir.env and run envmake -B.

18. Demo Projects

18.1. Training App

The demo project trainingApp demonstrates all ESDK⁺ features using the latest ESDK⁺ version (this can also be a SNAPSHOT version).

The trainingApp is for presenting features and therefore not all components make sense together as they are only intended to show how to use the specific ESDK⁺ features.

18.2. Geolocation App

The demo project g30l0 consists of a small Infosystem that resolves customers' geo locations using an Open Street Maps web service.

It includes unit tests using the mocking framework mockito and integration tests using the ESDK Testing Utilities.

To demonstrate how Kotlin can be used as an alternative programming language on the JFOP Server, there is a Kotlin port also: Repository on Github

18.3. Spare Parts Catalogue App

This example app implements an Infosystem for importing spare parts as a replacement catalogue from a CSV file. It also gives an example of how messages for multiple operating languages can be handled via properties files.

18.4. Further Demo Projects

Additionally there are several further projects in the ESDK Team Account on Github. E.g. small projects that were used in presentations during the ESDK Developer Days.

19. Infosystem ESSENTIALSAPPS

Use the infosystem ESSENTIALSAPPS to get information about all installed apps on your abas Essentials installation.

The infosystem gives you information about:

  • Error during installation (icon): Indicates if the current installation was successful

  • App ID⁺

  • App Version: The version of the app which is currently installed

  • Installation date

  • Installation duration

  • Licensing (icon): Indicates whether the app has a valid license (green), does not use licensing (blue), is not licensed (red), or the license controller is not available (grey).

  • abas Essentials version compatibility: The abas Essentials version ranges the app is compatible with

  • abas Essentials version compatibility (icon): Shows if the app is compatible with the actual abas Essentials version

  • Components (Button): Lists all components belonging to the app

  • Installation Log File (Button): Shows the installation log file of the current version

  • Installation Remarks: Shows error messages and information about the installation process

20. Submitting your ESDK App

20.1. Submitting your ESDK App for abas Marketplace Approval

You can submit your ESDK App⁺ for abas Marketplace Approval by raising a request for App Submittal.

Your ESDK App⁺ has to meet the following requirements:

Group Name Requirement

Formal Requirements

Version

Valid semantic version number, which is not a SNAPSHOT version (ending in -SNAPSHOT) and defined in gradle.properties.template.

Gradle Wrapper

A Gradle Wrapper compatible with the ESDK Gradle Plugin must be available.

App ID

The App ID⁺ must be valid and registered via the ESDK Developer Portal. Refer to Register your App ID.

Size

The packed ESDK App⁺ ZIP file cannot exceed 50MB.

Programming Language

Any JVM-based programming language that can be tested automatically and is runnable in the JFOP server.

Documentation

Documentation must be available for the ESDK App⁺ in Asciidoc format. Refer to Writing ESDK App documentation.

abas ERP Version

abas ERP Versions, provided for this app, must still be supported by abas.

Static Code Metrics

Cyclomatic Complexity

Must be less than 21.

Maximum Method Length

Max LOC/functions must be less than 31.

Dynamic Code Metrics

Tests

Test types are not restricted. You are free to use Unit Tests, Integration Tests and/or End-to-End Tests. All tests must pass.

Test Coverage

Test Coverage must be greater than or equal to 80%.

Test Execution

Test execution cannot exceed 1 hour.

You can check if your ESDK App⁺ meets the code metrics by executing the codeCoverageVerification task.

We reserve the right to do manual spot checks on submitted ESDK App⁺s.

20.2. Submitting your ESDK App for Support

You have the possibility to report any requests for missing features, or get help on any issues you are experiencing with abas Essentials SDK⁺ by raising a request for support. You will contact the ESDK⁺ development team directly and we will get back to you as soon as possible.

Glossary

This glossary is meant to clarify the naming of the components that relate to abas Essentials SDK⁺.

abas Essentials SDK

The Software Development Kit (SDK) for customizing abas Essentials⁺. It mainly consists of

abas Essentials

The core product of abas Software GmbH. It is also known as abas ERP.

App ID

Short for ESDK App ID⁺.

ESDK

Short for abas Essentials SDK⁺. Please use only upper case letters, not eSDK.

ESDK App

The result of an ESDK App Project⁺. The finished and automatically installable customizing for abas Essentials developed using abas Essentials SDK⁺.

Please do not use any other names, not ESDKs, ESDK package, etc.

ESDK App ID

The ESDK App⁺'s unique name space.

ESDK App Installer

The installation tool to install an ESDK App⁺ in an abas Essentials client.

ESDK App Project

The project structure to develop an ESDK App⁺.

ESDK Gradle Plugin

The core component of the ESDK⁺ toolset. It is the development tool for creating ESDK App⁺s.

About

Version: 0.12.32

abas Essentials SDK
© abas Software GmbH