diff --git a/.github/workflows/sync-and-deploy.yml b/.github/workflows/sync-and-deploy.yml
new file mode 100644
index 0000000..134a7bf
--- /dev/null
+++ b/.github/workflows/sync-and-deploy.yml
@@ -0,0 +1,57 @@
+# https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
+name: sync-and-deploy
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - devtober-demo
+
+jobs:
+# Unit test
+ unit_test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-java@v4
+ with:
+ java-version: '8'
+ distribution: 'temurin'
+ - name: 'Local unit test with Maven'
+ run: mvn clean test
+
+# Sync designtime artifact to tenant
+ sync:
+ runs-on: ubuntu-latest
+ needs: unit_test
+ container:
+ image: engswee/flashpipe:latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: 'Update/Upload Groovy XML Transformation to design time'
+ uses: engswee/flashpipe-action/sync@v1
+ with:
+ tmn-host: equaliseit.it-cpi023.cfapps.eu20-001.hana.ondemand.com
+ oauth-host: equaliseit.authentication.eu20.hana.ondemand.com
+ oauth-clientid: ${{ secrets.DEV_CLIENT_ID }}
+ oauth-clientsecret: ${{ secrets.DEV_CLIENT_SECRET }}
+ target: tenant
+ package-id: FlashPipeDemo
+
+ # Deploy to runtime
+ deploy:
+ runs-on: ubuntu-latest
+ needs: sync
+ container:
+ image: engswee/flashpipe:latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: 'Deploy Groovy XML Transformation to runtime'
+ uses: engswee/flashpipe-action/deploy@v1
+ with:
+ tmn-host: equaliseit.it-cpi023.cfapps.eu20-001.hana.ondemand.com
+ oauth-host: equaliseit.authentication.eu20.hana.ondemand.com
+ oauth-clientid: ${{ secrets.DEV_CLIENT_ID }}
+ oauth-clientsecret: ${{ secrets.DEV_CLIENT_SECRET }}
+ artifact-ids: GroovyXMLTransformation
diff --git a/Demo_Flow/META-INF/MANIFEST.MF b/Demo_Flow/META-INF/MANIFEST.MF
index e907819..a7abfbb 100644
--- a/Demo_Flow/META-INF/MANIFEST.MF
+++ b/Demo_Flow/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Demo Flow
Bundle-SymbolicName: Demo_Flow; singleton:=true
-Bundle-Version: 0.1.0
+Bundle-Version: 0.1.1
SAP-BundleType: IntegrationFlow
SAP-NodeType: IFLMAP
SAP-RuntimeProfile: iflmap
diff --git a/Demo_Flow/pom.xml b/Demo_Flow/pom.xml
new file mode 100644
index 0000000..fe590a8
--- /dev/null
+++ b/Demo_Flow/pom.xml
@@ -0,0 +1,14 @@
+
+ 4.0.0
+
+
+ com.equaliseit
+ flashpipe-demo
+ 1.0.0
+
+
+ Demo_Flow
+ 1.0.0
+
+
\ No newline at end of file
diff --git a/Demo_Flow/src/main/resources/scenarioflows/integrationflow/Demo Flow.iflw b/Demo_Flow/src/main/resources/scenarioflows/integrationflow/Demo Flow.iflw
index 13a344f..5f80111 100644
--- a/Demo_Flow/src/main/resources/scenarioflows/integrationflow/Demo Flow.iflw
+++ b/Demo_Flow/src/main/resources/scenarioflows/integrationflow/Demo Flow.iflw
@@ -217,7 +217,7 @@
script
- script1.groovy
+ XMLTransformation.groovy
SequenceFlow_3
diff --git a/Demo_Flow/src/main/resources/script/XMLTransformation.groovy b/Demo_Flow/src/main/resources/script/XMLTransformation.groovy
new file mode 100644
index 0000000..c7f1762
--- /dev/null
+++ b/Demo_Flow/src/main/resources/script/XMLTransformation.groovy
@@ -0,0 +1,37 @@
+import com.sap.gateway.ip.core.customdev.util.Message
+import com.sap.it.api.ITApiFactory
+import com.sap.it.api.mapping.ValueMappingApi
+import groovy.xml.MarkupBuilder
+
+import java.text.SimpleDateFormat
+
+def Message processData(Message message) {
+ Reader reader = message.getBody(Reader)
+ def Order = new XmlSlurper().parse(reader)
+ Writer writer = new StringWriter()
+ def builder = new MarkupBuilder(writer)
+
+ def sourceDocType = message.getProperty('DocType')
+ ValueMappingApi api = ITApiFactory.getService(ValueMappingApi, null)
+
+ def items = Order.Item.findAll { it.Valid.text() == 'true' }
+ builder.PurchaseOrder {
+ 'Header' {
+ 'ID' Order.Header.OrderNumber
+ 'DocumentDate' new SimpleDateFormat('yyyy-MM-dd').format(new SimpleDateFormat('yyyyMMdd').parse(Order.Header.Date.text()))
+ if (!items.size())
+ 'DocumentType' api.getMappedValue('S4', 'DocType', sourceDocType, 'ACME', 'DocumentType')
+ }
+
+ items.each { item ->
+ 'Item' {
+ 'ItemNumber' item.ItemNumber.text().padLeft(3, '0')
+ 'ProductCode' item.MaterialNumber
+ 'Quantity' item.Quantity
+ }
+ }
+ }
+
+ message.setBody(writer.toString())
+ return message
+}
\ No newline at end of file
diff --git a/Demo_Flow/src/main/resources/script/script1.groovy b/Demo_Flow/src/main/resources/script/script1.groovy
deleted file mode 100644
index 42c0f9e..0000000
--- a/Demo_Flow/src/main/resources/script/script1.groovy
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Refer the link below to learn more about the use cases of script.
-https://help.sap.com/viewer/368c481cd6954bdfa5d0435479fd4eaf/Cloud/en-GB/148851bf8192412cba1f9d2c17f4bd25.html
-
-If you want to know more about the SCRIPT APIs, refer the link below
-https://help.sap.com/doc/a56f52e1a58e4e2bac7f7adbf45b2e26/Cloud/en-GB/index.html */
-import com.sap.gateway.ip.core.customdev.util.Message;
-import java.util.HashMap;
-def Message processData(Message message) {
- //Body
- def body = message.getBody();
-/*To set the body, you can use the following method. Refer SCRIPT APIs document for more detail*/
- //message.setBody(body + " Body is modified");
- //Headers
- def headers = message.getHeaders();
- def value = headers.get("oldHeader");
- message.setHeader("oldHeader", value + " modified");
- message.setHeader("newHeader", "newHeader");
- //Properties
- def properties = message.getProperties();
- value = properties.get("oldProperty");
- message.setProperty("oldProperty", value + " modified");
- message.setProperty("newProperty", "newProperty");
- return message;
-}
\ No newline at end of file
diff --git a/Demo_Flow/src/test/groovy/XMLTransformationSpec.groovy b/Demo_Flow/src/test/groovy/XMLTransformationSpec.groovy
new file mode 100644
index 0000000..e3d94b4
--- /dev/null
+++ b/Demo_Flow/src/test/groovy/XMLTransformationSpec.groovy
@@ -0,0 +1,61 @@
+import com.sap.gateway.ip.core.customdev.util.Message
+import com.sap.it.api.mapping.ValueMappingApi
+import spock.lang.Shared
+import spock.lang.Specification
+
+class XMLTransformationSpec extends Specification {
+ @Shared
+ Script script
+ Message msg
+
+ def setupSpec() {
+ GroovyShell shell = new GroovyShell()
+ script = shell.parse(this.getClass().getResource('/script/XMLTransformation.groovy').toURI())
+ }
+
+ def setup() {
+ msg = new Message()
+ }
+
+ def 'Scenario 1 - Order has items'() {
+ given: 'the message body is initialized'
+ msg.setBody(this.getClass().getResource('input1.xml').newInputStream())
+
+ when: 'we execute the Groovy script'
+ script.processData(msg)
+
+ then: 'the output message body is as expected'
+ def root = new XmlSlurper().parse(msg.getBody(Reader))
+ verifyAll {
+ root.Header.ID.text() == 'ORD60001'
+ root.Header.DocumentDate.text() == '2019-02-18'
+ root.Header.DocumentType.text() == ''
+ root.Item.size() == 1
+ root.Item.ItemNumber.text() == '010'
+ root.Item.ProductCode.text() == 'MT70001'
+ root.Item.Quantity.text() == '57'
+ }
+ }
+
+ def 'Scenario 2 - Order does not have items'() {
+ given: 'the message body and property are initialized'
+ msg.setBody(this.getClass().getResource('input2.xml').newInputStream())
+ msg.setProperty('DocType', 'HDR')
+
+ // Set up value mapping entries
+ ValueMappingApi vmapi = ValueMappingApi.getInstance()
+ vmapi.addEntry('S4', 'DocType', 'HDR', 'ACME', 'DocumentType', 'ACME-HDR')
+
+ when: 'we execute the Groovy script'
+ script.processData(msg)
+
+ then: 'the output message body is as expected'
+ def root = new XmlSlurper().parse(msg.getBody(Reader))
+ verifyAll {
+ root.Header.ID.text() == 'ORD80002'
+ root.Header.DocumentDate.text() == '2020-02-18'
+ root.Header.DocumentType.text() == 'ACME-HDR'
+ root.Item.size() == 0
+ }
+ }
+}
\ No newline at end of file
diff --git a/Demo_Flow/src/test/resources/input1.xml b/Demo_Flow/src/test/resources/input1.xml
new file mode 100644
index 0000000..489e661
--- /dev/null
+++ b/Demo_Flow/src/test/resources/input1.xml
@@ -0,0 +1,18 @@
+
+
+ -
+ 10
+ MT70001
+ 57
+ true
+
+ -
+ 20
+ MT80001
+ 28
+ false
+
+
\ No newline at end of file
diff --git a/Demo_Flow/src/test/resources/input2.xml b/Demo_Flow/src/test/resources/input2.xml
new file mode 100644
index 0000000..f3e630e
--- /dev/null
+++ b/Demo_Flow/src/test/resources/input2.xml
@@ -0,0 +1,12 @@
+
+
+ -
+ 10
+ MT90001
+ 55
+ false
+
+
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..74da3d5
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,159 @@
+
+ 4.0.0
+
+ com.equaliseit
+ flashpipe-demo
+ 1.0.0
+ pom
+
+
+ UTF-8
+ 8
+ 2.4.21
+ 2.17.1
+ 1.3-groovy-2.4
+ 2.24.2
+
+
+
+ Demo_Flow
+
+
+
+
+
+ org.codehaus.groovy
+ groovy-all
+ ${groovy.all.version}
+
+
+ org.spockframework
+ spock-core
+ ${spock.version}
+ test
+
+
+
+
+
+
+ org.codehaus.groovy
+ groovy-all
+
+
+ org.spockframework
+ spock-core
+
+
+ org.apache.camel
+ camel-core
+ ${camel.core.version}
+
+
+ org.apache.logging.log4j
+ log4j-api
+ ${log4j.version}
+
+
+ org.apache.logging.log4j
+ log4j-core
+ ${log4j.version}
+
+
+ org.apache.logging.log4j
+ log4j-slf4j-impl
+ ${log4j.version}
+
+
+ com.equaliseit
+ sap-cpi-mocks
+ 1.0.2
+
+
+
+
+
+
+
+
+
+
+ src/main/resources/script
+
+
+ maven-surefire-plugin
+
+ false
+
+ **/*Spec.java
+ **/*Test.java
+
+
+
+
+ org.codehaus.gmavenplus
+ gmavenplus-plugin
+ 1.9.0
+
+
+
+ addSources
+ addTestSources
+ compile
+ compileTests
+
+
+
+
+
+
+
+
+ maven-dependency-plugin
+ 3.1.2
+
+
+ maven-clean-plugin
+ 3.1.0
+
+
+
+ maven-resources-plugin
+ 3.1.0
+
+
+ maven-compiler-plugin
+ 3.8.1
+
+ ${jdk.version}
+
+
+
+ maven-surefire-plugin
+ 2.22.2
+
+
+ maven-jar-plugin
+ 3.2.0
+
+
+ maven-install-plugin
+ 2.5.2
+
+
+ maven-deploy-plugin
+ 2.8.2
+
+
+
+
+
+
+ gitlab-maven
+ https://gitlab.com/api/v4/groups/12926885/-/packages/maven
+
+
+
\ No newline at end of file