added Health-Interface for microservice diag-tool
diff --git a/pom.xml b/pom.xml
index 3467b1a..3151c18 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
 
     <groupId>openk.pta.de</groupId>
     <artifactId>portal</artifactId>
-    <version>1.0.1</version>
+    <version>1.0.2</version>
     <packaging>war</packaging>
 
     <properties>
diff --git a/src/main/java/org/eclipse/openk/portal/auth2/util/JwtHelper.java b/src/main/java/org/eclipse/openk/portal/auth2/util/JwtHelper.java
index be182d5..f3a550a 100644
--- a/src/main/java/org/eclipse/openk/portal/auth2/util/JwtHelper.java
+++ b/src/main/java/org/eclipse/openk/portal/auth2/util/JwtHelper.java
@@ -45,11 +45,18 @@
 
   public static JwtToken login(String user, String password) throws PortalInternalServerError {
     String token = sendPost(BackendConfig.getInstance().getAuthServerUrl() + "auth/realms/" +
-            BackendConfig.getInstance().getKeycloakRealm() + "/protocol/openid-connect/token",
-        "username=" + user + "&password=" + password + "&client_id=" + BackendConfig.getInstance().getKeycloakClient() + "&grant_type=password");
+                    BackendConfig.getInstance().getKeycloakRealm() + "/protocol/openid-connect/token",
+            "username=" + user + "&password=" + password + "&client_id="
+                    + BackendConfig.getInstance().getKeycloakClient() + "&grant_type=password");
     return getJwtTokenFromJson(token);
   }
 
+  public static boolean serviceAvailable() throws PortalInternalServerError {
+    String jsonRet = sendGet(BackendConfig.getInstance().getAuthServerUrl() + "auth/realms/" +
+                    BackendConfig.getInstance().getKeycloakRealm(), "", null);
+    return jsonRet.contains("realm") && jsonRet.contains(BackendConfig.getInstance().getKeycloakRealm());
+  }
+
   public static List<KeyCloakUser> getUsers(JwtToken jwtToken, int maxUsers) throws PortalInternalServerError {
     String users = sendGet(BackendConfig.getInstance().getAuthServerUrl() + "auth/admin/realms/" + BackendConfig.getInstance().getKeycloakRealm() + "/users?max="+maxUsers,
         MediaType.APPLICATION_JSON, jwtToken.getAccessToken());
diff --git a/src/main/java/org/eclipse/openk/portal/health/base/HealthCheck.java b/src/main/java/org/eclipse/openk/portal/health/base/HealthCheck.java
new file mode 100644
index 0000000..08fc817
--- /dev/null
+++ b/src/main/java/org/eclipse/openk/portal/health/base/HealthCheck.java
@@ -0,0 +1,17 @@
+/*
+ ******************************************************************************
+ * Copyright © 2017-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.portal.health.base;
+
+public abstract class HealthCheck {
+
+    protected abstract Result check() throws Exception;
+}
diff --git a/src/main/java/org/eclipse/openk/portal/health/base/HealthChecker.java b/src/main/java/org/eclipse/openk/portal/health/base/HealthChecker.java
new file mode 100644
index 0000000..33d04f5
--- /dev/null
+++ b/src/main/java/org/eclipse/openk/portal/health/base/HealthChecker.java
@@ -0,0 +1,47 @@
+/*
+ ******************************************************************************
+ * Copyright © 2017-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.portal.health.base;
+
+import org.apache.log4j.Logger;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+public class HealthChecker {
+    private static final Logger logger = Logger.getLogger(HealthChecker.class);
+
+    private List<HealthCheck> registeredHealthChecks = new LinkedList<>();
+    private Map<HealthCheck, String> namingMap = new HashMap<>();
+
+    public void register( String title, HealthCheck hc ) {
+        namingMap.put(hc, title);
+        registeredHealthChecks.add(hc);
+    }
+
+    public List<NamedHealthCheckResult> performHealthChecks() {
+        List<NamedHealthCheckResult> hcList = new LinkedList<>();
+        for( HealthCheck hc : registeredHealthChecks) {
+            try {
+                hcList.add(new NamedHealthCheckResult(namingMap.get(hc), hc.check()));
+
+            } catch (Throwable t) {
+                logger.error("Error during healthcheck", t);
+                hcList.add(new NamedHealthCheckResult(namingMap.get(hc),
+                        Result.unhealthy("Exception during test: "+t+" -> See Log!")));
+            }
+        }
+        return hcList;
+    }
+
+}
diff --git a/src/main/java/org/eclipse/openk/portal/health/base/NamedHealthCheckResult.java b/src/main/java/org/eclipse/openk/portal/health/base/NamedHealthCheckResult.java
new file mode 100644
index 0000000..9ee581e
--- /dev/null
+++ b/src/main/java/org/eclipse/openk/portal/health/base/NamedHealthCheckResult.java
@@ -0,0 +1,53 @@
+/*
+ ******************************************************************************
+ * Copyright © 2017-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.portal.health.base;
+
+import com.google.gson.GsonBuilder;
+
+import java.util.List;
+
+public class NamedHealthCheckResult {
+    private String name;
+    private Result result;
+
+    public NamedHealthCheckResult( String name, Result result ) {
+        this.name = name;
+        this.result = result;
+    }
+
+    public String toJson() {
+        StringBuffer buffer = new StringBuffer();
+        buffer.append("\""+name+"\":");
+        buffer.append(new GsonBuilder().disableHtmlEscaping().create().toJson(result));
+        return buffer.toString();
+    }
+
+    public static String toJson(List<NamedHealthCheckResult> resultArray ) {
+        StringBuilder builder = new StringBuilder();
+        builder.append('{');
+        for( int i=0; i < resultArray.size(); i++ ) {
+            builder.append(resultArray.get(i).toJson());
+            if( i+1 < resultArray.size() ) {
+                builder.append(',');
+            }
+        }
+        return builder.append('}').toString();
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Result getResult() {
+        return result;
+    }
+}
diff --git a/src/main/java/org/eclipse/openk/portal/health/base/Result.java b/src/main/java/org/eclipse/openk/portal/health/base/Result.java
new file mode 100644
index 0000000..6ff7de7
--- /dev/null
+++ b/src/main/java/org/eclipse/openk/portal/health/base/Result.java
@@ -0,0 +1,41 @@
+/*
+ ******************************************************************************
+ * Copyright © 2017-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.portal.health.base;
+
+
+public class Result {
+    private boolean healthy;
+    private String message;
+
+    private Result() {}
+
+    public static Result healthy() {
+        Result res = new Result();
+        res.healthy = true;
+        return res;
+    }
+
+    public static Result unhealthy(String message) {
+        Result res = new Result();
+        res.healthy = false;
+        res.message = message;
+        return res;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public boolean isHealthy() {
+        return healthy;
+    }
+}
diff --git a/src/main/java/org/eclipse/openk/portal/health/impl/KeyCloakPresentHealthCheck.java b/src/main/java/org/eclipse/openk/portal/health/impl/KeyCloakPresentHealthCheck.java
new file mode 100644
index 0000000..1295f46
--- /dev/null
+++ b/src/main/java/org/eclipse/openk/portal/health/impl/KeyCloakPresentHealthCheck.java
@@ -0,0 +1,38 @@
+/*
+ ******************************************************************************
+ * Copyright © 2017-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.portal.health.impl;
+
+import org.eclipse.openk.portal.auth2.util.JwtHelper;
+import org.eclipse.openk.portal.common.BackendConfig;
+import org.eclipse.openk.portal.exceptions.PortalInternalServerError;
+import org.eclipse.openk.portal.health.base.HealthCheck;
+import org.eclipse.openk.portal.health.base.Result;
+
+public class KeyCloakPresentHealthCheck extends HealthCheck {
+    public KeyCloakPresentHealthCheck() {}
+
+    protected boolean checkit() throws PortalInternalServerError {
+        return JwtHelper.serviceAvailable();
+    }
+
+    @Override
+    protected Result check() throws Exception {
+        if( checkit() ) {
+            return Result.healthy();
+        }
+        else {
+            BackendConfig gc = BackendConfig.getInstance();
+            String msg = gc.getAuthServerUrl() + "/" + gc.getKeycloakRealm();
+            return Result.unhealthy("KeyCloak-Service not available: "+msg);
+        }
+    }
+}
diff --git a/src/main/java/org/eclipse/openk/portal/rest/BackendRestService.java b/src/main/java/org/eclipse/openk/portal/rest/BackendRestService.java
index 532349d..79ce8e8 100644
--- a/src/main/java/org/eclipse/openk/portal/rest/BackendRestService.java
+++ b/src/main/java/org/eclipse/openk/portal/rest/BackendRestService.java
@@ -11,7 +11,8 @@
 */
 package org.eclipse.openk.portal.rest;
 
-import javax.ws.rs.PathParam;
+import javax.ws.rs.*;
+
 import org.apache.log4j.Logger;
 import org.eclipse.openk.portal.auth2.model.JwtToken;
 import org.eclipse.openk.portal.common.Globals;
@@ -24,14 +25,11 @@
 import org.eclipse.openk.portal.exceptions.PortalException;
 import org.eclipse.openk.portal.exceptions.PortalExceptionMapper;
 import org.eclipse.openk.portal.exceptions.PortalUnauthorized;
+import org.eclipse.openk.portal.health.base.HealthChecker;
+import org.eclipse.openk.portal.health.base.NamedHealthCheckResult;
+import org.eclipse.openk.portal.health.impl.KeyCloakPresentHealthCheck;
 import org.eclipse.openk.portal.viewmodel.VersionInfo;
 
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.HeaderParam;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
@@ -137,6 +135,23 @@
         return invoke(accessToken, false, new ControllerImplementations.GetUsers());
     }
 
+    @GET
+    @Path("/healthcheck")
+    @Produces("application/json")
+    public Response getHealthCheck(@FormParam(value = "pretty") boolean yn) {
+        HealthChecker hc = new HealthChecker();
+        hc.register("Keycloak present", new KeyCloakPresentHealthCheck());
+
+        String returnJson = NamedHealthCheckResult.toJson(hc.performHealthChecks());
+
+        try {
+            return ResponseBuilderWrapper.INSTANCE.buildOKResponse(returnJson);
+        } catch (PortalException e) {
+            logger.error("unexpected error", e);
+            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
+        }
+    }
+
     private boolean isBackdoor( String sessionId ) {
         // backdoor is only available when the version(POM) contains "DEVELOP" or "SNAPSHOT"
         return DEVELOP_MODE && LET_ME_IN.equals(sessionId);
diff --git a/src/test/java/org/eclipse/openk/portal/health/base/HealthCheckerTest.java b/src/test/java/org/eclipse/openk/portal/health/base/HealthCheckerTest.java
new file mode 100644
index 0000000..87aed26
--- /dev/null
+++ b/src/test/java/org/eclipse/openk/portal/health/base/HealthCheckerTest.java
@@ -0,0 +1,93 @@
+/*
+ ******************************************************************************
+ * 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.portal.health.base;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+
+import static junit.framework.TestCase.assertTrue;
+import static org.junit.Assert.*;
+
+public class HealthCheckerTest {
+    public boolean hc1Called;
+    public boolean hc2Called;
+    public boolean hc3Called;
+
+    @Before
+    public void init() {
+        hc1Called = false;
+        hc2Called = false;
+        hc3Called = false;
+    }
+
+    @Test
+    public void test_ok() {
+        HealthCheck hc1 = new HealthCheck() {
+
+            @Override
+            protected Result check() throws Exception {
+                hc1Called = true;
+                return Result.healthy();
+            }
+        };
+
+        HealthCheck hc2 = new HealthCheck() {
+            @Override
+            protected Result check() throws Exception {
+                hc2Called = true;
+                return Result.unhealthy("because of...");
+            }
+        };
+
+        HealthChecker theChecker = new HealthChecker();
+        theChecker.register("firstTest", hc1 );
+        theChecker.register( "secondTest", hc2 );
+
+        List<NamedHealthCheckResult> retList = theChecker.performHealthChecks();
+
+        assertEquals( 2, retList.size() );
+        assertTrue( hc1Called );
+        assertTrue( hc2Called );
+        assertNull( retList.get(0).getResult().getMessage());
+        assertNotNull( retList.get(1).getResult().getMessage());
+        assertEquals( "firstTest", retList.get(0).getName());
+        assertEquals( "secondTest", retList.get(1).getName());
+        assertTrue( retList.get(0).getResult().isHealthy());
+        assertFalse( retList.get(1).getResult().isHealthy());
+    }
+
+    @Test
+    public void test_nok() {
+        HealthCheck hc1 = new HealthCheck() {
+
+            @Override
+            protected Result check() throws Exception {
+                hc3Called = true;
+                throw new Exception("Error in healthCheck");
+            }
+        };
+
+
+        HealthChecker theChecker = new HealthChecker();
+        theChecker.register("errorTest", hc1 );
+
+        List<NamedHealthCheckResult> retList = theChecker.performHealthChecks();
+
+        assertEquals( 1, retList.size() );
+        assertTrue( hc3Called );
+        assertNotNull( retList.get(0).getResult().getMessage());
+        assertFalse( retList.get(0).getResult().isHealthy());
+
+    }
+}
diff --git a/src/test/java/org/eclipse/openk/portal/health/base/NamedHealthCheckResultTest.java b/src/test/java/org/eclipse/openk/portal/health/base/NamedHealthCheckResultTest.java
new file mode 100644
index 0000000..0fdd4e7
--- /dev/null
+++ b/src/test/java/org/eclipse/openk/portal/health/base/NamedHealthCheckResultTest.java
@@ -0,0 +1,25 @@
+package org.eclipse.openk.portal.health.base;
+
+import org.junit.Test;
+
+import java.util.LinkedList;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class NamedHealthCheckResultTest {
+    @Test
+    public void testAll() {
+        NamedHealthCheckResult h1 = new NamedHealthCheckResult("Uno", Result.healthy());
+        NamedHealthCheckResult h2 = new NamedHealthCheckResult("Due", Result.unhealthy("Darum"));
+
+        assertEquals("\"Uno\":{\"healthy\":true}", h1.toJson());
+        assertEquals("\"Due\":{\"healthy\":false,\"message\":\"Darum\"}", h2.toJson());
+
+        List<NamedHealthCheckResult> lista = new LinkedList<>();
+        lista.add(h1);
+        lista.add(h2);
+        assertEquals( "{\"Uno\":{\"healthy\":true},\"Due\":{\"healthy\":false,\"message\":\"Darum\"}}",
+                NamedHealthCheckResult.toJson(lista));
+    }
+}
diff --git a/src/test/java/org/eclipse/openk/portal/health/base/ResultTest.java b/src/test/java/org/eclipse/openk/portal/health/base/ResultTest.java
new file mode 100644
index 0000000..9379922
--- /dev/null
+++ b/src/test/java/org/eclipse/openk/portal/health/base/ResultTest.java
@@ -0,0 +1,20 @@
+package org.eclipse.openk.portal.health.base;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+public class ResultTest {
+
+    @Test
+    public void testAll() {
+        Result res1 = Result.healthy();
+        Result res2 = Result.unhealthy("Msg");
+
+        assertTrue(res1.isHealthy());
+        assertFalse(res2.isHealthy());
+        assertNull(res1.getMessage());
+        assertNotNull(res2.getMessage());
+
+    }
+}
diff --git a/src/test/java/org/eclipse/openk/portal/health/impl/KeyCloakPresentHealthCheckTest.java b/src/test/java/org/eclipse/openk/portal/health/impl/KeyCloakPresentHealthCheckTest.java
new file mode 100644
index 0000000..1727b6a
--- /dev/null
+++ b/src/test/java/org/eclipse/openk/portal/health/impl/KeyCloakPresentHealthCheckTest.java
@@ -0,0 +1,37 @@
+package org.eclipse.openk.portal.health.impl;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.powermock.reflect.Whitebox;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class KeyCloakPresentHealthCheckTest {
+    private KeyCloakPresentHealthCheck hc;
+
+    @Before
+    public void init() {
+        hc = new KeyCloakPresentHealthCheck() {
+            public boolean checkit;
+
+            @Override
+            protected boolean checkit() {
+                return checkit;
+            }
+        };
+    }
+
+    @Test
+    public void testOk() throws Exception {
+        Whitebox.setInternalState(hc, "checkit", true);
+        assertTrue(hc.check().isHealthy());
+    }
+
+    @Test
+    public void testNok() throws Exception {
+        Whitebox.setInternalState(hc, "checkit", false);
+        assertFalse(hc.check().isHealthy());
+    }
+
+}