/ Release  

The (all we've been waiting for!) update on AppWorks 21.4

Hi there AppWorks fans,

Welcome to a new installment of AppWorks tips.

A new GA AppWorks platform version 21.4 (also known as version 21 EP4) is available since Q4 2021. In this post we’ll have an update on the new features released for this version!

Let get right into it…

Again (it gets boring) the main installation menu still has the 21.2 installation applied!. Why? Because of the same reason for release 21.3. I could plot that installation one-to-one on the 21.4 installation (incl. all the software versions for TomEE, Java, and PostgreSQL). So, the 10 steps procedure to install an AppWorks environment from scratch is still a great post to follow for this new release. In this post will do a review on the (AppWorks Platform CE 21.4 Release Notes) delivered with the installation package. We will do a deeper dive on the newest functionalities delivered in this GA release. More information is also available in the release notes PDF.

One note after my installation this time! On entering the ‘system’ space I immediately get an error on the CWS service container about incomplete libraries and this as message: Error :org.postgresql.util.PSQLException: ERROR: out of shared memory Hint: You might need to increase max_locks_per_transaction.

Steps to resolve (as it might help you too):

sudo vi /var/lib/pgsql/11/data/postgresql.conf
#Uncomment "max_locks_per_transaction" and set the value to 1024. Can be found in the section LOCK MANAGEMENT at the end of the file!
shutdown -r now #reboots the VM and after some time CWS restores itself on the missing libraries!

🆕 Update on the available changes in 21.4 🆕

With a new version of the platform we also get a lot of new functionality. This will give you a proper overview of the ‘new stuff’. Let’s just jump through the list of new features in the release notes and see what’s up in this release.

A brand-new JS API for a tighter and more responsive customization

Interesting as we already played around with the HTML5SDK, but this API has a tighter integration within the runtime. Meaning that we don’t need to do ‘hard’ refreshes in runtime to update other panels when you update information in our custom HTML content panel (this includes xForm calls within that same content panel). The custom pages can ‘communicate’ between other panels in runtime. The technique behind this is called ‘Promise’ and is based on asynchronous calls. The ‘Promise’ represents the completion/failure of that call. It’s the future of JavaScript development which makes an internet/intranet page more interactive and refreshable in the data flow of the page.

More can be found in the ‘OpenText AppWorks Platform 21.4 Advanced Development Guide’ where we can find a chapter called: “Using the application JavaScript APIs”. That’s a #RTFM but does not bring sufficient information (yet!) to let me try out some stuff…I asked for a small HTML example file at OpenText support to get an entrance where the documented object ‘publicAPIProvider’ is retrieved from!? I placed it on my backlog and have you updated as quickly as I can. I’m as curious as you on the value it will provide for our solutions. Although it’s a first GA; it already makes it possible to read, update, and refresh information!

Business user friendly audit view in runtime

A new panel for our layout based on the history BB. It looks like this, once implemented.


When compared with the ‘History’ action button; this panel shows the more business-related updates for the entity which is a subset of the full ‘History’. It’s unclear to me why an explicit ‘Refresh’ needs to be triggered by the end-user as the refresh is already detected!? Maybe it has to do with the big data behind it which might raise a performance issue, but then it would be nicer to implement a pagination feature and only retrieve the top X of that page. Or maybe it’s just me!? Let me know in the comments otherwise! Still a nice panel to show interesting information to our end-users in runtime.

I also see some extra checkbox options on the building block itself:


The release notes are talking about categories defined in a parent entity. These are categories defined in a form and make it possible to ‘tag’ a part of your form and define rules to it, so you are in control to show/hide parts of that same form and even set styles based on rules. With this release we can still create categories on our parent entity, but when we have a related entity which has some business rules applied, we can now for example show a ‘Repeating group’ on our parent entity form based on values defined in the related entity…Yes! Read that line again…It took me also some time before it fell into place! 🤔

A practical example

I have a default ‘todo’ entity (see screenshot of the previous section), and a ‘toMany’ relation to a ‘task’ entity (just for a demo!) like this:


In the ‘Create’ form of my ‘todo’ entity, I make sure to drag & drop this relation which makes it a repeating group. We also select a ‘browse list’ for this component and we also add a new ‘Category’ to it…Like this:


Parent ‘todo’ entity is done…Now we also add a new relation to_one_todo on the related ‘task’ entity, and we make it bidirectional as well. Why this relation? Because otherwise it will never be possible to ‘see’ the ‘Categories’ of our parent entity (I guess!?).

Now it’s time to create a new rule BB for our ‘task’ related entity where we define a new “event” type of rule with name: e_on_prop_change_hide_to_many_task. In this rule we are able to hide/show categories of the current entity, but as the feature is telling us, also categories defined on our parent ‘todo’ entity!


Nice…This can for sure help in certain use-cases to show the correct data in the correct moment in time.

“Saved” filters in runtime

Also, a long beloved feature for runtime users:


Once saved, it can be found back on the top-right icon bar of the result list:


Filter option for form grids

Back to our ‘to_many_task’ component available on the ‘Create’ form of our parent ‘todo’ entity. By default, this will be of type ‘Repeating group’, but we can update this one to a ‘Grid’ type of component. Once we’ve done this update we have the ability to set a ‘filter’ mark to it:


Some notes on this feature

  • It’s also available on the ‘hasChild’ relation
  • For the ‘toMany’ relation this is only available with a ‘bidirectional’ relation (like in our example!)
  • And…saving filters is NOT supported (yet!?)

AppWorks runtime performance improvement

This all has to do with ‘Dictionary content’ which is smartly cached on the client side which makes it faster to retrieve. Sure, but what is this content!? As far as I could find any information in the documentation about the term ‘dictionary’ it’s all about translated text! So, data from an installed language pack, or your own translations of the components in your solution.

Right-click your project in the workspace and play with translations in these settings:


I followed my own post, and prepared some translations for the ‘Dutch - NL_nl’ language to ‘see’ something in runtime…I Hope?

Well, after some playing around and monitoring the developer toolbar within Chrome I can only conclude that indeed data is caching, but I couldn’t find any relation with the language pack!?

The ‘Disable cache’ option made an improvement of approximately 700ms (2200ms vs. 1500ms), but when I look at the network traffic it’s all in the disk cache of some JavaScript libraries and not my translation data or the result list data!?


Maybe it’s also my test, and the small solution I test with!?…Let me know in the comments. I trust OpenText on their blue eyes on a better performance in runtime!

Configurable error behavior in runtime

A recognizable image:


The error is shown immediately even if the user didn’t have the chance (yet!) to fill-in the field. Well, there is light brought into the tunnel of darkness with a property setting in the file wcp.properties

sudo vi /opt/opentext/AppWorksPlatform/defaultInst/config/wcp.properties

The property option sounds like this: platform.ui.application.error.onload = false. When set to FALSE, we see a lazier error message panel after the user performs an action. This action can be a button click; like the ‘Create’, a rule action button in the action bar of the entity instance; Also, the auto-save, when you remove the focus from the form, is a trigger.

After a restart of TomEE systemctl restart tomee we start to see the results.

By default, this flag is TRUE, but the error handling ‘feels’ much clearer/in-line with this setting on FALSE…In my opinion! 😲

Enhancements for the license usage report

For this feature we enter the ‘system’ space with our ‘sysadmin’ account. Here we have an artifact available with the name ‘License Manager’.


When you click the ‘View’ button in the ‘Report Information’ section, you get a modal popup with an extra checkbox for this released feature:


This image shows you to download the license information in XML/CSV format; The “copy XML to clipboard” action is removed!

AppWorks Platform container image availability in the OpenText registry

The OpenText registry?? Yes, we’re talking about the OpenText Docker Hub registry on this location: https://registry.opentext.com/. This is just a central location to store so-called Docker images. Docker images are the “templates/blueprints” to build Docker containers. Docker has its own public image registry on https://hub.docker.com/, but as OpenText doesn’t deliver its images publicly, they host their own central Docker registry which we can use to retrieve specific OpenText Docker images.

Other OpenText products were already available from this registry and AppWorks is added to the list. The feature also describes that customers can build solution specific images which can (I guess) be saved into this registry instead of hosting their own Docker hub registry…Interesting!

Have a look here for more Docker registry information

The containerized installation of the platform can be found here. When we have a look in the containerized Cloud Edition, we see it’s based on Docker-compose. There is also an extra abstraction available based on Kubernetes HELM charts. All these tools help you to build Docker containers based on Docker images saved in the public registry.

When you have Docker running, and configured it to use the registry.opentext.com (with your OpenText account!), we should be able to make calls like this (which are eventually being executed in the background of a HELM charts installation!):

#First login with your support credentials!
docker login registry.opentext.com
#OTAWP (OpenText AppWork Platform)
docker pull registry.opentext.com/otawp:21.4
#CARS (aka OpenLDAP!)
docker pull registry.opentext.com/otawp-openldap:21.4
docker pull docker.io/postgres:13.3-alpine

There is a backlog item on my list to do an installation based on the cloud edition package with tools like Minikube and Kubectl to build a Kubernetes (also known as K8s) cluster of Docker containers (also known as ‘pods’ in Kubernetes terminology!)…Great stuff to play around with, but a totally different skill-set to learn!

Enhancements for container-based deployments

Support for a Kubernetes Secrets vault for password storage. The “appworks-secret.yml” file of the containerized installation package clearly shows an if-else on this level:

{{- if eq .Values.useExternalSecrets true }}
apiVersion: kubernetes-client.io/v1
kind: ExternalSecret
{{- else }}
apiVersion: v1
kind: Secret
{{- end }}

It’s now possible to run CARS (or better OpenLDAP) in non-secure mode. By default, it was always running in secure-mode (TLS) only, but it can now be configured to run in both modes. The “ldap-configmap.yml” file clearly shows a supportive option:

apiVersion: v1
kind: ConfigMap
LDAP_ALLOW_NON_TLS_CONNECTIONS: {{ .Values.allowNonTlsConnections | quote }}

The last enhancement makes it possible to trigger a user consolidation in OTDS during solution building. Didn’t I just explain the CE contains only the minimal platform images!? Yes, my smart AppWorks friend, but this can be (and almost must be!) extended with other containers like for example OTDS (which is delivered with its own CE). Have a read in the “OpenText AppWorks Platform 21.4 Cloud Deployment Guide.pdf” documentation and find information about ‘Application/solution specific’ images, and the configuration files involved with this. Have a look at the ‘solution.yml’ file which are available ‘inside’ the initial Docker container images!

To clear things up (as it wasn’t that clear to me either!). You start the CE with a set of basic images; from these images you can extract application specific images which have the crafted solution in them and can be rolled out to production. The advantage? We don’t to deliver a CAP file anymore; We deliver a Docker image with the pre-installed solution where we (as this feature tells us!) can now also do a user consolidation upfront!

Custom property support in the Content panel

Let’s add the ‘Content’ BB to the crafted ‘todo’ entity and add a content panel to the ‘DefaultLayout’. On the right-side you see those custom content specific properties (my cnt_description which is created on the related content entity!) to be shown in the panel in runtime:


Microsoft Graph support in the Email connector

Read here about Microsoft Graph. It’s just a new API to connect to Microsoft Azure services via the OpenText E-mail connector. We played with this connector already. Don’t worry; POP, SMTP, and IMAP is still supported. 🙄


Enhancements for Brava integration with AppWorks Platform

For this feature I just enable Brava! based on my own post. After some #$@$%#@ it came alive again (with that additional preview panel on the ‘DefaultLayout’ of my entity!):


In quick steps:

Now back to the feature as when we have the Brava! viewer up and running, we can also do some administration configuration to it. Jump in the /app/admin side of the platform for your organization and see this being available for you:


The options speak almost for themselves! Play around I would say as they depend on your own requirements.

One extra feature is also available for the markup editing which has to do with permission on other users. When we open the related ‘Content’ entity, and add a ‘Security’ BB to it, have the ability to set a permission ‘Edit markup’. This makes it possible to edit markups created by other users.


Enhancements for Entity REST APIs

First the question: What is a “TypedReST” API? as I see a lot of communication about that term. I know “Representational State Transfer”, but a ‘typed’ variant is unclear to me!? Or is it maybe because it’s Swagger documented in a ‘typed’ manner? Help me out here!?

The release notes tell me all about updates in ‘relationships’, ‘lifecycle’, ‘activity flow’, and ‘assignee’. It would even be possible to INJECT states and activities into a lifecycle (which is just a case-model if you didn’t know!). Interesting, as what will be the next step? That business users are going to overrule and manipulate our hard craftsmanship in design-time…That does ring a bell from another meeting where this was discussed! We’ll see what the future will bring us!?

Right…So, let’s just add those kinds of building blocks to our ‘todo’ entity. Publish it all and jump into the ‘TypedReST’ layer of the platform:


This is the direct URL for my space:

…we wait

…we view

…we view again

…we double-check

…we triple-check…nothing!?…we ask support…

It’s a beta released feature which can only be enabled by OpenText support. This also matches the documentation “OpenText AppWorks Platform 21.4 Entity REST API Developer Guide.pdf” as there is nothing to be found about any new operations for this feature.

BUT…I don’t give up that easy as the Swagger UI is just a nice documentation wrapper around the “real” API calls. When I create a ‘todo’ entity instance in runtime, I’m able to retrieve its JSON data by a call like this:


So, this URL can also be opened directly from a new tab:


With my little development background, we are also able to retrieve the other ReST calls (only without a nice Swagger UI). Have a look at the deployed WAR file on the TomEE instance. The file is called “/opt/tomee/apache-tomee-plus-8.0.6/webapps/home#app#entityRestService.war”. A little decompiling on the Java compiled .class files (for the insiders in package: com.opentext.cordys.entity.rest) extracts me to these available URLs for my entity:


Method ReST URL
POST /api/appworkstipsgeneric/entities/todo/items/1/ActiviyFlow/actions/InitiateActivityFlow


Method ReST URL
POST /api/appworkstipsgeneric/entities/todo/items/1/Assignee/actions/Assign
POST /api/appworkstipsgeneric/entities/todo/items/1/Assignee/actions/Forward
POST /api/appworkstipsgeneric/entities/todo/items/1/Assignee/actions/Claim
POST /api/appworkstipsgeneric/entities/todo/items/1/Assignee/actions/Revoke


Method ReST URL
POST /api/appworkstipsgeneric/entities/todo/items/1/Email/actions/SendEmail


Method ReST URL
GET /api/appworkstipsgeneric/entities/todo/items/1/Lifecycle/actions/followupActivities
POST /api/appworkstipsgeneric/entities/todo/items/1/Lifecycle/actions/AddTask

Within the decompiled code, I also see Task related URLs passing by with a long list of specific POST request actions; It’s a glimpse into the future where we see a more mature ReST API layer:

Method ReST URL
POST /api/appworkstipsgeneric/entities/todo/items/1/tasks/actions/Start | Stop | Pause | Revoke |
Suspend | Resume | Claim | Assign | Forward | Delegate | Skip | Complete |
AddRelatedTask | ModifyDueDate | ModifyStartDate
GET /api/appworkstipsgeneric/entities/todo/items/1/tasks/actions/CompleteTaskFollowups
GET /api/appworkstipsgeneric/entities/todo/items/1/tasks/actions/AddRelatedTaskFollowups

That’s an interesting list of API calls to make a bright API future! I leave it for this feature for now as we will probably see much more happening in this ReST layer of the platform; We just wait till it’s fully available by default.

Additional task actions

It’s a long time we saw any new building blocks being introduces into the entity modeling, but this feature does have it! Tell me, Tell me…Well, add the Lifecycle BB which gets delivered with a related “LifecycleTask” entity…Open that one!

…we wait, view, view again…would it not?

Nope…Asked support again! Also, a beta feature to be enabled by OpenText support. Too bad for us to give a glimpse! What did we expect to get? Well, a new BB called ‘Task Outcome’ where we can define custom task actions (which related back to are ReST API updates!). At the moment a task always shows all possible actions, but this BB can limit the list.

For a task we also have 2 new extra actions available: ‘Approve’, and ‘Reject’. Let’s continue our journey and recheck this feature once it’s fully available in the next release.

New UX for AppWorks Administration

The ‘old’ UX is removed and completely “revamped” (It’s for me an unfamiliar word, but sounds like “new & improved”) with a new UX:


Well, it ‘smells’ indeed newish, and it is indeed consistent with the runtime, but if it makes that much of a difference? I doubt it…Only the administrators will be in this layer of the platform. When is it our turn (as developers) for having a nice consistent UX in design time? 😉

Email configuration enhancements

This feature makes it possible to translate the default folders which are created in the storage back-end. Folders like ‘Inbox’, ‘Sent’, and ‘Attachments’. It’s a bit hard to try this one out as we need an external CMS (Documentum / OT Content Server), and make sure the mail connector is up and running. Both are not available on my VM at the moment for this release. The effort to implement is too much for just trying out some localized folder naming. Too bad for you, but I believe this feature on the blue eyes of OpenText. 😍

Rule engine enhancements

This all has to do with server-side validations for…? Yes, for what? The feature is talking about a new rule engine API to run the property (??), and validate child entities based on child entity relations. If you know where we’re talking about here? Let me know in the comments…

There is also a configuration added to add a child (or related entity) categories for validations.

Well, that leaves me with open question and a short dive into the rule engine. The only entrance I know of is the BPM service container where we have the ability to enable the ‘Rule Engine’ option:


We also learned about the rule engine already during a play-off with a decision table in our BPMs, but what relation does this option have with the feature description?

Just a sleepless night with heavy “rule engine” dreams! 😴😴😴

A good morning with a rethought on the ‘property’ question mark and the rule engine though! This “smells” off-course like the “Rule” building block which we can add to an entity (I sometimes forget to think in “entity modeling” as we do also a lot of work in the “BPM modeling”). On the ‘Rule BB’ we define that validation property and do we have the ability to execute some action (also based on relations). The ‘relations’ part and playing with ‘categories’ is already described in above feature “Using form ‘categories’ of related entities”!! Aha…So, the engineers probably needed to update something in the rule engine API to make that link possible in the UI and concluded that it might give a performance boost to handle the validations server-side…Yeah! That’s what this is all about…right? Let me know otherwise!

That’s it…Playground 21.4 is open and ready to be used. I give it a ‘DONE’ on this update post with a nice overview of the new features for this GA 2021 Q4 release. Happy low code with this brand-new release, and I see you in the next post!

Don’t forget to subscribe to get updates on the activities happening on this site. Have you noticed the quiz where you find out if you are also “The AppWorks guy”?