No description
  • Groovy 89.5%
  • CSS 5.9%
  • Shell 4.4%
  • JavaScript 0.2%
Find a file
2026-10-08 14:06:15 +02:00
buildSrc optimize deployment system 2024-09-17 19:10:23 +02:00
docker added backup script 2025-03-04 11:13:34 +01:00
gradle/wrapper optimize deployment system 2024-09-17 19:10:23 +02:00
grails-app use BS icons in menu 2026-10-08 14:06:15 +02:00
src upgrade brute-force stuff to v.1.2.1 2025-03-21 16:56:13 +01:00
tools remove commented comment due to server startup error 2024-12-19 16:42:33 +01:00
.editorconfig optimize deployment system 2024-09-17 16:46:23 +02:00
.gitignore upgrade grails + dependencies 2024-06-05 11:42:14 +02:00
.sdkmanrc-template upgrade dependencies 2024-09-17 13:30:21 +02:00
build.gradle upgrade build scripts & dependencies 2024-12-24 14:50:05 +01:00
CHANGELOG.md add Users via JMS, spring security, ctag standard plugins 2022-11-29 18:27:08 +01:00
deploy.sh use https://activities.stage.westend61.com/ for STAGE 2024-12-12 12:48:44 +01:00
deploy2STAGE.sh use https://activities.stage.westend61.com/ for STAGE 2024-12-12 12:48:44 +01:00
deployDocker2Stage.sh (NOT STAGE COMPATIBLE ANY MORE!) reinvent domainId for links; dont use Date if not necessary; add Postgres jsonb column handling (UserType and DB Dialect) 2024-06-10 12:22:23 +02:00
gradle.properties tomcat.version = 9.0.120 2026-10-02 15:19:15 +02:00
gradlew optimize deployment system 2024-09-17 19:10:23 +02:00
INSTALL.md use https://activities.stage.westend61.com/ for STAGE 2024-12-12 12:48:44 +01:00
PortForwardStage.sh add PortForwardStage.sh 2022-03-23 18:01:22 +01:00
README.md postgres db on stage, remove overwrite feature for imports 2024-06-20 12:06:36 +02:00
settings.gradle upgrade grails + dependencies 2024-06-05 11:42:14 +02:00
TODO.md use Gson (to prevent an outofmemory error on resizing some buffer arrays - like JsonSlurper...), convert legacy data to a 'legacyData' value (fixed data2Map), minor view enhancements 2022-03-30 08:59:58 +02:00
TODO_GOING_LIVE.md fine tune web access (do not allow any request fro any localhost) 2024-09-11 13:45:44 +02:00

Microservice to manage the Activity Traces of all our apps at a central place

Idea

All apps send the AT to this MicroService where it will be stored in a separated DB. For this it supports JMS, REST Service, etc. The combination of name,creationDate,module,domain and refUUID is considered unique.

Inbound

Send JSON payload. Make sure to send at least data for dateCreated and name (sent dateCreated will be saved as creationDate in the local database). All Dates are expected to be sent in the format "yyyy-MM-dd'T'HH:mm:ss.SSSXXX" with a fallback to ISO_DATE_TIME. All traces should only contain \n as line separator.

  • for JSON you can use the following snippet in your ActivityTrace class:
final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat( "yyyy-MM-dd'T'HH:mm:ss.SSSXXX" )

JSON asJson() {
   final Map atAsMap = [:]
   ActivityTrace.gormPersistentEntity.persistentPropertyNames.each { prop ->
      if( prop == 'dateCreated' ) {
         final String dateFormatted = dateCreated ? DATE_FORMAT.format( dateCreated ) : null
         atAsMap.put( prop, dateFormatted )
      } else if( prop == 'trace' ) {
         final String traceFormatted = trace?.replaceAll( '\\R', '\\\n' )
         atAsMap.put( prop, traceFormatted )
      } else {
         atAsMap.put( prop, this[ prop ] )
      }
   }

   return atAsMap as JSON
}
  • (deprecated) for a low level database export you can use the writeActivityTracesToJSON groovy scripts in the tools directory.

Data can be sent via the following interfaces:

REST

POST the JSON data of one ActivityTrace to

<ActivityTrace_Server_Host>/activityTrace/save

The result is either a HTTP Status Code 201 Created or an Error.

or

POST a JSON list of several ActivityTraces to

<ActivityTrace_Server_Host>/activityTrace/saveBatch

or

copy your JSON export file to the data directory and import it at

<ActivityTrace_Server_Host>/import

Only not already existing entries are saved. The combination of name,creationDate,module,domain,refUUID,userName,chainId is considered unique.

Possible configuration for the batch save (via HTTP parameters) or in the import GUI:

  • test (default: false): do not save anything. Please be aware, that with a clean test run there still might be save errors afterwards!
  • max (default: -1): save (or test) up to max entries from the import data. A negative value is ignored and all input is processed.

The result is either a HTTP Status Code 201 Created, an Error if nothing is saved or HTTP Status Code 207 MultiStatus with a JSON response containing the count of successfully saved instances and the ones with errors.

MultiStatus Response Example:

{
   "multistatus": {
      "success": <number of successfully saved instances>,
      "error": [
         {
            "instance": { <failed instance> },
            "reason": <error message>
         },
         ...
      ]
   }
}

JMS

Send your data to one of the queues activityTrace.records.queue.dev, activityTrace.records.queue.stage or activityTrace.records.queue.prod.

f.e. using this console script:

import java.time.*
import java.time.format.*
import javax.jms.*

<my-list-of-activityTrace-ids>.each { aid ->
   def at = ActivityTrace.get( aid )
   def queueName = 'activityTrace.records.queue.prod'

   ctx.getBean( 'jmsService' ).send( queue: queueName, at.asJson().toString().getBytes() ) { Message msg ->
      msg.JMSCorrelationID = UUID.randomUUID().toString()
      msg.setStringProperty( 'tenant', 'W61' )
      msg.setStringProperty( 'appName', 'asset-manager' )
      msg.setStringProperty( 'action', 'saveActivityTrace' )
      msg.setStringProperty( 'date', LocalDateTime.now().format( DateTimeFormatter.ISO_DATE_TIME ) )
      msg.setJMSDeliveryMode( DeliveryMode.PERSISTENT )
      msg
   }
}

Example configuration in application.groovy (sending app)

The ActivityTrace functionality can be switched off app wide. If available, it will check if JMS is disabled. If JMS is available, it will try to send data via JMS first. It will try to send data via HTTP only if JMS is disabled or sending via JMS is switched off.

koala {
   // false: disables the creation and management of ActivityTraces regardless of any other configuration
   activityTrace.enabled = true
}

environments {
   development {
      jms {
         disabled = false
         activityTrace.queueName = 'activityTrace.records.queue.dev'
      }
       
      activityTrace {
         // false: disables sending of ActivityTrace data via Jms; will try HTTP configuration, if switched off
         sendViaJms = true
         url = 'http://localhost:8080'
         // false: disables sending of ActivityTrace data via HTTP as well; no fallback
         sendViaHttp = true // considered, if jms is disabled
      }
   }
   ...
}

Outbound

REST

Get HTML, CSV, XML or JSON payload with the export action:

// get a HTML table
GET <ActivityTrace_Server_Host>/activityTrace/export?format=table  or
GET <ActivityTrace_Server_Host>/activityTrace/export.table

// get a CSV list
GET <ActivityTrace_Server_Host>/activityTrace/export?format=csv  or
GET <ActivityTrace_Server_Host>/activityTrace/export.csv

// get a XML list
GET <ActivityTrace_Server_Host>/activityTrace/export?format=xml  or
GET <ActivityTrace_Server_Host>/activityTrace/export.xml

// get a JSON list
GET <ActivityTrace_Server_Host>/activityTrace/export?format=json  or
GET <ActivityTrace_Server_Host>/activityTrace/export.json

The result can be filtered via HTTP parameters:

GET <ActivityTrace_Server_Host>/activityTrace/export?format=table&chainId=1972415373

GET <ActivityTrace_Server_Host>/activityTrace/export?format=json&uuid=d0c12e65-4f54-4528-90fa-8caba2191b07

GET <ActivityTrace_Server_Host>/activityTrace/export?format=csv&dateFrom=2022-01-01T12:00:00