Merge branch 'DEVELOP_BE' of ssh://172.18.22.160:29418/oK/PlannedGridMeasures/mics-backend into DEVELOP_BE
diff --git a/devlocal.yml b/devlocal.yml
index 66c4421..2d04435 100644
--- a/devlocal.yml
+++ b/devlocal.yml
@@ -8,7 +8,8 @@
   port: 5672
   user: admin
   password: admin
-  exchangeName: opkon-pgm-exchange
+  exchangeName: openk-pgm-exchange
+  autoSetup: true
 
 dbConn:
   driver: org.postgresql.Driver
diff --git a/devserver.yml b/devserver.yml
index 3318e14..8646ad5 100644
--- a/devserver.yml
+++ b/devserver.yml
@@ -8,7 +8,8 @@
   port: 5672
   user: admin
   password: admin
-  exchangeName: opkon-pgm-exchange
+  exchangeName: openk-pgm-exchange
+  autoSetup: true
 
 dbConn:
   driver: org.postgresql.Driver
diff --git a/prodserver.yml b/prodserver.yml
index 5ba8f36..aade14a 100644
--- a/prodserver.yml
+++ b/prodserver.yml
@@ -8,7 +8,8 @@
   port: 5672
   user: admin
   password: admin
-  exchangeName: opkon-pgm-exchange
+  exchangeName: openk-pgm-exchange
+  autoSetup: true
 
 dbConn:
   driver: org.postgresql.Driver
diff --git a/qserver.yml b/qserver.yml
index 757b5df..5c72bf1 100644
--- a/qserver.yml
+++ b/qserver.yml
@@ -8,7 +8,8 @@
   port: 5672
   user: admin
   password: admin
-  exchangeName: opkon-pgm-exchange
+  exchangeName: openk-pgm-exchange
+  autoSetup: true
 
 dbConn:
   driver: org.postgresql.Driver
diff --git a/roleAccessConfiguration/role-access-definition.json b/roleAccessConfiguration/role-access-definition.json
index 3b51740..db00bac 100644
--- a/roleAccessConfiguration/role-access-definition.json
+++ b/roleAccessConfiguration/role-access-definition.json
@@ -136,6 +136,10 @@
                 "stepAffectedResources",
                 "stepSwitchingObject",
                 "stepTargetState",
+                "stepPresentState",
+                "stepPresentTime",
+                "stepType",
+                "stepOperator",
                 "useResourceBtn",
                 "addStepBtn",
                 "createInvertedStep",
@@ -202,6 +206,10 @@
                 "stepAffectedResources",
                 "stepSwitchingObject",
                 "stepTargetState",
+                "stepPresentState",
+                "stepPresentTime",
+                "stepType",
+                "stepOperator",
                 "useResourceBtn",
                 "addStepBtn",
                 "createInvertedStep",
@@ -269,6 +277,10 @@
                 "stepAffectedResources",
                 "stepSwitchingObject",
                 "stepTargetState",
+                "stepPresentState",
+                "stepPresentTime",
+                "stepType",
+                "stepOperator",
                 "useResourceBtn",
                 "addStepBtn",
                 "createInvertedStep",
@@ -334,6 +346,10 @@
                 "stepAffectedResources",
                 "stepSwitchingObject",
                 "stepTargetState",
+                "stepPresentState",
+                "stepPresentTime",
+                "stepType",
+                "stepOperator",
                 "useResourceBtn",
                 "addStepBtn",
                 "createInvertedStep",
@@ -398,6 +414,10 @@
                 "stepAffectedResources",
                 "stepSwitchingObject",
                 "stepTargetState",
+                "stepPresentState",
+                "stepPresentTime",
+                "stepType",
+                "stepOperator",
                 "useResourceBtn",
                 "addStepBtn",
                 "createInvertedStep",
@@ -462,6 +482,10 @@
                 "stepAffectedResources",
                 "stepSwitchingObject",
                 "stepTargetState",
+                "stepPresentState",
+                "stepPresentTime",
+                "stepType",
+                "stepOperator",
                 "useResourceBtn",
                 "addStepBtn",
                 "createInvertedStep",
@@ -525,6 +549,10 @@
                 "stepAffectedResources",
                 "stepSwitchingObject",
                 "stepTargetState",
+                "stepPresentState",
+                "stepPresentTime",
+                "stepType",
+                "stepOperator",
                 "useResourceBtn",
                 "addStepBtn",
                 "createInvertedStep",
@@ -588,6 +616,10 @@
                 "stepAffectedResources",
                 "stepSwitchingObject",
                 "stepTargetState",
+                "stepPresentState",
+                "stepPresentTime",
+                "stepType",
+                "stepOperator",
                 "useResourceBtn",
                 "addStepBtn",
                 "createInvertedStep",
@@ -647,6 +679,10 @@
                 "stepAffectedResources",
                 "stepSwitchingObject",
                 "stepTargetState",
+                "stepPresentState",
+                "stepPresentTime",
+                "stepType",
+                "stepOperator",
                 "useResourceBtn",
                 "addStepBtn",
                 "createInvertedStep",
@@ -708,6 +744,10 @@
                 "stepAffectedResources",
                 "stepSwitchingObject",
                 "stepTargetState",
+                "stepPresentState",
+                "stepPresentTime",
+                "stepType",
+                "stepOperator",
                 "useResourceBtn",
                 "addStepBtn",
                 "createInvertedStep",
@@ -769,6 +809,10 @@
                 "stepAffectedResources",
                 "stepSwitchingObject",
                 "stepTargetState",
+                "stepPresentState",
+                "stepPresentTime",
+                "stepType",
+                "stepOperator",
                 "useResourceBtn",
                 "addStepBtn",
                 "createInvertedStep",
diff --git a/src/main/asciidoc/architectureDocumentation/architectureDocumentation.adoc b/src/main/asciidoc/architectureDocumentation/architectureDocumentation.adoc
index 55af5d4..0068e20 100644
--- a/src/main/asciidoc/architectureDocumentation/architectureDocumentation.adoc
+++ b/src/main/asciidoc/architectureDocumentation/architectureDocumentation.adoc
@@ -363,6 +363,30 @@
 </dependency>
 ----
 |Mail|CDDL GLP 2.0|Backend
+
+|com.icegreen.greenmail|1.5.7
+a|
+[source,xml]
+----
+<dependency>
+    <groupId>com.icegreen</groupId>
+    <artifactId>greenmail</artifactId>
+    <version>1.5.7</version>
+</dependency>
+----
+|Unit testing|Apache 2.0|Backend
+
+|com.rabbitmq.amqp-client|5.2.0
+a|
+[source,xml]
+----
+<dependency>
+    <groupId>com.rabbitmq</groupId>
+    <artifactId>amqp-client</artifactId>
+    <version>5.2.0</version>
+</dependency>
+----
+|Message Broker|Apache 2.0, GPL 2.0, MPL 1.1|Backend
 |=========================================================
 
 == System Scope and Context
@@ -844,7 +868,7 @@
 
 
 ==== E-Mail Configuration
-The E-Mail is been configured in the Backend tier. There are 3 steps for the E-Mail Configuration:
+The E-Mail is configured in the Backend tier. There are 3 steps for the E-Mail Configuration:
 
 . *SMTP Settings* are configured in the according yml-file found in the root folder of the microservice.
   (For Example:  'prodserver.yml' is located next to 'planned-grid-measures.jar')
@@ -918,6 +942,65 @@
 
 |===
 
+==== RabbitMQ Configuration
+
+. *Prerequisites:*
+
+RabbitMQ Server is already installed and running
+
+It's recommend to enable the 'Management Plugin' to be able to use the Web UI
+(http://www.rabbitmq.com/management.html)
+
+The initial user and password for the Web-UI is '"guest"' but you need to create
+a new user since the initial user can  only connect via 'localhost'.
+
+Create new user with admin rights.
+
+[start=2]
+. *RabbitMQ Configuration in the Backend tier*
+
+RabbitMQ is configured in the according yml-file found in the root folder of the microservice.
+(For Example: prodserver.yml is located next to planned-grid-measures.jar)
+
+[source, yml]
+{
+  ...
+  rabbitmqConfiguration:
+    host: 172.18.22.160
+    port: 5672
+    user: admin
+    password: admin
+    exchangeName: openk-pgm-exchange
+    autoSetup: true
+  ...
+}
+
+- 'host' : Host adress of RabbitMQ Server
+- 'port' : Port of RabbitMQ Server (Default: 5672)
+- 'user' : Username you create in Step 1 (Prerequisites)
+- 'password' : Password belonging to user you create in Step 1 (Prerequisites)
+- 'exchangeName' : The name of the 'Exchange' (https://www.rabbitmq.com/tutorials/tutorial-three-python.html)
+- 'autoSetup' : If set to 'true' the Autosetup will fire once on application start.
+
+Autosetup means the Planned Grid Measure Microservice will create the Exchange according to the name defined one line
+above. All needed Queues will be created and bind to the Exchange.
+
+The automatically create Queues and their belonging routing keys are:
+
+[source]
+Queuename: pgm-applied-queue    | Routing key:  applied
+Queuename: pgm-canceled-queue   | Routing key:  canceled
+Queuename: pgm-approved-queue   | Routing key:  approved
+Queuename: pgm-rejected-queue   | Routing key:  rejected
+Queuename: pgm-requested-queue  | Routing key:  requested
+Queuename: pgm-released-queue   | Routing key:  released
+Queuename: pgm-finished-queue   | Routing key:  finished
+Queuename: pgm-closed-queue     | Routing key:  closed
+
+If 'autosetup' is set to 'false' you have to create the exchange, queues and bindings manually.
+
+CAUTION: You still have to use the same routing keys above If 'autosetup' is set to 'false'
+(Example: 'applied' for the Applied-Queue).
 
 
 == Runtime View
diff --git a/src/main/java/org/eclipse/openk/PlannedGridMeasuresApplication.java b/src/main/java/org/eclipse/openk/PlannedGridMeasuresApplication.java
index edde80b..30c0f8b 100644
--- a/src/main/java/org/eclipse/openk/PlannedGridMeasuresApplication.java
+++ b/src/main/java/org/eclipse/openk/PlannedGridMeasuresApplication.java
@@ -20,6 +20,7 @@
 import org.eclipse.openk.common.util.ResourceLoaderBase;
 import org.eclipse.openk.core.controller.BackendConfig;
 import org.eclipse.openk.core.controller.InitMailAddressCacheJob;
+import org.eclipse.openk.core.controller.InitRabbitMqSetup;
 import org.eclipse.openk.db.dao.EntityHelper;
 import org.eclipse.openk.health.DBIsPresentHealthCheck;
 import org.eclipse.openk.health.MailConfigurationHealthCheck;
@@ -88,6 +89,9 @@
 
         InitMailAddressCacheJob initMailAddressCacheJob = new InitMailAddressCacheJob();
         initMailAddressCacheJob.init();
+
+        InitRabbitMqSetup initRabbitMqSetup = new InitRabbitMqSetup();
+        initRabbitMqSetup.init();
     }
 
     private BackendSettings getBackendSettings() {
diff --git a/src/main/java/org/eclipse/openk/PlannedGridMeasuresConfiguration.java b/src/main/java/org/eclipse/openk/PlannedGridMeasuresConfiguration.java
index 182a7f9..2532742 100644
--- a/src/main/java/org/eclipse/openk/PlannedGridMeasuresConfiguration.java
+++ b/src/main/java/org/eclipse/openk/PlannedGridMeasuresConfiguration.java
@@ -34,6 +34,9 @@
         @JsonProperty
         private String exchangeName;
 
+        @JsonProperty
+        private boolean autoSetup;
+
         public String getHost() {
             return host;
         }
@@ -73,6 +76,14 @@
         public void setExchangeName(String exchangeName) {
             this.exchangeName = exchangeName;
         }
+
+        public boolean isAutoSetup() {
+            return autoSetup;
+        }
+
+        public void setAutoSetup(boolean autoSetup) {
+            this.autoSetup = autoSetup;
+        }
     }
 
     public static class EmailConfiguration {
diff --git a/src/main/java/org/eclipse/openk/common/Globals.java b/src/main/java/org/eclipse/openk/common/Globals.java
index b689f9d..ffe4e0e 100644
--- a/src/main/java/org/eclipse/openk/common/Globals.java
+++ b/src/main/java/org/eclipse/openk/common/Globals.java
@@ -11,6 +11,9 @@
 */
 package org.eclipse.openk.common;
 
+import java.util.Arrays;
+import java.util.List;
+
 public final class Globals {
 
     public static final String HEADER_JSON_UTF8 = "application/json; charset=utf-8";
@@ -24,5 +27,10 @@
 
     public static final String DATE_ZONE_ID_EUROPE = "Europe/Berlin";
 
+    //Sonar complaining about RABBIT_MQ_QUEUE_NAME_LIST beeing muteable althoug Arrays.asList returns a immutable List = False positve
+    public static final List<String> RABBIT_MQ_QUEUE_NAME_LIST = Arrays.asList("pgm-applied-queue", "pgm-canceled-queue", //NOSONAR
+        "pgm-approved-queue", "pgm-rejected-queue", "pgm-requested-queue", "pgm-released-queue",
+        "pgm-finished-queue", "pgm-closed-queue");
+
     private Globals() {}
 }
diff --git a/src/main/java/org/eclipse/openk/core/bpmn/gridmeasure/tasks/util/GridMeasureStorageHelper.java b/src/main/java/org/eclipse/openk/core/bpmn/gridmeasure/tasks/util/GridMeasureStorageHelper.java
index a15b7b0..5482fcb 100644
--- a/src/main/java/org/eclipse/openk/core/bpmn/gridmeasure/tasks/util/GridMeasureStorageHelper.java
+++ b/src/main/java/org/eclipse/openk/core/bpmn/gridmeasure/tasks/util/GridMeasureStorageHelper.java
@@ -79,10 +79,8 @@
 
             if (listSg != null && !listSg.isEmpty()) {
                 sortSingleGridMeasuresByDate(vmGm);
-            }
-            if(!listSg.isEmpty()) {
-
                 processExistingSingleGridMeasureList(model, changedGM.getId(), em, listSg, sgmDao, newSingleGms);
+
             }
             else{
                 //Anlegen einer Leermassnahme
diff --git a/src/main/java/org/eclipse/openk/core/controller/InitRabbitMqSetup.java b/src/main/java/org/eclipse/openk/core/controller/InitRabbitMqSetup.java
new file mode 100644
index 0000000..a1235aa
--- /dev/null
+++ b/src/main/java/org/eclipse/openk/core/controller/InitRabbitMqSetup.java
@@ -0,0 +1,74 @@
+/*
+ * *****************************************************************************
+ *  Copyright © 2018 PTA GmbH.
+ *  All rights reserved. This program and the accompanying materials
+ *  are made available under the terms of the Eclipse Public License v1.0
+ *  which accompanies this distribution, and is available at
+ *
+ *      http://www.eclipse.org/legal/epl-v10.html
+ *
+ * *****************************************************************************
+ */
+
+package org.eclipse.openk.core.controller;
+
+import com.rabbitmq.client.BuiltinExchangeType;
+import com.rabbitmq.client.Channel;
+import com.rabbitmq.client.Connection;
+import com.rabbitmq.client.ConnectionFactory;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.TimeoutException;
+import org.apache.log4j.Logger;
+import org.eclipse.openk.PlannedGridMeasuresConfiguration.RabbitmqConfiguration;
+import org.eclipse.openk.common.Globals;
+
+public class InitRabbitMqSetup {
+
+    private static final Logger LOGGER = Logger.getLogger(GridMeasureBackendController.class);
+
+    public void init()  {
+        LOGGER.debug("InitRabbitMqSetup called");
+        RabbitmqConfiguration rabbitmqConfiguration = BackendConfig.getInstance().getRabbitmqConfiguration();
+        if (!rabbitmqConfiguration.isAutoSetup()) {
+            LOGGER.debug("InitRabbitMqSetup canceled > Autosetup is off");
+            return;
+        }
+        ConnectionFactory factory = createRabbitFactory(rabbitmqConfiguration);
+        try (Connection connection = factory.newConnection();
+            Channel channel = connection.createChannel()) {
+
+            // durable = true
+            channel.exchangeDeclare(rabbitmqConfiguration.getExchangeName(), BuiltinExchangeType.DIRECT, true);
+
+            Map<String, Object> args = new HashMap<>();
+            args.put("x-queue-mode", "lazy");
+
+            for (String queueName : Globals.RABBIT_MQ_QUEUE_NAME_LIST) {
+                channel.queueDeclare(queueName, true, false, false, args);
+                String routingKey = queueName.split("-")[1];
+                channel.queueBind(queueName, rabbitmqConfiguration.getExchangeName(), routingKey);
+            }
+
+        } catch (TimeoutException | IOException e) {
+            LOGGER.error("Error in InitRabbitMqSetup", e);
+        }
+    }
+
+
+    private static ConnectionFactory createRabbitFactory(RabbitmqConfiguration rabbitmqConfiguration) {
+        ConnectionFactory factory = new ConnectionFactory();
+        factory.setHost(rabbitmqConfiguration.getHost());
+        factory.setPassword(rabbitmqConfiguration.getPassword());
+        factory.setUsername(rabbitmqConfiguration.getUser());
+        factory.setPort(Integer.parseInt(rabbitmqConfiguration.getPort()));
+        return factory;
+    }
+
+
+}
diff --git a/src/test/java/org/eclipse/openk/TestUtils/TestHelper.java b/src/test/java/org/eclipse/openk/TestUtils/TestHelper.java
index bda3393..6cec61f 100644
--- a/src/test/java/org/eclipse/openk/TestUtils/TestHelper.java
+++ b/src/test/java/org/eclipse/openk/TestUtils/TestHelper.java
@@ -31,7 +31,7 @@
     RabbitmqConfiguration rabbitmqConfiguration = new RabbitmqConfiguration();
     rabbitmqConfiguration.setUser("admin");
     rabbitmqConfiguration.setPassword("admin");
-    rabbitmqConfiguration.setExchangeName("opkon-pgm-exchange");
+    rabbitmqConfiguration.setExchangeName("openk-pgm-exchange");
     rabbitmqConfiguration.setHost("MockHost");
     rabbitmqConfiguration.setPort("5672");