Skip to main content

Alerting Component

· One min read
Frédéric Hannes
Frédéric Hannes
R&D Engineer

The newest addition to our family of base components, the alerting component, has been released. The alerting component is intended to send simple alerts/notifications to various channels based on a pub-sub system. This is also an experiment to make more modular/extensible components by providing specific expanded integration points. Implementations for new channel to send alerts to can be provided externally in different components and will be integrated seamlessly into the system by the included expanders.

Out-of-the-box, it can send alerts over email, Slack and Pushover. For more information, check out the documentation page.

Default email template example

Expanders 5.20.0

· 3 min read
Koen De Cock
Koen De Cock
R&D Engineer

Changes and Improvements

New ValueType System

ValueFieldTypes are now obsolete and will be replaced with ValueTypes.

You can use the MigrateValueFieldsToValueType transmutation to migrate your ValueFields to the new ValueType representation.

The new ValueTypes support adding restrictions to some basic ValueTypes, like String patterns. So, it will be useful to check out the supported restrictions and see where they can be used in the model.

Expander compatibility

To make the model compatible with both new and old Expanders, ValueTypes are transformed to an equivalent ValueFieldType model and vice versa.

Custom ValueFieldTypes

Custom ValueFieldTypes will not be automatically migrated. Instead, look at the use-case and see if you can replace it with a SimpleValueType.

In case of a custom front-end, you can use the correct feature anchors to replace the default implementation using a feature. A reference implementation will be provided in the near future.

Furthermore, there are plans to implement more complex ValueTypes.

String length

The Strings ValueType is limited to 255 characters. Before this version, this limit was not enforced in the code. However, this version will enforce the limit in the SharedValidator class.

If you have a field that should not be limited, use the Text ValueType.

<field name="foo">
<valueField>
<type name="Text"/>
</valueField>
</field>

Mapping Xml Improvements

Some improvements have been added to simplify mapping files.

Filter and Distinct in List

First, the <list> tag has 2 new child tags:

  • <filter name="filterName" eval="condition">: Evaluate the condition. If the condition is false, the item will not appear in the list.
  • <distinct name="distinctionName" eval="value">: Evaluate the value. Items with duplicate values will be de-duplicated.

These feature were previously already available as the filter and unique attributes on the <list> tag. However, these tags can be interleaved with <let> tags to simplify some of the logic.

E.g. this:

<list name="oneToManyLinkFields" eval="dataElement.fields" param="field"
filter="field.linkField neq null and not field.linkField.linkFieldType.isMultivalued">
<value name="name" eval="field.name"/>
<value name="element" eval="field.linkField.linkFieldType.targetElement.name"/>
</list>

becomes:

<list name="oneToManyLinkFields" eval="dataElement.fields" param="field">
<filter name="isLinkField" eval="field.linkField neq null"/>
<let name="linkFieldType" eval="field.linkField.linkFieldType"/>
<filter name="isOneToMany" eval="not linkFieldType.isMultivalued"/>
<value name="name" eval="field.name"/>
<value name="element" eval="linkFieldType.targetElement.name"/>
</list>

NotEmpty and Flatten in ognl

2 methods have been attached to lists in OGNL statements in the mapping files:

<mapping>
<!-- List#notEmpty returns true iff the list has no items -->
<value name="hasDataElements" eval="component.dataElements.notEmpty"/>
<!-- List#flatten will turn a list-of-lists List<List<T>> into a flat list List<T> -->
<value name="allDataElements" eval="application.components.{ dataElements }.flatten"/>
</mapping>

String manipulation in OGNL

Several properties have been attached to Strings to give them similar features to the StringTemplates:

<value name="fieldCapitalized" eval="field.name.firstToUpper"/>
tip

It is best to leave all formatting to the StringTemplate files. However, this might help to simplify some specific use-cases.

Lambdas in OGNL

OGNL does not support java 8 lambda syntax. And while OGNL did have its own version of lambdas, these did not work together with java 8 functional interfaces. This has been fixed for the Function, Predicate and Supplier functions.

So now, you can use the OGNL lambda syntax with, for example, Optional:

<value name="valueName" eval="someOptionalValue.map(:[ #this.name ]).orElse('no value')"/>

REST Expanders 3.10.0

· 6 min read
Frédéric Hannes
Frédéric Hannes
R&D Engineer
danger

Some bugfixes were applied, use version 3.10.3 instead of 3.10.0.

Changes and improvements

OpenApi 3.0 support

caution

Using OpenApi 3.0 requires at least version 2.15.2 of the Docker image nsx-tomee-base.

In this version of rest-expanders, we've introduced support for OpenAPI 3.0. Previously we only supported OpenAPI 2.0, which was Swagger originally. Due to some technical challenges, we were not able to support OpenAPI 3.0 up to this point. Now that these hurdles have been cleared, we've finished the implementation and made it the new default.

The new version of the specification is also integrated with a Swagger UI front-end as was the case with the previous specification. This version does rely on a new major version of the Swagger library, which brings many breaking changes. As a regular, custom code will be heavily impacted by this change. We do provide a model option to switch back to OpenAPI 2.

info

For OpenAPI 3.0, the endpoints for the api specification have changed:

  • /{applicationName}/{basePath}/swagger.json to /{applicationName}/{basePath}/openapi.json
  • /{applicationName}/{basePath}/swagger.yaml to /{applicationName}/{basePath}/openapi.yaml

The location of Swagger UI has not been altered.

More information about updating can be found in the migration guide.

SecurityRight annotation

The SecurityRight annotation is used to define rights for an endpoint. Previously these would only be added to expanded endpoints when use of account::DataAccess was enabled. This made it difficult to add more functionality to the annotation. Now this annotation is added to all expanded endpoints and anchors are available in the annotation to add additional property values.

Expanders 5.19.0

· 4 min read
Frédéric Hannes
Frédéric Hannes
R&D Engineer

This version of Expanders is quite impactful. It has a breaking change that could potentially affect several projects if they did not apply the NS theory correctly. This change is the removal of the detailed constructor in the projection POJO classes. We carefully considered the impact of this change and this topic describes the motivation for that and other changes.

Resources

The expansion resources below provide Expanders 5.19.0.

ResourceVersion
Expanders5.19.0
nsx-default-stack2023.3.0
rest-jaxrs-stack3.9.0

Changes and improvements

Removal of detailed constructor

The projection POJO classes such as <dataElement>Details and <dataElement>Info have always had two constructors. The primary constructor is the constructor with no arguments. There was however also a secondary constructor with the database id and all fields of the projection as arguments. We have now removed the secondary constructor, as there is no technical reason for this to exist anymore.

The reason for removing the secondary constructor is that it violates Data Version Transparency, the first theorem of the NS theory. This theorem states that a changes in a data structure should not affect processing functions that consume them. This constructor, though generated by Expanders, would change whenever the relevant projection or fields in the DataElement change.

Example
Anti-Pattern

Imagine you have a DataElement with two fields:

The Expanders would generate a Details projection POJO with constructor(id: Long, name: String, value: String). This could've been used in multiple places to create an object of the POJO:

MyElementDetails myElement = new MyElementDetails(0L, "some name", "and a value");
...
CrudsResult<Void> result = createMethod(context.withParameter(new MyElementDetails(0L, "please don't", "do this")));

  • We now change the DataElement by adding a field:

    Now the detailed constructor becomes constructor(id: Long, name: String, value: String, anotherValue: Long) and every piece of code where it was used previously has to be updated. This is the textbook definition of a combinatorial effect.

  • Even worse would be if the order of the fields change:

    Now all code where the constructor is used will still compile correctly. The behavior will change completely at runtime.

The legacy option legacy.projectionDetailedConstructor.reenable was added to re-enable the old behavior where the secondary constructor was generated. This option will expire on the 1st of September 2023.

Pruning deprecated imports

Some expanders still contained some deprecated imports for code that was reworked or removed. These have now been removed, so the relevant classes could be deprecated or removed in nsx-runtime.

In version 5.16.0 of Expanders, we removed several expired legacy options. One such option was legacy.searchDataRefMethods.reenable. All related functionality has been removed from the expanders. As such, all related classes have now been removed from nsx-runtime in version 2023.0.0. The remaining related imports have been removed from all expanders for the following classes:

  • net.democritus.support.ejb3.SearchDataRefToSearchDetailsMapper
  • net.democritus.support.Paging
  • net.democritus.sys.SearchDataRef

In 2020 the implementation of the FileUploadFeature, used to upload files through the generated UI, was improved and imports for two now deprecated classes in nsx-runtime were left behind in the Enterer classes. These imports have now been removed, though the classes are at this time still present in nsx-runtime:

  • net.democritus.io.NioFileCopier
  • net.democritus.io.SimpleUriFormat

Expanders 5.18.0

· One min read
Jorren Hendriks
Jorren Hendriks
R&D Engineer

Changes and improvements

GetProjection

The behaviour of the getProjection method in the element cruds has been changed to no longer return an empty object when the requested element could not be found. Instead it now returns a CrudsError to allow for better error handling.

  • The option experimental.cruds.failOnProjectionNotFound has been removed, as it is now the default behaviour.
  • A legacy option legacy.cruds.getProjection.emptyOnError was added to revert to old behaviour. (Expires 2023-08-01)

This change shouldn't affect your application if errors were handled previously. If the application assumes the returned CrudsResult to be successful you either:

  • Handle the error explicitly, by checking CrudsResult.isError
  • Or by providing a default value, for example with CrudsResult.getValueOrElseGet(Projection::new)

Frontend support for Null fieldoperator

Finders specifying the Null fieldoperator will now be shown as a checkbox in the knockout UI to enable or disable the null check when searching. The label for this checkbox can be customized by overriding the $component.$dataElement.$field.null translation.

REST Expanders 3.7.0

· 2 min read
Frédéric Hannes
Frédéric Hannes
R&D Engineer

Changes and improvements

UniqueConstraints

This version of rest-expanders introduces initial support for the new UniqueConstraints added to the elements model. Though at this time the isUnique option will not yet be replaced by these constraints, if they are added to the model and fail validation, they will be correctly mapped to unique constraint validation errors in the REST API.

Known issues

  • This release breaks the DiagnosticInterceptor interface. This can affect implementations of the class in custom code that override the intercept(Diagnostic) method that was removed. Version 3.8.0 has a fix for backwards compatibility, though refactoring the custom class would be the preferred solution.

Base Components 2023.0.0

· 2 min read
Frédéric Hannes
Frédéric Hannes
R&D Engineer

The most notable change in this release of the base components is the pruning of several DataElements, which have been deprecated and unused for a very long time. It may be prudent to migrate databases of applications. Though these changes should not have a technical impact, these old data structures will just be a clutter in the database if not removed.

caution

If your application was initialized with an older version of NS Initializer, you may need to remove entries for the IdCounter element from your initial data XML file. The sql-expanders will throw an error on expansion if you provide entries for elements or fields that do not exist in the model.

Account component

From the account component, we removed the following DataElements:

  • Component
  • HelpInfo
  • Menu
  • MenuItem
  • Portal
  • Screen
  • ScreenProfile

Previous account component model:

Previous account component modelPrevious account component model

Current account component model:

Current account component modelCurrent account component model

Aside from these elements, the unused field DataAccess.target was also removed.

Utils component

From the utils component, we removed the following DataElements:

  • Execution
  • IdCounter
  • Thumbnail

Previous utils component model:

Previous utils component modelPrevious utils component model

Current utils component model:

Current utils component modelCurrent utils component model

The Executor TaskElement was also removed.

Workflow component

From the workflow component, we removed the following DataElements:

  • StateTimer
  • TimeTask

Previous workflow component model:

Previous workflow component modelPrevious workflow component model

Current workflow component model:

Current workflow component modelCurrent workflow component model

REST Expanders 3.6.0

· One min read
Frédéric Hannes
Frédéric Hannes
R&D Engineer

Migration guide

This version of the expanders provides an update of Swagger UI from 3.52.5 to 4.15.5. One notable change is that all inline JavaScript and CSS styling was moved from the main swagger-ui.html file into separate files swagger-initializer.js and index.css. The CSS file has simply been added as css/swagger-ui-index.css. The inline JavaScript code did however contain several anchors. These anchors have been moved from their original location in html/<componentName>-swagger.html to js/<componentName>-swagger-initializer.js. This pertains to the following anchors:

  • @before-setup and custom-before-setup
  • @config and custom-config
  • @after-setup and custom-after-setup

As all of these anchors were placed in inline javascript code, it should be sufficient move the harvest file from html/<componentName>-swagger.html.harvest to js/<componentName>-swagger-initializer.js.harvest.

Of course any expanders that may target these anchors will also have to be updated to inject features into the new file.

Expanders 5.16.0

· One min read
Koen De Cock
Koen De Cock
R&D Engineer

Changes and improvements

UniqueConstraint

This Expanders version introduces a new Element UniqueConstraint. Each DataElement can have one or more of these UniqueConstraints.

Each one lists a number of Fields. The constraint will generate a check to make sure it is not possible to create 2 instances. with the same values for these Fields.

It replaces the option uniqueKey and improves on it:

  • You can have more than one UniqueConstraint.
  • The check uses a dedicated query instead of a Finder, so that it will work even for null values.
  • No need to explicitly define a Finder.
  • No more loosely typed String to define the Fields.
ConvertUniqueKeyOptions Transmuter

You can automatically convert uniqueKey options by using the ConvertUniqueKeyOptions transmuter. In the µRadiant (version 1.8.3+), right-click on the Application and select Convert Unique Key Options.

Removed Options

Some of the Options have expired and have been removed:

  • legacy.logicDataMethods.reenable
  • legacy.oldCollectionMethods.reenable
  • legacy.oldSearchMethods.reenable
  • legacy.relationRetrievalMethods.reenable
  • legacy.searchDataRefMethods.reenable
  • legacy.struts.defaultStyle

Expanders 5.15.0

· 6 min read
Frédéric Hannes
Frédéric Hannes
R&D Engineer
Koen De Cock
Koen De Cock
R&D Engineer

Version 5.15.0 of the Expanders brings quite a few new features and improvements! This post will cover an overview of what's new and provide a migration guide to assist in updating. The full release notes can be found here.

Resources

The expansion resources below provide Expanders 5.15.0.

ResourceVersion
Expanders5.15.0
nsx-default-stack2022.15.0
rest-jaxrs-stack3.4.1
caution

Due to some structural changes in the way Struts is packaged, it is recommended to update to one of the listed stack resources. It is also recommended to update expanders-maven-plugin to at least version 2022.5.2.

Changes and improvements

Changes in GlobalOptionSettings

Several of the settings in GlobalOptionSettings have been replaced with options on the ApplicationInstance. The long-term goal is to make the GlobalOptionSettings, TechnicalInfrastructure, PresentationSettings and BusinessLogicSettings obsolete.

BeanInterfacePolicy

The beanInterfacePolicy setting could either be BOTH, LOCAL or REMOTE and controls which interfaces are present on the bean. However, in practice, only the LOCAL and BOTH settings were functional. The option ejb.interfaces.localOnly replaces beanInterfacePolicy='LOCAL', while beanInterfacePolicy='BOTH' becomes the default.

Security Options

The following flags have been migrated to options:

  • enforceHttpMethod: replaced by option struts.security.enforceHttpMethod (Prevents requests to struts control layer from using the wrong HTTP Method.)
  • useCsrfProtection: replaced by option struts.security.csrfProtection (Adds a security mechanism to protect against CSRF attacks.)
  • useJavaEESecurity: replaced by option struts.security.custom, or simply remove account Component from the Application. (Removes login mechanism from the struts-header.xml file.)

GenerateArtifactLabel

This feature added a postfix to the versions of Component artifacts in the project. This allows you to install artifacts or deploy them to the nexus so speed up subsequent maven builds by using e.g. the -Pslim profile.

The flag has been replaced by the option mvn.version.appendUniqueLabel. It also now appends the applicationInstance shortname and expanders version, instead of the names of the settings objects. This change is necessary if we want to move away from the settings elements.

CounterDefault

The counterDefault settings on GlobalOptionSettings used to support a GLOBAL value. This would cause all of the id's to be set programmatically based on a single table.

This has been removed as there are better alternatives (see below).

Identity generation strategy for JPA

The options persistence.identifier, persistence.sequence.name and persistence.sequence.schema have been renamed from options previously marked as experimental. These options allow a specific identity generation strategy to be selected for a DataElement. The options are available at any level of the model above DataElement and cascaded down. They can be overridden on a lower level for granular control if needed.

The options support either auto-incremented identity columns or native sequences.

For more information, visit the documentation about id generation.

Struts2 6.0

Support for Struts2 6.0.3 was added to the expanders and is now the default version. From this version and onward, the expanders will start supporting a specific contemporary release version of Struts to improve the distribution of security patches.

There are some breaking changes both in how we handle Struts and the framework itself. See the migration guide for more information.