Commit 9657e173 authored by Eduardo González Real's avatar Eduardo González Real
Browse files

add witdom-core-po-deployment

parent 61da6bfb
# The base image from which we are building
FROM tomcat:8-alpine
LABEL Description="This image starts the deployment of the protection orchestrator"
RUN mkdir /home/witdom-core-po-conf/ && mkdir /home/witdom-core-po-conf/lib/ && mkdir /usr/local/tomcat/webapps/witdom-core-po/ && mkdir /home/witdom-core-po-conf/protectionConfigurations/
ADD witdom-core-po.war /home/witdom-core-po-conf/
ADD resources/init.sh /home/witdom-core-po-conf/
ADD resources/conf/protectionComponents.properties /home/witdom-core-po-conf/
ADD resources/conf/CustomWorkItemHandlers.conf /home/witdom-core-po-conf/
ADD resources/conf/protectionItemHandlers/ /home/witdom-core-po-conf/lib/
ADD resources/conf/protectionComponentsClients/ /home/witdom-core-po-conf/lib/
ADD resources/conf/protectionConfigurations/ /home/witdom-core-po-conf/protectionConfigurations/
ADD resources/conf/jsonResources/ /home/witdom-core-po-conf/jsonResources/
RUN unzip -qq /home/witdom-core-po-conf/witdom-core-po.war -d /usr/local/tomcat/webapps/witdom-core-po/
CMD sh /home/witdom-core-po-conf/init.sh
# For the image build: $ docker build -t witdom-core-po .
# For the container run: $ docker run -it -p 8080:8080 witdom-core-po
\ No newline at end of file
# The port used on the docker host machine to access the PO service
MAPPED_PORT=8081
IMAGE=po
CONTAINER=po
all: build run
build:
docker build -t $(IMAGE) .
run:
docker run -d -p $(MAPPED_PORT):8080 --name $(CONTAINER) $(IMAGE)
clean:
-docker stop $(CONTAINER)
-docker rm $(CONTAINER)
logs:
docker logs $(CONTAINER)
\ No newline at end of file
# **WITDOM** Protection Orchestrator
This document describes basic setup and usage of **Protection Orchestrator** services, running inside a single *Docker* container.
### **Description**
This component is in charge of parsing the **protection configuration** of an application and applying it by building the requests to the **protection components** deployed in the trusted domain of **WITDOM** and calling them for:
- **Protecting** the input data that a service in the **untrusted domain** will need.
- **Pisclosing** the results after a service in the **untrusted domain** has finished.
After the client application has prepared and segmented the **input data** and placed it in a **storage service** accessible by the **trusted-environments’ protection components**, a call to the **broker** initiates the **pre-processing** of the signals. The **broker** then calls the **PO** indicating the **protection configuration** for the application, which includes the needed components, the **pieces of data** (pointers) that are used by each component and the composition of the components in order to **orchestrate their execution**.
Once a service finishes, its outputs are still protected, so they must be **post-processed** in the **trusted domain** to recover the clear-text outcomes of the process that can be used by the client application. In this case, the **Broker** calls the **Protection Orchestrator** to perform this post-processing, and, again, by parsing the **protection configuration** of the application, the **PO** will build the needed requests to each of the **protection components** and call them on the **output data** of the service.
[witdom.eu](http://witdom.eu/ "About Witdom")
### **Prerequisites**
- Docker Engine (https://docs.docker.com/engine/installation)
- **REST Client** like *Curl*, *Postman* or *ARS* (for initial testing)
### **Instructions**
1. Navigate to the root directory of this project (it contains **Dockerfile**) and write this command:
```
$ docker build -t witdom-core-po .
```
2. Once you have built the *Docker* image, write **this command** to run a container:
```
$ docker run -it -p 8080:8080 witdom-core-po
```
3. Use this **path** to access the PO within the **container**:
```
http://localhost:8080/witdom-core-po/*
```
> **Note:** If you are running the container in *Windows*, use `http://192.168.99.100:8080/witdom-core-po/*` to access the PO within the container (through *Docker Virtual Machine*).
### **Resource Naming**
#### API Resources:
**Executes** a protection configuration
``` bash
POST /api/execute/{protectionconfigurationid}/{purpose}
Content-Type: application/json
Request Body: serviceCallParameters
```
> The `serviceCallParameters` depends on the protection configuration definition.
Sends a **signal event** to a process instance
``` bash
POST /api/processsignalevent/{processinstanceid}/{eventName}/{randomUUID}
Content-Type: application/json
Request Body: eventData
```
> The `eventData` depends on the protection configuration definition.
**Creates or updates** a protection configuration
``` bash
POST /api/protectionconfiguration/{protectionconfigurationid}/{purpose}
Content-Type: application/json
Request Body: BPMN2
```
> The `BPMN2` refers to the protection configuration **XML definition**
Gets a **list** of protection configurations
``` bash
GET /api/protectionconfigurations?{numberofresults}&{startresult}
```
> Params `numberofresults` and `startresult` are optional.
Gets the protection configuration definition **associated** with that id and purpose
``` bash
GET /api/protectionconfiguration/{protectionconfigurationid}/{purpose}
```
> The protection configuration returned is in **XML format**.
Gets the **nodes log** of a given process instance
``` bash
GET /api/log?{id}&{type}&{offset}&{count}&{asc}
```
> Params `type`, `offset`, `count` and `asc` are optional.
**Deletes** a protection configuration
``` bash
DELETE /api/protectionconfiguration/{protectionconfigurationid}/{purpose}
```
Gets the **execution status** of a given process instance
``` bash
GET /api/processstatus/{processinstanceid}
```
#### Demo Resources:
Protection Orchestrator **index page**
``` bash
/demo/index
```
In this form page, you can upload and execute the protection configuration. You will have to upload the definition file, the protection configuration image and the service call parameters.
> If you want to execute and monitor a demo process, you can get the sample files from `witdom-core-po/resources/samples`. The signal event names are in the BPMN definition.
Protection Orchestrator **demo page**
``` bash
/demo/audit
```
In this page you will see the process running, **node by node**. The active elements will be shown within an orange rectangle and the completed elements will be shown in green. Also, there is a **console** where you will see the **execution log** and two input texts for the signal event params.
Gets protection configuration **process image**
``` bash
GET /demo/processimage/{imageName}
```
> **Note:** For a more detailed info about the Resource Naming please see the **Swagger** yaml file.
### **Integration**
For the integration tests, we have provided a Java file in which we show how to communicate with the Protection Orchestrator. The specifications are detailed below:
> **Code available [here](https://gitlab-witdom.xlab.si/WitdomWP5/witdom-core-po/blob/master/integration-tests/src/main/java/com/witdom/integration/test/po/RunClient.java)**
You can **execute the code** within your IDE. If you want to compile and run the JAR, use the following commands:
Go to the root directory of the project, where the pom.xml is, and compile:
``` bash
$ mvn clean compile assembly:single
```
Go to the JAR directory (target folder) and run it with:
``` bash
$ java -jar file.jar [IP] [PORT]
```
Once the JAR is running, you will see the log with the methods execution. The log will have this format:
``` bash
[POST/GET/DELETE]: [URL] | [RESPONSE_CODE]
GET: http://localhost:8080/witdom-core-po/api/protectionconfigurations | 200
POST: http://localhost:8080/witdom-core-po/api/execute/dummy/test | 200
...
```
The client tests the following:
- List protection configurations.
- Create dummy protection configuration (script task and signal event).
- Get the protection configuration definition.
- Execute dummy protection configuration.
- Get execution log to check if signal event is waiting.
- Send signal event to process instance.
- Delete dummy protection configuration.
- Read SSP integration BPMN from properties file.
- Create SSP integration configuration.
- Execute SSP integration configuration.
> **Note:** SSP integration XML definition and process image are available **[here](https://gitlab-witdom.xlab.si/WitdomWP5/witdom-core-po/tree/master/resources/samples)**.
\ No newline at end of file
*-inputs.yaml
.cloudify/
\ No newline at end of file
APPPLICATION=po
BLUEPRINT_FILE=po.yaml
BLUEPRINT_INPUTS_FILE=po-inputs.yaml
all: deploy
redeploy: undeploy deploy
deploy:
cfy blueprints upload -b $(APPPLICATION) -p $(BLUEPRINT_FILE)
cfy deployments create -d $(APPPLICATION) -b $(APPPLICATION) -i $(BLUEPRINT_INPUTS_FILE)
cfy executions start -w install -vv -d $(APPPLICATION)
undeploy:
cfy executions start -w uninstall -d $(APPPLICATION)
cfy deployments delete -d $(APPPLICATION)
cfy blueprints delete -b $(APPPLICATION)
outputs:
cfy deployments outputs -d $(APPPLICATION)
\ No newline at end of file
tosca_definitions_version: cloudify_dsl_1_3
imports:
- http://www.getcloudify.org/spec/cloudify/3.4/types.yaml
- http://www.getcloudify.org/spec/fabric-plugin/1.4.1/plugin.yaml
- http://dice-project.github.io/cloudify-openstack-plugin/1.4/plugin.yaml
- http://www.getcloudify.org/spec/docker-plugin/1.3.2/plugin.yaml
# Declaration of required inputs (to be read from another file at the time of deployment)
inputs:
# VM settings
vm_name:
description: Name of the VM instance to which we are connecting
vm_user:
description: User for connecting to agent VM's
vm_ip:
description: Floating IP of the VM on which we want to deploy
vm_sg:
description: Security group of the VM
# Docker settings
docker_repo:
description: URL of the Docker repository
docker_tag:
description: Tag of the image from the Docker repository
docker_container_name:
description: Name of the container to run
po_port:
description: Port where PO listens (inside the container)
po_mapped_port:
description: Port that is externally accessible
node_templates:
vm:
type: cloudify.openstack.nodes.Server
properties:
use_external_resource: true
resource_id: { get_input: vm_name }
agent_config:
install_method: remote
user: { get_input: vm_user }
relationships:
- target: floating_ip
type: cloudify.openstack.server_connected_to_floating_ip
- target: security_group
type: cloudify.openstack.server_connected_to_security_group
floating_ip:
type: cloudify.openstack.nodes.FloatingIP
properties:
use_external_resource: true # Uses existing Floating IP, already assigned to witdom tenant on OS
resource_id: { get_input: vm_ip }
security_group:
type: cloudify.openstack.nodes.SecurityGroup
properties:
use_external_resource: true
resource_id: { get_input: vm_sg }
po_container:
type: cloudify.docker.Container
properties:
name: { get_input: docker_container_name }
image:
repository: { get_input: docker_repo }
tag: { get_input: docker_tag }
interfaces:
cloudify.interfaces.lifecycle:
create:
implementation: docker.docker_plugin.tasks.create_container
inputs:
params:
ports:
- { get_input: po_port }
detach: true
stdin_open: true
start:
implementation: docker.docker_plugin.tasks.start
inputs:
params:
port_bindings:
8080: { get_input: po_port }
relationships:
- target: vm
type: cloudify.relationships.contained_in
outputs:
po:
description: "WITDOM-PO Cloudify deployment outputs"
value:
description: WITDOM Protection orchestrator component
host: { get_attribute: [floating_ip, floating_ip_address] }
port: { get_input: po_mapped_port }
image: { concat: [ { get_input: docker_repo }, ":", { get_input: docker_tag } ] }
name: protection_orchestrator
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src/main/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>
/target/
/.settings/.classpath/.project
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>integration-test-po</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/test/java=UTF-8
encoding/<project>=UTF-8
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.8
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.witdom</groupId>
<artifactId>integration-test-po</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>integration-test-po</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.witdom.integration.test.po.RunClient</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="Definition"
targetNamespace="http://www.jboss.org/drools"
typeLanguage="http://www.java.com/javaTypes"
expressionLanguage="http://www.mvel.org/2.0"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd"
xmlns:g="http://www.jboss.org/drools/flow/gpd"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
xmlns:tns="http://www.jboss.org/drools">
<itemDefinition id="_request" structureRef="String" />
<itemDefinition id="_operation" structureRef="String" />
<itemDefinition id="_data" structureRef="Object" />
<itemDefinition id="_randomUUID" structureRef="Object" />
<process processType="Private" isExecutable="true" id="e2ee-test" name="Sample Process" tns:packageName="defaultPackage" >
<!-- process variables -->
<property id="request" itemSubjectRef="_request"/>
<property id="operation" itemSubjectRef="_operation"/>
<property id="data" itemSubjectRef="_data"/>
<property id="randomUUID" itemSubjectRef="_randomUUID"/>
<!-- nodes -->
<startEvent id="_1" isInterrupting="true"/>
<exclusiveGateway id="_jbpm-unique-1" name="Gateway" gatewayDirection="Diverging" />
<task id="_jbpm-unique-2" name="End-to-end encryption" tns:taskName="EndToEndEncryption" >
<extensionElements>
<tns:onEntry-script scriptFormat="http://www.java.com/java">
<tns:script>kcontext.setVariable("operation", "protect");
kcontext.setVariable("data", "{'callbackURL':'http://192.168.99.100:8080/witdom-core-po/api/processsignalevent/#{processInstanceId}/E2EE/#{randomUUID}','location':{'host':'#{host}','port':'#{port}','containerName':'#{containerName}','objectName':'#{objectName}','dbCredentials':{'username':'#{username}','password':'#{password}'}}}");</tns:script>
</tns:onEntry-script>
</extensionElements>
<ioSpecification>
<dataInput id="_jbpm-unique-2_dataInput" name="data" />
<dataInput id="_jbpm-unique-2_operationInput" name="operation" />
<inputSet>
<dataInputRefs>_jbpm-unique-2_dataInput</dataInputRefs>
<dataInputRefs>_jbpm-unique-2_operationInput</dataInputRefs>
</inputSet>
<outputSet>
</outputSet>
</ioSpecification>
<dataInputAssociation>
<sourceRef>data</sourceRef>
<targetRef>_jbpm-unique-2_dataInput</targetRef>
</dataInputAssociation>
<dataInputAssociation>
<sourceRef>operation</sourceRef>
<targetRef>_jbpm-unique-2_operationInput</targetRef>
</dataInputAssociation>
</task>
<task id="_jbpm-unique-3" name="End-to-end encryption" tns:taskName="EndToEndEncryption" >
<extensionElements>
<tns:onEntry-script scriptFormat="http://www.java.com/java">
<tns:script>kcontext.setVariable("operation", "protect");
kcontext.setVariable("data", "{'callbackURL':'http://192.168.99.100:8080/witdom-core-po/api/processsignalevent/#{processInstanceId}/E2EE/#{randomUUID}','location':{'host':'#{host}','port':'#{port}','containerName':'#{containerName}','objectName':'#{objectName}','dbCredentials':{'username':'#{username}','password':'#{password}'}}}");</tns:script>
</tns:onEntry-script>
</extensionElements>
<ioSpecification>
<dataInput id="_jbpm-unique-3_dataInput" name="data" />
<dataInput id="_jbpm-unique-3_operationInput" name="operation" />
<inputSet>
<dataInputRefs>_jbpm-unique-3_dataInput</dataInputRefs>
<dataInputRefs>_jbpm-unique-3_operationInput</dataInputRefs>
</inputSet>
<outputSet>
</outputSet>
</ioSpecification>
<dataInputAssociation>
<sourceRef>data</sourceRef>
<targetRef>_jbpm-unique-3_dataInput</targetRef>
</dataInputAssociation>
<dataInputAssociation>
<sourceRef>operation</sourceRef>
<targetRef>_jbpm-unique-3_operationInput</targetRef>
</dataInputAssociation>
</task>
<intermediateCatchEvent id="_jbpm-unique-4" name="Signal" >
<signalEventDefinition signalRef="E2EE-success"/>
</intermediateCatchEvent>
<exclusiveGateway id="_jbpm-unique-5" name="Gateway" gatewayDirection="Converging" />
<endEvent id="_jbpm-unique-6" name="End" >
<terminateEventDefinition />
</endEvent>
<task id="_jbpm-unique-0" name="End-to-end encryption" tns:taskName="EndToEndEncryption" >
<extensionElements>
<tns:onEntry-script scriptFormat="http://www.java.com/java">
<tns:script>kcontext.setVariable("operation", "opensession");
kcontext.setVariable("data", "{'passphrase':'test'}");</tns:script>
</tns:onEntry-script>
</extensionElements>
<ioSpecification>
<dataInput id="_jbpm-unique-0_dataInput" name="data" />
<dataInput id="_jbpm-unique-0_operationInput" name="operation" />
<inputSet>
<dataInputRefs>_jbpm-unique-0_dataInput</dataInputRefs>
<dataInputRefs>_jbpm-unique-0_operationInput</dataInputRefs>
</inputSet>
<outputSet>
</outputSet>
</ioSpecification>
<dataInputAssociation>
<sourceRef>data</sourceRef>
<targetRef>_jbpm-unique-0_dataInput</targetRef>
</dataInputAssociation>
<dataInputAssociation>
<sourceRef>operation</sourceRef>
<targetRef>_jbpm-unique-0_operationInput</targetRef>
</dataInputAssociation>
</task>
<!-- connections -->
<sequenceFlow id="_jbpm-unique-0-_jbpm-unique-1" sourceRef="_jbpm-unique-0" targetRef="_jbpm-unique-1" />
<sequenceFlow id="_jbpm-unique-1-_jbpm-unique-2" sourceRef="_jbpm-unique-1" targetRef="_jbpm-unique-2" name="async" tns:priority="1" >
<conditionExpression xsi:type="tFormalExpression" language="http://www.java.com/java" >if(kcontext.getVariable("request").equals("async")){return true;}return false;</conditionExpression>
</sequenceFlow>
<sequenceFlow id="_jbpm-unique-1-_jbpm-unique-3" sourceRef="_jbpm-unique-1" targetRef="_jbpm-unique-3" name="sync" tns:priority="1" >
<conditionExpression xsi:type="tFormalExpression" language="http://www.java.com/java" >if(kcontext.getVariable("request").equals("sync")){return true;}return false;</conditionExpression>