
System Architecture Diagram

OSGI Bundle Lifecycle and Bundle Framework Event

Integration Flow for Event Handler
import com.sap.it.api.asdk.datastore.*
import com.sap.it.api.asdk.runtime.*
import com.sap.gateway.ip.core.customdev.util.Message
import groovy.json.JsonOutput
import org.osgi.framework.*
import org.osgi.service.event.*
def Message processData(Message message) {
//Get message properties, which were set in ContentModifier (1)
def eventHandlerId = message.getProperty("eventHandlerId")
def eventListenType = message.getProperty("eventListenType")
//Register our custom IFlow event
def res = registerOSGiEvent(eventHandlerId, eventListenType)
return message
}
/***********************************************
* This function helps registering OSGi events *
***********************************************/
private registerOSGiEvent(def eventHandlerId, def eventListenType) {
//Get general bundle context
def bundleCtx = FrameworkUtil.getBundle(Class.forName("com.sap.gateway.ip.core.customdev.util.Message")).getBundleContext()
//Define the topics we like to listen to
def topics = eventListenType
//Configure our event listener
def props = new Hashtable();
props.put(EventConstants.EVENT_TOPIC, topics)
props.put("custom.id", eventHandlerId)
//Register custom EventHandler as service and pass properties, credentials
bundleCtx.registerService(EventHandler.class.getName(), new DeployEventHandler(), props)
return [successful: true]
}
/**************************************************************
* This is the custom eventhandler class, we want to register *
**************************************************************/
public class DeployEventHandler implements EventHandler {
//This function will be called everytime, when an
//event with a matching topic passes by. Everything which
//should happen at an event, must be implemented here.
public void handleEvent(Event event) {
//The complete code is called as "async" Runnable in a different thread,
//because OSGi has a default timeout of 5000ms for events. If an event-
//handler takes more time, it will be blacklisted. By use of Runnable,
//we can bypass this limit.
Runnable runnable = {
//Build event information
def evntMsg = []
try {
evntMsg = [topic: event.getTopic(), bundleName: event.getProperty("bundle").getSymbolicName(), TimeStamp: event.getProperty("timestamp")]
def bundle = event.getProperty("bundle").getSymbolicName();
def pattern = ~/^Test_[a-fA-F0-9]{32}$/
if (!(bundle ==~ pattern)) {
def service = new Factory(DataStoreService.class).getService()
//Check if valid service instance was retrieved
if (service != null) {
def dBean = new DataBean()
dBean.setDataAsArray(JsonOutput.toJson(evntMsg).getBytes("UTF-8"))
//Define datatore name and entry id
def dConfig = new DataConfig()
dConfig.setStoreName("osgiEvents")
dConfig.setId(bundle)
dConfig.doOverwrite()
//Write to data store
def result = service.put(dBean, dConfig)
}
}
} catch (Exception e) {
def pattern = ~/An entry with id \w+ does already exist in data store \w+/
if (!(e instanceof com.sap.it.api.asdk.exception.DataStoreException &&
e.message ==~ pattern)) {
evntMsg = e.toString();
def service = new Factory(DataStoreService.class).getService()
//Check if valid service instance was retrieved
if (service != null) {
def dBean = new DataBean()
dBean.setDataAsArray(evntMsg.getBytes("UTF-8"))
//Define datatore name and entry id
def dConfig = new DataConfig()
dConfig.setStoreName("osgiEventsError")
dConfig.setId("error")
dConfig.doOverwrite()
//Write to data store
def result = service.put(dBean, dConfig)
}
}
}
}
//Call the Runnable
def thread = new Thread(runnable);
thread.start();
}
}cf push <NameForYourContainer> --docker-image asutoshmaharana23/jenkins-light-plugin:latest --docker-username <YourDockerHubUser>FROM jenkins/jenkins:alpine
ENV JENKINS_USER admin
ENV JENKINS_PASS admin
# Skip initial setup
ENV JAVA_OPTS -Djenkins.install.runSetupWizard=false
USER root
RUN apk add docker
RUN apk add py-pip
RUN jenkins-plugin-cli \
--plugins \
bouncycastle-api \
instance-identity \
javax-activation-api \
javax-mail-api \
structs \
workflow-step-api \
scm-api \
workflow-api \
pipeline-milestone-step \
caffeine-api \
script-security \
workflow-support \
pipeline-build-step \
workflow-scm-step \
ionicons-api \
cloudbees-folder \
variant \
workflow-cps \
pipeline-groovy-lib \
credentials \
plain-credentials \
trilead-api \
ssh-credentials \
credentials-binding \
pipeline-stage-step \
jaxb \
snakeyaml-api \
jackson2-api \
pipeline-model-api \
workflow-job \
pipeline-model-extensions \
jakarta-activation-api \
jakarta-mail-api \
display-url-api \
mailer \
branch-api \
workflow-multibranch \
durable-task \
workflow-durable-task-step \
pipeline-stage-tags-metadata \
mina-sshd-api-common \
mina-sshd-api-core \
apache-httpcomponents-client-4-api \
git-client \
pipeline-input-step \
workflow-basic-steps \
pipeline-model-definition \
workflow-aggregator \
generic-webhook-trigger \
git \
okhttp-api \
commons-lang3-api \
github-api \
token-macro \
github \
jjwt-api \
github-branch-source \
http_request \
commons-text-api \
pipeline-utility-steps \
file-operations \
pipeline-graph-analysis \
pipeline-rest-api \
pipeline-stage-view
RUN echo $'import jenkins.model.Jenkins \n\
import hudson.security.* \n\
import jenkins.security.s2m.AdminWhitelistRule \n\
def jenkinsUser = System.getenv("JENKINS_USER") ?: "admin" \n\
def jenkinsPass = System.getenv("JENKINS_PASS") ?: "admin" \n\
def instance = Jenkins.getInstance() \n\
def hudsonRealm = new HudsonPrivateSecurityRealm(false) \n\
hudsonRealm.createAccount(jenkinsUser, jenkinsPass) \n\
instance.setSecurityRealm(hudsonRealm) \n\
def strategy = new FullControlOnceLoggedInAuthorizationStrategy() \n\
strategy.setAllowAnonymousRead(false) \n\
instance.setAuthorizationStrategy(strategy) \n\
instance.save() \n\
' > /usr/share/jenkins/ref/init.groovy.d/init-security.groovy
USER jenkins

SAP Cloud Integration Credentials

GitHub Credentials
| Name | Value |
| CPI_HOST | {{url value from Service Key without https://}} e.g. xxxxxxxxxxx.it-cpi002.cfapps.ap10.hana.ondemand.com |
| CPI_OAUTH_CRED | CPIOAuthCredentials |
| CPI_OAUTH_HOST | {{tokenurl value from Service Key without https://}} e.g. xxxxxxxxxxx.authentication.ap10.hana.ondemand.com |
| GIT_BRANCH_NAME | master |
| GIT_CRED | GIT_Credentials |
| GIT_REPOSITORY_URL | github.com/Asutosh-Integration/Jenkins.git (Use your own forked repo) |





Integration flow for webhook trigger

Data Store Sender Channel Configuration
import com.sap.gateway.ip.core.customdev.util.Message;
import groovy.json.*
def Message processData(Message message) {
def json = new JsonSlurper().parseText(message.getBody(String));
message.setHeader('name',json.bundleName)
message.setHeader('Authorization','Bearer <Token Mentioned in Jenkins Webhook Trigger>')
return message;
}
HTTP Receiver Channel Configuration

explorer iFlow Deployed

Data Store Entry for the event

Messages got processed

Jenkins Pipeline got completed

Binary files got archived in GitHub

Code Analysis was done by cpilint
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
| User | Count |
|---|---|
| 33 | |
| 28 | |
| 24 | |
| 14 | |
| 13 | |
| 12 | |
| 11 | |
| 11 | |
| 9 | |
| 8 |