How Do I Introduce a StreamBase Project into My CI/CD Pipeline?

How Do I Introduce a StreamBase Project into My CI/CD Pipeline?

book

Article ID: KB0138402

calendar_today

Updated On:

Products Versions
TIBCO Streaming 11.1 and later

Description

Overview

StreamBase projects follow standard Maven conventions and can be integrated into most enterprise CI/CD platforms and orchestrators (Jenkins, GitLab CI, GitHub Actions, Azure DevOps, etc.). The integration process involves automated builds, testing, containerization, and deployment of fragments and StreamBase Applications.

A typical CI/CD pipeline for StreamBase includes these stages:

  • Build - Compile EventFlow and custom code to eventflow fragment, application archive, or container image
  • Test - Execute unit and integration tests found in src/test/java
  • Deploy - install archive to nodes and start
  • Validate - Health checks and smoke tests in target environment

These should not be confused with Maven targets or phases, even though specific Maven commands are useful for each stage. For example:

  • 'mvn install' will run 'test' as well.
  • 'mvn deploy' runs 'install', 'test', and pushes artifacts to a repository, but does not start a node by itself.
  • 'mvn validate' only checks the pom.xml and project structure and is not related to the pipeline stage.

Each stage is typically scripted to conform to the expectations of the build orchestrator, and are integrated into the pipeline by running those scripts.

For example, the Build stage for a Streaming application is simply implemented by the command:
    mvn install -DskipTests
The Test stage may be:
    mvn test
The Deploy stage may be a script with steps:
    mvn deploy -DskipTests
    cd {deployment environment}
    cp my_app-ef-application-1.0.0.zip {execution environment}
    epadmin install node nodename=A.X application=my_app-ef-application-1.0.0.zip adminport=22000
    epadmin adminport=22000 start node

Note, the Maven 'deploy' target requires specific configuration in the pom.xml file, for example:

<distributionManagement>  
  <repository>  
    <id>releases</id>  
    <url>https://repo.example.com/releases</url>  
  </repository>  
  <snapshotRepository>  
    <id>snapshots</id>  
    <url>https://repo.example.com/snapshots</url>  
  </snapshotRepository>  
</distributionManagement>

When deploying to remote repositories, configure authentication credentials in the local Maven local repository file, settings.xml .

Prerequisites

Before setting up your CI/CD pipeline, ensure you have:

  • StreamBase projects organized as Maven modules with pom.xml files
  • Projects committed to a version control system (Git, SVN, etc.)
  • Supported Java Development Kit (JDK) installed on build agents
  • Supported Maven version available on build agents
  • Access to a Maven repository (Maven Central or internal repository)
  • For containerized deployments: a container runtime on build agents
  • A container registry (Docker Hub, Artifactory, Amazon ECR, etc.) for storing images

Version Control Setup

Structure your StreamBase project repository to support CI/CD:

  • Project Root - Contains a parent pom.xml defining common build properties and dependencies
  • Fragments - Each fragment project in its own subdirectory with its pom.xml
  • Applications - Each application project referencing fragments as dependencies
  • .gitignore - Exclude target/, .settings/, bin/, and build artifacts
  • Documentation - Include README.md with build and deployment instructions or make use of the project src/site/site.xml to structure markdown into HTML documentation.

Example Version Control repository structure:

my-streambase-project/
├── pom.xml     (parent POM of type "pom" with <module> references)
├── README.md
├── .gitignore
├── my-fragment-1/
│   ├── pom.xml (POM with no project <dependencies>)
│   └── ...
├── my-fragment-2/
│   ├── pom.xml (POM with <dependency> on "my-fragment-1")
│   └── ...
└── my-application/
    ├── pom.xml (POM with <dependency> on "my-fragment-2" but not "my-fragment-1")
    ├── src/
    └── ...

Build Stage Configuration

The build stage compiles EventFlow modules, custom Java code, and resolves dependencies.

Maven Build Commands

Execute these Maven goals in sequence for a complete build:

  1. Clean -- mvn clean -- Remove previous build artifacts from target/ folder and stops and removes test nodes
  2. Compile -- mvn compile -- Compile all sources to classes in target/ folder
  3. Install -- mvn install -DskipTests -- Combine all artifacts into JAR and ZIP files in the local Maven repository
    -DskipTests  - Use -DskipTests to prevent running tests during this phase (recommended). Remove this flag to run tests so that test failures are logged with the installed version.

Combined command for a typical automated CI/CD pipeline: mvn clean install -DskipTests -B -q

  • -B -- Batch mode (no interactive prompts)
  • -q -- Quiet mode (minimal output)

Developers are advised to interactively use: mvn install -DskipTests. This displays any errors, avoids running unnecessary tests, and does not recompile classes that are already built from non-dirtied sources.

Jenkins Build Using Maven

This is an example of optional configuration and usage. Other build orchestrators will also have patterns for running Maven or shell scripts which can call Maven to perform the build.

See the Jenkins Pipeline example for Maven here: https://www.jenkins.io/doc/pipeline/examples/#maven-and-jdk-specific-version

Supply the paths to the Streaming JDK and Streaming installed Maven (example): {TIBCO_HOME}/str/11.3/jdk/bin {TIBCO_HOME}/str/11.3/sdk/mvn/bin

To deploy only into the local repository replace the shown 'mvn' command with the combined command shown above: mvn clean install -DskipTests -B -q Otherwise to deploy into a remote repository, use the deploy target as shown in the example. The project POM must supply <repository> configuration and the local Maven settings.xml file must supply authentication credentials to use that repository.

Build Failure Handling

Configure your pipeline to halt immediately on build failure:

  • Set the pipeline exit code to non-zero on Maven build failures (most CI/CD systems do this by default)
  • Collect and archive build logs for debugging, target/ directories, and Maven output
  • Notify developers immediately of compilation failures (do not proceed to test or deployment stages)

Testing Strategy

Include automated testing to validate EventFlow logic and custom adapters before deployment.

Unit and Integration Tests

StreamBase supports JUnit 4 and JUnit 5 for testing custom operators and adapters. Run tests as part of the build: mvn test Or include tests in the install phase: mvn install -B -q (omitting -DskipTests allows tests to run)

Configure your pom.xml to generate test reports:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.22.2</version>
  <configuration>
 <reportFormat>plain</reportFormat>
  </configuration>
</plugin>

Collect test results from target/surefire-reports/ and make them visible in your CI/CD dashboard.

EventFlow Application Testing

For EventFlow applications, consider:

  • Testing custom Java operators and adapters using JUnit (built into the project)
  • Integration tests that start a test node and validate data flows (use epadmin commands to start/stop nodes)

Artifact and Container Management

StreamBase Application Archives

The Maven build produces a .zip (StreamBase Application) archive. This is the deployable artifact containing the application and all fragments. After mvn install, the archive is located in the active project at: target/my-application-1.0.0-ep-application.zip

Archive this artifact in your build repository (Artifactory, Nexus, etc.) for later deployment:

  • Assign a version based on your versioning scheme (e.g., git commit SHA, release number)
  • Tag with build metadata (branch, timestamp, build ID)
  • Keep artifacts for a defined retention period for troubleshooting

Docker Container Images

For containerized deployments, build Docker container images from the StreamBase Application archive:

  1. Create a Dockerfile in your application project that packages the .zip archive. Reference the Docker Dockerfile guide for details.

  2. Build the image in your CI/CD pipeline:
    docker build -t my-app:$BUILD_VERSION .

  3. Tag the image for your registry:
    docker tag my-app:$BUILD_VERSION my-registry.example.com/my-app:$BUILD_VERSION
    docker tag my-app:$BUILD_VERSION my-registry.example.com/my-app:latest

  4. Push the image(s) to your container registry:
    docker push my-registry.example.com/my-app:$BUILD_VERSION
    docker push my-registry.example.com/my-app:latest

Ensure your build agent has authenticated access to the container registry before pushing.

Deployment Stage

Direct Node Deployment

For traditional deployments to StreamBase nodes:

  1. Stop the running node:

 epadmin --host targethost --adminport 5005 stop node

  1. Remove the application from the target node:

 epadmin --host targethost --adminport 5005 remove node

  1. Copy the new .zip archive to the target host (via SCP, artifact repository, etc.)
  2. Install the application on the target node:

 epadmin --host targethost --adminport 5005 install node--application /path/to/app.zip

  1. Start the node:

 epadmin --host targethost --adminport 5005 start node

  1. Verify the node status (see topic Post-Deployment Validation)

For automated deployment, wrap these commands in a shell script and invoke it from your CI/CD pipeline. Use SSH key-based authentication for epadmin connections.

Container and Cloud Deployment

Please see the documentation and tutorials for creating container images found in the documentation here:
  TIBCO Streaming > StreamBase Admin Guide > Cloud
StreamBase Applications encapsulated in containers can be integrated into Kubernetes, with or without Helm control, and can by uploaded to an Image Registry, for example Docker Hub, or to a site-specific image registry.

For current configuration examples, see the Docker sample projects available in Studio by importing samples from:
  TIBCO Supported Samples > Docker: Samples
The sample configuration will be more current than the examples shown below for reference. 

Product Activation configuration for container deployments is described in the product documentation here:
  TIBCO Streaming > Welcome Guide > Activation in TIBCO Streaming and Model Management Server, Streaming Maven Archetypes

Kubernetes Deployment

For Kubernetes deployments, use the built container image:

  1. Create a Kubernetes Deployment manifest that references the container image and configures resource limits, environment variables, and readiness probes:

# ConfigMap for configuration  
#  
apiVersion: v1  
kind: ConfigMap  
metadata:  
 name: my-streambase-app-configuration  
 labels:  
   app.kubernetes.io/part-of: my-streambase-app  
   app.kubernetes.io/name: my-streambase-app-configuration  
data:  
---

#  
# ConfigMap for resources  
#  
apiVersion: v1  
kind: ConfigMap  
metadata:  
 name: my-streambase-app-resources  
 labels:  
   app.kubernetes.io/part-of: my-streambase-app  
   app.kubernetes.io/name: my-streambase-app-resources  
data:  
---

#  
# use a cluster role to allow the application to access the Kubernetes API  
#  
kind: ClusterRole  
apiVersion: rbac.authorization.k8s.io/v1  
metadata:  
 name: my-streambase-app-cr  
rules:  
- apiGroups: [""]  
 resources: ["services", "pods"]  
 verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]  
---

#  
# Service account to install and run the pods with  
#  
apiVersion: v1  
kind: ServiceAccount  
metadata:  
 name: my-streambase-app-sa  
---

#  
# use a cluster role binding to bind the cluster role to the above service account  
#  
apiVersion: rbac.authorization.k8s.io/v1  
kind: ClusterRoleBinding  
metadata:  
 name: my-streambase-app-crb  
roleRef:  
 apiGroup: rbac.authorization.k8s.io  
 kind: ClusterRole  
 name: my-streambase-app-cr  
subjects:  
- kind: ServiceAccount  
 name: my-streambase-app-sa  
 namespace: az-datastreams  
---

#  
# application cluster as a stateful set  
#  
apiVersion: apps/v1  
kind: StatefulSet  
metadata:  
 name: my-streambase-app  
 labels:  
   app.kubernetes.io/part-of: my-streambase-app  
   app.kubernetes.io/name: my-streambase-app  
spec:  
 selector:  
   matchLabels:  
     app: my-streambase-app  
 serviceName: my-streambase-app  
 #  
 # initially 2 eventflow nodes in the cluster  
 # can be scaled up or down  
 #  
 replicas: 2  
 #  
 # start all pods at the same time  
 #  
 podManagementPolicy: Parallel  
 #  
 # Enable rolling updates  
 #  
 updateStrategy:  
   type: RollingUpdate  
 template:  
   metadata:  
     labels:  
       app: my-streambase-app  
       app.kubernetes.io/part-of: my-streambase-app  
   spec:  
     serviceAccountName: my-streambase-app-sa  
     securityContext:  
       fsGroup: 1000  
     volumes:  
      - name: configuration  
        configMap:  
          name: my-streambase-app-configuration  
      - name: resources  
        configMap:  
          name: my-streambase-app-resources  
      - name: my-streambase-app-tmp  
        emptyDir: {}  
      - name: my-streambase-app-node  
        emptyDir: {}  
     containers:  
      - name: my-streambase-app  
        #  
        # docker image to use  
        #  
        image: my-registry.example.com/my-app:$BUILD_VERSION  
        imagePullPolicy: Always  
        #  
        # mount the configuration and resources volumes  
        #  
        volumeMounts:  
        - name: configuration  
          mountPath: /var/opt/tibco/streambase/configuration  
        - name: resources  
          mountPath: /var/opt/tibco/streambase/resources  
        - name: my-streambase-app-tmp  
          mountPath: /tmp  
        - name: my-streambase-app-node  
          mountPath: /var/opt/tibco/streambase/node  
        #  
        # Share application logs to docker console  
        #  
        tty: true  
        #  
        # set Streaming node name  
        #  
        env:  
        - name: POD_NAME  
          valueFrom:  
            fieldRef:  
              fieldPath: metadata.name  
        - name: POD_NAMESPACE  
          valueFrom:  
            fieldRef:  
              fieldPath: metadata.namespace  
        - name: APPNAME  
          value: my-streambase-app  
        - name: STREAMING_NODENAME  
          value: "$(POD_NAME).$(APPNAME)"  
        #  
        # set the application to run as user 1000  
        #  
        securityContext:  
          runAsUser: 1000  
          readOnlyRootFilesystem: true  
        #  
        # use a startup probe to wait for the application to be ready  
        #  
        startupProbe:  
          exec:  
            command:  
              - /bin/sh  
              - -c  
              - touch /tmp/healthy; cat /tmp/healthy  
          initialDelaySeconds: 20  
          failureThreshold: 30  
          periodSeconds: 10  
        #  
        # use healthcheck API for an initial wait until the application is ready  
        #  
        readinessProbe:  
          httpGet:  
            path: /healthcheck/v1/status  
            port: 8008  
          initialDelaySeconds: 60  
          periodSeconds: 10  
        #  
        # use healthcheck API for on-going health  
        #  
        livenessProbe:  
          httpGet:  
            path: /healthcheck/v1/status  
            port: 8008  
          initialDelaySeconds: 240  
          periodSeconds: 10  
        #  
        # set resource limits  
        #  
        resources:  
          limits:  
            cpu: '4'  
            memory: 4Gi  
          requests:  
            cpu: '2'  
            memory: 2Gi  
        #  
        # attempt tidy-shutdown to remove discovery service objects  
        #  
        lifecycle:  
          preStop:  
            exec:  
              command: ["/bin/sh","-c","/opt/tibco/streambase/stop-node"]
  1. Apply the manifest to your Kubernetes cluster:

 kubectl apply-f deployment.yaml

  1. Monitor the rollout and verify pod status

See Kubernetes and EventFlow for more information on Kubernetes deployment.

Helm Deployment

A Helm deployment of Streaming application images provides greater flexibility in managing local license files.

For helm deployments, use the built container image:

  1. Edit the Helm Chart that references the container image and configures resource limits, environment variables, and readiness probes in target/helm/my-streambase-app/templates/ as {PROJ}-app.yaml (for example project "my-streambase-app"):
{{- if .Values.containerLicenseDirectory }}  
#  
# Secret for license files  
#  
apiVersion: v1  
kind: Secret  
metadata:  
  name: my-streambase-app-license-files  
  labels:  
    app.kubernetes.io/part-of: my-streambase-app  
    app.kubernetes.io/name: my-streambase-app-license-files  
type: Opaque  
data:  
{{ (.Files.Glob "licenses/*").AsSecrets | indent 2 }}  
---  
{{- end }}

#  
# ConfigMap for license configuration  
#  
apiVersion: v1  
kind: ConfigMap  
metadata:  
  name: my-streambase-app-license-configuration  
  labels:  
    app.kubernetes.io/part-of: my-streambase-app  
    app.kubernetes.io/name: my-streambase-app-license-configuration  
data:  
  license.conf: |-  
{{ .Files.Get "license.conf" | indent 4 }}  
---

#  
# ConfigMap for configuration  
#  
apiVersion: v1  
kind: ConfigMap  
metadata:  
  name: my-streambase-app-configuration  
  labels:  
    app.kubernetes.io/part-of: my-streambase-app  
    app.kubernetes.io/name: my-streambase-app-configuration  
data:  
---

#  
# ConfigMap for resources  
#  
apiVersion: v1  
kind: ConfigMap  
metadata:  
  name: my-streambase-app-resources  
  labels:  
    app.kubernetes.io/part-of: my-streambase-app  
    app.kubernetes.io/name: my-streambase-app-resources  
data:  
---

#  
# use a cluster role to allow the application to access the Kubernetes API  
#  
kind: ClusterRole  
apiVersion: rbac.authorization.k8s.io/v1  
metadata:  
  name: my-streambase-app-cr  
rules:  
- apiGroups: [""]  
  resources: ["services", "pods"]  
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]  
---

#  
# Service account to install and run the pods with  
#  
apiVersion: v1  
kind: ServiceAccount  
metadata:  
  name: my-streambase-app-sa  
---

#  
# use a cluster role binding to bind the cluster role to the above service account  
#  
apiVersion: rbac.authorization.k8s.io/v1  
kind: ClusterRoleBinding  
metadata:  
  name: my-streambase-app-crb  
roleRef:  
 apiGroup: rbac.authorization.k8s.io  
  kind: ClusterRole  
  name: my-streambase-app-cr  
subjects:  
- kind: ServiceAccount  
  name: my-streambase-app-sa  
  namespace: {{ .Release.Namespace }}  
---

{{- if eq .Values.cloudPlatform "openshift" }}

#  
# On openshift, create an scc allowing the stateful set's pods to run as a specific user  
#  
apiVersion: security.openshift.io/v1  
kind: SecurityContextConstraints  
metadata:  
  name: my-streambase-app-scc  
  annotations:  
    "helm.sh/hook": "pre-install"  
    "helm.sh/hook-weight": "0"  
allowHostDirVolumePlugin: false  
allowHostIPC: false  
allowHostNetwork: false  
allowHostPID: false  
allowHostPorts: false  
allowPrivilegedContainer: false  
readOnlyRootFilesystem: true  
allowedCapabilities: null  
runAsUser:  
  type: RunAsAny  
seLinuxContext:  
  type: MustRunAs  
fsGroup:  
  type: RunAsAny  
supplementalGroups:  
  type: RunAsAny  
---

#  
# CR for using the SCC  
#  
apiVersion: rbac.authorization.k8s.io/v1  
kind: ClusterRole  
metadata:  
  name: system:openshift:scc:my-streambase-app-scc  
rules:  
- apiGroups:  
  - security.openshift.io  
  resourceNames:  
  - my-streambase-app-scc  
  resources:  
  - securitycontextconstraints  
  verbs:  
  - use  
---

#  
# Bind the SCC to the service account  
#  
apiVersion: rbac.authorization.k8s.io/v1  
kind: ClusterRoleBinding  
metadata:  
  name: system:openshift:scc:my-streambase-app-scc  
roleRef:  
  apiGroup: rbac.authorization.k8s.io  
  kind: ClusterRole  
  name: system:openshift:scc:my-streambase-app-scc  
subjects:  
- kind: ServiceAccount  
  name: my-streambase-app-sa  
  namespace: {{ .Release.Namespace }}  
---

{{- end }}

#  
# application cluster as a stateful set  
#  
apiVersion: apps/v1  
kind: StatefulSet  
metadata:  
  name: my-streambase-app  
  labels:  
    app.kubernetes.io/part-of: my-streambase-app  
    app.kubernetes.io/name: my-streambase-app  
spec:  
  selector:  
    matchLabels:  
      app: my-streambase-app  
  serviceName: my-streambase-app  
  #  
  # initially 1 eventflow nodes in the cluster  
  # can be scaled up or down  
  #  
  replicas: {{ .Values.replicaCount }}  
  #  
  # start all pods at the same time  
  #  
  podManagementPolicy: Parallel  
  #  
  # Enable rolling updates  
  #  
  updateStrategy:  
    type: RollingUpdate  
  template:  
    metadata:  
      labels:  
        app: my-streambase-app  
        app.kubernetes.io/part-of: my-streambase-app  
    spec:  
      serviceAccountName: my-streambase-app-sa  
      securityContext:  
        fsGroup: 1000  
      volumes:  
{{- if .Values.containerLicenseDirectory }}  
        - name: license-files  
          secret:  
            secretName: my-streambase-app-license-files  
{{- end }}  
        - name: license-configuration  
          configMap:  
            name: my-streambase-app-license-configuration  
        - name: configuration  
          configMap:  
            name: my-streambase-app-configuration  
        - name: resources  
          configMap:  
            name: my-streambase-app-resources  
        - name: my-streambase-app-tmp  
          emptyDir: {}      
        - name: my-streambase-app-node  
          emptyDir: {}  
      containers:  
        - name: my-streambase-app  
          #  
          # docker image to use  
          #  
{{- if .Values.containerRegistry }}  
          image: {{ .Values.containerRegistry }}/my-streambase-app:0.0.1-SNAPSHOT  
{{- else}}  
          image: my-streambase-app:0.0.1-SNAPSHOT  
{{- end }}  
          imagePullPolicy: Always  
          #  
          # mount the configuration and resources volumes  
          #  
          volumeMounts:  
{{- if .Values.containerLicenseDirectory }}  
          - name: license-files  
            mountPath: {{ .Values.containerLicenseDirectory }}  
{{- end }}  
          - name: license-configuration  
            mountPath: /var/opt/tibco/streambase/license-configuration  
          - name: configuration  
            mountPath: /var/opt/tibco/streambase/configuration  
          - name: resources  
            mountPath: /var/opt/tibco/streambase/resources  
          - name: my-streambase-app-tmp  
            mountPath: /tmp    
          - name: my-streambase-app-node  
            mountPath: /var/opt/tibco/streambase/node  
          #  
          # Share application logs to docker console  
          #  
          tty: true  
          #  
          # set Streaming node name  
          #  
          env:  
          - name: POD_NAME  
            valueFrom:  
              fieldRef:  
                fieldPath: metadata.name              
          - name: POD_NAMESPACE  
            valueFrom:  
              fieldRef:  
                fieldPath: metadata.namespace  
          - name: APPNAME  
            value: my-streambase-app  
          - name: STREAMING_NODENAME  
            value: "$(POD_NAME).$(APPNAME)"  
          - name: STREAMING_LICENSECONFIGURATION  
            value: /var/opt/tibco/streambase/license-configuration/license.conf  
          #  
          # set the application to run as user 1000    
          #    
          securityContext:  
            runAsUser: 1000  
            readOnlyRootFilesystem: true  
          #  
          # use a startup probe to wait for the application to be ready  
          #  
          startupProbe:  
            exec:  
              command:  
                - /bin/sh  
                - -c  
                - touch /tmp/healthy; cat /tmp/healthy  
            initialDelaySeconds: 20  
            failureThreshold: 30  
            periodSeconds: 10  
          #  
          # use healthcheck API for an initial wait until the application is ready  
          #  
          readinessProbe:  
            httpGet:  
              path: /healthcheck/v1/status  
              port: 8008  
            initialDelaySeconds: 60  
            periodSeconds: 10  
          #  
          # use healthcheck API for on-going health  
          #  
          livenessProbe:  
            httpGet:  
              path: /healthcheck/v1/status  
              port: 8008  
            initialDelaySeconds: 240  
            periodSeconds: 10  
          #  
          # set resource limits  
          #  
          resources:  
            limits:  
              cpu: '4'  
              memory: 4Gi  
            requests:  
              cpu: '2'  
              memory: 2Gi  
          #  
          # attempt tidy-shutdown to remove discovery service objects  
          #  
          lifecycle:  
            preStop:  
              exec:  
                command: ["/bin/sh","-c","/opt/tibco/streambase/stop-node"]  
---

#  
# Horizontal Pod Autoscaler  
#  
apiVersion: autoscaling/v2  
kind: HorizontalPodAutoscaler  
metadata:  
  name: my-streambase-app-hpa  
  namespace: {{ .Release.Namespace }}  
spec:  
  scaleTargetRef:  
    apiVersion: apps/v1  
    kind: StatefulSet  
    name: my-streambase-app  
  minReplicas: 1  
  maxReplicas: 3  
  metrics:  
    - type: Resource  
      resource:  
        name: cpu  
        target:  
          type: Utilization  
          averageUtilization: 50
  1. Apply the Helm Chart:

helm install <release-name> ./path/to/chart-directory

  1. Monitor the rollout and verify pod status

Post-Deployment Validation

After deployment, validate that the application is running correctly:

Node Health Checks

Use epadmin to verify the node and its engines are running and healthy:

Display node-level information:

epadmin --host targethost --port 5005 display node

Display engine-level information:

epadmin --host targethost --port 5005 display engine

Expected output includes:

  • Node is RUNNING
  • All configured engines are RUNNING
  • Application state is RUNNING

For a failed deployment, the node will show STOPPED or specific engines will be FAILED. Check node logs for error details.

Smoke Tests

Run lightweight smoke tests to verify application functionality:

  • Send test events to input streams and verify expected output on downstream streams
  • Query LiveView tables to verify data is flowing correctly
  • Invoke REST API endpoints (if configured) and validate responses
  • Check that expected log messages appear in application logs

Script these tests using the Streaming administration utility (e.g. epadmin --adminport=nodePortNumber enqueue stream ...) or REST API calls, and run them from your CI/CD pipeline after deployment completes.

Rollback Strategy

If post-deployment validation fails, have a rollback plan:

  • For traditional deployments: Keep the previous .zip archive and use epadmin to restart the previous version
  • For Kubernetes: Revert the Deployment manifest to the previous image version or use kubectl rollout undo
  • Document the rollback procedure and test it regularly in non-production environments

Best Practices

  • Version Everything - Use semantic versioning for StreamBase artifacts and Docker images. Include git commit SHA for traceability.
  • Isolate Environments - Maintain separate development, testing, and production StreamBase nodes. Use CI/CD pipeline stage gates to control promotion between environments.
  • Automate Tests - Maximize automation of unit, integration, and smoke tests. Make test failure a hard stop in the pipeline.
  • Log and Monitor - Configure comprehensive logging and integrate with your monitoring system. Set up alerts for node failures or application errors.
  • Secure Credentials - Use your CI/CD platform's secrets management (not environment variables) for credentials, API keys, and registry authentication.
  • Document Dependencies - Clearly list required infrastructure (nodes, database connections, message queues) in your README and deployment documentation.
  • Use Parallel Stages - Run independent tests and builds in parallel to reduce pipeline execution time. However, ensure deployment stages are sequential to avoid conflicts.
  • Archive Logs - Collect and archive build logs, test reports, and deployment logs for troubleshooting and audit purposes.
  • Plan for High Availability - If using clusters, ensure your CI/CD deployment updates nodes in a rolling fashion to maintain availability during deployments.

Issue/Introduction

This article describes the recommended approach for integrating StreamBase projects into continuous integration and continuous deployment (CI/CD) pipelines, including build automation, testing strategies, and deployment practices.

Contents

Overview
Prerequisites
Version Control Setup
Build Stage Configuration
Testing Strategy
Artifact and Container Management
Deployment Stage
Post-Deployment Validation
Best Practices