BET-34 AutoSynchContacts
diff --git a/src/main/java/org/eclipse/openk/elogbook/common/BackendConfig.java b/src/main/java/org/eclipse/openk/elogbook/common/BackendConfig.java
index 45c640a..78a05da 100644
--- a/src/main/java/org/eclipse/openk/elogbook/common/BackendConfig.java
+++ b/src/main/java/org/eclipse/openk/elogbook/common/BackendConfig.java
@@ -38,6 +38,11 @@
   private boolean enableEmailPresenceCheckJob;
   private boolean isOnlySendSameDayReminderEmail;
 
+  private String cronSyncContacts;
+  private boolean enableContactSyncJob;
+  private String contactServiceTechUser;
+  private String contactServiceTechUserPwd;
+
   private static BackendConfig instance;
 
   private BackendConfig() {
@@ -128,6 +133,22 @@
   public boolean isOnlySendSameDayReminderEmail() {
     return isOnlySendSameDayReminderEmail;
   }
+
+  public String getCronSyncContacts() {
+    return cronSyncContacts;
+  }
+
+  public boolean isEnableContactSyncJob() {
+    return enableContactSyncJob;
+  }
+
+  public String getContactServiceTechUser() {
+    return contactServiceTechUser;
+  }
+
+  public String getContactServiceTechUserPwd() {
+    return contactServiceTechUserPwd;
+  }
 }
 
 
diff --git a/src/main/java/org/eclipse/openk/elogbook/common/timer/ContactSyncJob.java b/src/main/java/org/eclipse/openk/elogbook/common/timer/ContactSyncJob.java
new file mode 100644
index 0000000..81a35e3
--- /dev/null
+++ b/src/main/java/org/eclipse/openk/elogbook/common/timer/ContactSyncJob.java
@@ -0,0 +1,27 @@
+package org.eclipse.openk.elogbook.common.timer;
+
+import org.apache.log4j.Logger;
+import org.eclipse.openk.elogbook.controller.BackendControllerUser;
+import org.eclipse.openk.elogbook.exceptions.BtbException;
+import org.quartz.Job;
+import org.quartz.JobExecutionContext;
+import org.quartz.JobExecutionException;
+
+public class ContactSyncJob implements Job {
+
+    private static final Logger LOGGER = Logger.getLogger(ContactSyncJob.class.getName());
+
+    @Override
+    public void execute(JobExecutionContext arg0) throws JobExecutionException {
+        LOGGER.debug("Quartz: ContactSyncJob called");
+
+        try {
+            new BackendControllerUser().synchronizeContacts();
+        } catch (BtbException btbException) {
+            LOGGER.error("Error in synchronizeContacts");
+        }
+        LOGGER.debug("Quartz: ContactSyncJob finished");
+
+    }
+
+}
diff --git a/src/main/java/org/eclipse/openk/elogbook/common/timer/InitContactSyncJobServlet.java b/src/main/java/org/eclipse/openk/elogbook/common/timer/InitContactSyncJobServlet.java
new file mode 100644
index 0000000..06f2ffd
--- /dev/null
+++ b/src/main/java/org/eclipse/openk/elogbook/common/timer/InitContactSyncJobServlet.java
@@ -0,0 +1,50 @@
+package org.eclipse.openk.elogbook.common.timer;
+
+import org.apache.log4j.Logger;
+import org.eclipse.openk.elogbook.common.BackendConfig;
+import org.quartz.CronScheduleBuilder;
+import org.quartz.JobBuilder;
+import org.quartz.JobDetail;
+import org.quartz.Scheduler;
+import org.quartz.SchedulerException;
+import org.quartz.Trigger;
+import org.quartz.TriggerBuilder;
+import org.quartz.impl.StdSchedulerFactory;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+
+public class InitContactSyncJobServlet extends HttpServlet {
+
+    private static final long serialVersionUID = -7802116179801471578L;
+
+    private static final Logger LOGGER = Logger.getLogger(InitContactSyncJobServlet.class.getName());
+
+    @Override
+    public void init() throws ServletException {
+        String cronExpression = BackendConfig.getInstance().getCronSyncContacts();
+        boolean isJobEnabled = BackendConfig.getInstance().isEnableContactSyncJob();
+        if (isJobEnabled) {
+            LOGGER.info("Init timer: 'Check contact sync job' triggered with cronExpression: " + cronExpression);
+
+            Trigger trigger = TriggerBuilder.newTrigger().withIdentity("CheckContactSyncTrigger", "CheckContactSyncTriggerGroup1")
+                    .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)).build();
+
+            Scheduler scheduler;
+
+            try {
+                JobDetail contactSyncJob = JobBuilder.newJob(ContactSyncJob.class)
+                        .withIdentity("contactSyncJob", "contactSyncJobGroup").build();
+                scheduler = new StdSchedulerFactory().getScheduler();
+                scheduler.start();
+                scheduler.scheduleJob(contactSyncJob, trigger);
+            } catch (SchedulerException e) {
+                LOGGER.error("SchedulerException caught", e);
+            }
+        } else {
+            LOGGER.info("'Check contact sync job' is disabled");
+        }
+
+    }
+
+}
diff --git a/src/main/java/org/eclipse/openk/elogbook/controller/BackendControllerUser.java b/src/main/java/org/eclipse/openk/elogbook/controller/BackendControllerUser.java
index 6e0a18d..38c675a 100644
--- a/src/main/java/org/eclipse/openk/elogbook/controller/BackendControllerUser.java
+++ b/src/main/java/org/eclipse/openk/elogbook/controller/BackendControllerUser.java
@@ -13,6 +13,7 @@
 package org.eclipse.openk.elogbook.controller;
 
 import org.apache.log4j.Logger;
+import org.eclipse.openk.elogbook.auth2.model.JwtToken;
 import org.eclipse.openk.elogbook.auth2.model.KeyCloakUser;
 import org.eclipse.openk.elogbook.auth2.util.JwtHelper;
 import org.eclipse.openk.elogbook.common.BackendConfig;
@@ -56,6 +57,17 @@
 		return userAuthenticationList;
 	}
 
+	public String portalLogin(String user, String pwd) throws BtbException {
+		LOGGER.debug("portalLogin is called");
+		String credentials = "{ \"userName\": \""+user+"\", \"password\": \""+pwd+"\"}";
+		RestServiceWrapper restServiceWrapper = new RestServiceWrapper(BackendConfig.getInstance().getPortalBaseURL(), false);
+		String url = "login";
+		JwtToken jwt = JsonGeneratorBase.getGson().fromJson( restServiceWrapper.performPostRequest(url, "", credentials), JwtToken.class );
+
+		return jwt.getAccessToken();
+
+	}
+
 	public UserAuthentication authenticate(String credentials) throws BtbException {
 		LOGGER.debug("authenticate() is called");
 
@@ -112,6 +124,20 @@
 
 	}
 
+
+	public void synchronizeContacts() throws BtbException {
+		LOGGER.debug("synchronizeContacts() is called");
+
+		try {
+			ContactBaseDataManager.getInstance().synchronizeContacts(portalLogin(
+					BackendConfig.getInstance().getContactServiceTechUser(),
+					BackendConfig.getInstance().getContactServiceTechUserPwd()
+			));
+		} finally {
+			LOGGER.debug("synchronizeContacts() is finished");
+		}
+
+	}
 	public String getUserSettings( String modUser ) throws BtbInternalServerError {
 		LOGGER.debug("getUserSettings() is called");
 		EntityManager emOrg = EntityHelper.getEMF().createEntityManager();
diff --git a/src/main/java/org/eclipse/openk/elogbook/controller/ContactBaseDataManager.java b/src/main/java/org/eclipse/openk/elogbook/controller/ContactBaseDataManager.java
index 8bc650d..ec45f29 100644
--- a/src/main/java/org/eclipse/openk/elogbook/controller/ContactBaseDataManager.java
+++ b/src/main/java/org/eclipse/openk/elogbook/controller/ContactBaseDataManager.java
@@ -12,18 +12,27 @@
 package org.eclipse.openk.elogbook.controller;
 
 
+import org.apache.log4j.Logger;
 import org.eclipse.openk.elogbook.common.BackendConfig;
 import org.eclipse.openk.elogbook.common.JsonGeneratorBase;
 import org.eclipse.openk.elogbook.communication.RestServiceWrapper;
 import org.eclipse.openk.elogbook.exceptions.BtbException;
+import org.eclipse.openk.elogbook.persistence.dao.AutoCloseEntityManager;
+import org.eclipse.openk.elogbook.persistence.dao.EntityHelper;
+import org.eclipse.openk.elogbook.persistence.dao.TblNotificationDao;
 import org.eclipse.openk.elogbook.viewmodel.contactbasedata.ContactTupel;
 import org.eclipse.openk.elogbook.viewmodel.contactbasedata.VwDetailedContact;
 import org.eclipse.openk.elogbook.viewmodel.contactbasedata.VwDetailedContactPage;
 
+import javax.persistence.EntityManager;
 import java.util.List;
+import java.util.Map;
+import java.util.UUID;
 import java.util.stream.Collectors;
 
 public class ContactBaseDataManager {
+    private static final Logger LOGGER = Logger.getLogger(ContactBaseDataManager.class.getName());
+
 
     private static final ContactBaseDataManager INSTANCE = new ContactBaseDataManager();
 
@@ -42,6 +51,25 @@
         return vwDetailedContactPage.getContent().stream().map(this::mapFromViewObj ).collect(Collectors.toList());
     }
 
+    public void synchronizeContacts(String token) {
+        LOGGER.debug("synchronizeContacts is called");
+        EntityManager emOrg = EntityHelper.getEMF().createEntityManager();
+        try (AutoCloseEntityManager em = new AutoCloseEntityManager(emOrg)) {
+            em.getTransaction().begin();
+            TblNotificationDao notifDao = new TblNotificationDao(em);
+            Map<UUID, String> uuid2NameMap = getUserContacts(token).stream().collect(Collectors.toMap(ContactTupel::getContactUuid, ContactTupel::getContactName));
+            notifDao.getDistinctResponsibilityForwardingUuid()
+                        .forEach( contactUuid -> notifDao.updateResponsibilityForwardingByContactUuid( contactUuid, uuid2NameMap.getOrDefault(contactUuid, "/gelöscht/")));
+            em.getTransaction().commit();
+
+        } catch (BtbException btbException) {
+            LOGGER.error("error in synchronizeContacts", btbException);
+        } finally {
+            LOGGER.debug("synchronizeContacts is finished");
+        }
+    }
+
+
     private ContactTupel mapFromViewObj( VwDetailedContact vwDetailedContact ) {
         String userName = vwDetailedContact.getName();
         if (userName != null) {
diff --git a/src/main/java/org/eclipse/openk/elogbook/controller/ControllerImplementations.java b/src/main/java/org/eclipse/openk/elogbook/controller/ControllerImplementations.java
index 4b33f32..b7ba24b 100644
--- a/src/main/java/org/eclipse/openk/elogbook/controller/ControllerImplementations.java
+++ b/src/main/java/org/eclipse/openk/elogbook/controller/ControllerImplementations.java
@@ -580,6 +580,24 @@
 		}
 	}
 
+
+	public static class SynchronizeContacts extends BackendInvokable {
+
+		private BackendControllerUser backendControllerUser;
+		private String token;
+
+		public SynchronizeContacts(BackendControllerUser backendControllerUser, String token) {
+			this.backendControllerUser = backendControllerUser;
+			this.token = token;
+		}
+
+		@Override
+		public Response invoke() throws BtbException {
+			backendControllerUser.synchronizeContacts();
+			return ResponseBuilderWrapper.INSTANCE
+					.buildOKResponse(JsonGeneratorBase.getGson().toJson(Globals.OK_STRING));
+		}
+	}
 	public static class GetTestMail extends BackendInvokable {
 
 		private BackendControllerUser backendControllerUser;
diff --git a/src/main/java/org/eclipse/openk/elogbook/persistence/dao/TblNotificationDao.java b/src/main/java/org/eclipse/openk/elogbook/persistence/dao/TblNotificationDao.java
index d8bf720..9685cbb 100644
--- a/src/main/java/org/eclipse/openk/elogbook/persistence/dao/TblNotificationDao.java
+++ b/src/main/java/org/eclipse/openk/elogbook/persistence/dao/TblNotificationDao.java
@@ -11,11 +11,6 @@
 */
 package org.eclipse.openk.elogbook.persistence.dao;
 
-import java.sql.Timestamp;
-import java.util.ArrayList;
-import java.util.List;
-import javax.persistence.EntityManager;
-import javax.persistence.Query;
 import org.eclipse.openk.elogbook.common.NotificationStatus;
 import org.eclipse.openk.elogbook.exceptions.BtbException;
 import org.eclipse.openk.elogbook.exceptions.BtbInternalServerError;
@@ -29,6 +24,13 @@
 import org.eclipse.openk.elogbook.viewmodel.NotificationSearchFilter;
 import org.eclipse.openk.elogbook.viewmodel.ReminderSearchFilter;
 
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
 public class TblNotificationDao extends GenericDaoJpa<TblNotification, Integer> {
 	private static final String VIEW_ACTIVE_NOTIFICATION = EntityHelper.instance().makeIdentifier("VIEW_ACTIVE_NOTIFICATION");
 	private static final String FK_REF_NOTIFICATION_STATUS = EntityHelper.instance().makeIdentifier("fk_ref_notification_status");
@@ -36,6 +38,7 @@
 	private static final String INCIDENT_ID = EntityHelper.instance().makeIdentifier("incident_id");
 	private static final String VERSION = EntityHelper.instance().makeIdentifier("version");
 	private static final String RESPONSIBILITY_FORWARDING = EntityHelper.instance().makeIdentifier("responsibility_forwarding");
+	private static final String RESPONSIBILITY_FORW_UUID = EntityHelper.instance().makeIdentifier("responsibility_forwarding_uuid");
 
 
 
@@ -189,6 +192,31 @@
 		}
 	}
 
+	public List<UUID> getDistinctResponsibilityForwardingUuid() throws BtbInternalServerError {
+		try {
+			String selectString = "select distinct "+RESPONSIBILITY_FORW_UUID+" from "+TBL_NOTIFICATION+" n where n.responsibility_forwarding_uuid is not null";
+			Query q = getEM().createNativeQuery(selectString);
+			return q.getResultList();
+
+		} catch (Exception t) {
+			LOGGER.error(t);
+			throw new BtbInternalServerError("Error loading distict responsibility forwarding uuid");
+		}
+	}
+
+	public void updateResponsibilityForwardingByContactUuid( UUID contactUuid, String contactName ) {
+		try {
+			String selectString = "update "+TBL_NOTIFICATION+" set "+RESPONSIBILITY_FORWARDING+" = ? where "+RESPONSIBILITY_FORW_UUID+" = ?";
+			Query q = getEM().createNativeQuery(selectString);
+			q.setParameter(2, contactUuid);
+			q.setParameter(1, contactName);
+			q.executeUpdate();
+
+		} catch (Exception t) {
+			LOGGER.error(t);
+		}
+	}
+
 
 	/**
 	 * Create and execute the query to get a collection of notifications.
diff --git a/src/main/java/org/eclipse/openk/elogbook/rest/BackendRestService.java b/src/main/java/org/eclipse/openk/elogbook/rest/BackendRestService.java
index 7f9b029..b0b694e 100644
--- a/src/main/java/org/eclipse/openk/elogbook/rest/BackendRestService.java
+++ b/src/main/java/org/eclipse/openk/elogbook/rest/BackendRestService.java
@@ -325,6 +325,15 @@
 				new ControllerImplementations.GetUserSuggestions(new BackendControllerUser(), token));
 	}
 
+
+	@GET
+	@Path("/synchronizeContacts")
+	@Produces("application/json")
+	public Response synchronizeContacts(@HeaderParam(value = Globals.KEYCLOAK_AUTH_TAG) String token) {
+		return invoke(token, SecureType.NORMAL,
+				new ControllerImplementations.SynchronizeContacts(new BackendControllerUser(), token));
+	}
+
 	@GET
 	@Path("/testmail")
 	@Produces("application/json")
diff --git a/src/main/resources/backendConfigDevLocal.json b/src/main/resources/backendConfigDevLocal.json
index feea975..f0de1af 100644
--- a/src/main/resources/backendConfigDevLocal.json
+++ b/src/main/resources/backendConfigDevLocal.json
@@ -18,5 +18,12 @@
   "isOnlySendSameDayReminderEmail": true,
 
   "cronEmailPresenceCheck": "30 0 16 * * ?",
-  "enableEmailPresenceCheckJob": true
+  "enableEmailPresenceCheckJob": true,
+
+  "_cronSyncContacts": "0 0 1 * * ?",
+  "cronSyncContacts": "* 0/1 * * * ?",
+  "enableContactSyncJob": true,
+  "contactServiceTechUser": "admin",
+  "contactServiceTechUserPwd": "admin"
+
 }
diff --git a/src/main/resources/backendConfigDevServer.json b/src/main/resources/backendConfigDevServer.json
index 423efd9..f945a7c 100644
--- a/src/main/resources/backendConfigDevServer.json
+++ b/src/main/resources/backendConfigDevServer.json
@@ -19,5 +19,11 @@
 
   "_cronEmailPresenceCheck": "30 0 16 * * ?",
   "cronEmailPresenceCheck": "* 0/1 * * * ?",
-  "enableEmailPresenceCheckJob": true
+  "enableEmailPresenceCheckJob": true,
+
+  "_cronSyncContacts": "0 0 1 * * ?",
+  "cronSyncContacts": "* 0/1 * * * ?",
+  "enableContactSyncJob": true,
+  "contactServiceTechUser": "admin",
+  "contactServiceTechUserPwd": "admin"
 }
diff --git a/src/main/resources/backendConfigProduction.json b/src/main/resources/backendConfigProduction.json
index da1c02d..dc6de41 100644
--- a/src/main/resources/backendConfigProduction.json
+++ b/src/main/resources/backendConfigProduction.json
@@ -16,5 +16,11 @@
 
   "_cronEmailPresenceCheck": "30 0 16 * * ?",
   "cronEmailPresenceCheck": "0/10 * * * * ?",
-  "enableEmailPresenceCheckJob": true
+  "enableEmailPresenceCheckJob": true,
+
+  "cronSyncContacts": "0 0 1 * * ?",
+  "enableContactSyncJob": true,
+  "contactServiceTechUser": "admin",
+  "contactServiceTechUserPwd": "admin"
+
 }
\ No newline at end of file
diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml
index d8a0ce9..99fd8b3 100644
--- a/src/main/webapp/WEB-INF/web.xml
+++ b/src/main/webapp/WEB-INF/web.xml
@@ -73,5 +73,9 @@
         <load-on-startup>3</load-on-startup>
     </servlet>
 
-
+    <servlet>
+        <servlet-name>InitContactSyncJobServlet</servlet-name>
+        <servlet-class>org.eclipse.openk.elogbook.common.timer.InitContactSyncJobServlet</servlet-class>
+        <load-on-startup>4</load-on-startup>
+    </servlet>
 </web-app>
diff --git a/src/test/java/org/eclipse/openk/elogbook/controller/ControllerImplementationsTest.java b/src/test/java/org/eclipse/openk/elogbook/controller/ControllerImplementationsTest.java
index 57dfa37..5087479 100644
--- a/src/test/java/org/eclipse/openk/elogbook/controller/ControllerImplementationsTest.java
+++ b/src/test/java/org/eclipse/openk/elogbook/controller/ControllerImplementationsTest.java
@@ -369,7 +369,7 @@
     public void testGetAssignedUserSuggestions() throws BtbException {
         List<String> assignedUserSuggestionsList = new LinkedList<>();
 
-        ControllerImplementations.GetUserSuggestions controllerImpl = new ControllerImplementations.GetUserSuggestions(beMockUser, "fakeToken");
+        ControllerImplementations.SynchronizeContacts controllerImpl = new ControllerImplementations.SynchronizeContacts(beMockUser, "fakeToken");
         expect(beMockUser.getAssignedUserSuggestions()).andReturn(assignedUserSuggestionsList);
          PowerMock.replay(beMockUser);