SDN-R helpserver show version info

SDN-R helpserver show version info

Change-Id: Ifa9d5a8c914f942151594c583c31184eef6f3296
Issue-ID: SDNC-681
Signed-off-by: Herbert Eiselt <herbert.eiselt@highstreet-technologies.com>
diff --git a/sdnr/wt/helpserver/provider/pom.xml b/sdnr/wt/helpserver/provider/pom.xml
index fff54d2..72ec046 100644
--- a/sdnr/wt/helpserver/provider/pom.xml
+++ b/sdnr/wt/helpserver/provider/pom.xml
@@ -24,6 +24,9 @@
 	<packaging>bundle</packaging>
 	<properties>
 		<checkstyle.skip>true</checkstyle.skip>
+		<buildtime>${maven.build.timestamp} UTC</buildtime>
+		<distversion>ONAP Dublin (Flourine-SR1)</distversion>
+		<buildno>1.15b7491</buildno>
 	</properties>
 	<parent>
 		<groupId>org.onap.ccsdk.parent</groupId>
@@ -61,6 +64,13 @@
 
 	</dependencies>
 	<build>
+		<resources>
+			<!-- replace properties in about.md -->
+			<resource>
+			<directory>src/main/resources</directory>
+			<filtering>true</filtering>
+			</resource>
+		</resources>
 		<plugins>
 			<!-- fixed bug for sonarcube -->
 			<plugin>
diff --git a/sdnr/wt/helpserver/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/helpserver/HelpServlet.java b/sdnr/wt/helpserver/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/helpserver/HelpServlet.java
index 76ac17b..35e3515 100644
--- a/sdnr/wt/helpserver/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/helpserver/HelpServlet.java
+++ b/sdnr/wt/helpserver/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/helpserver/HelpServlet.java
@@ -22,10 +22,8 @@
 import java.io.FileInputStream;
 import java.io.FileReader;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.URISyntaxException;
-import java.net.URL;
 import java.net.URLDecoder;
 import java.nio.file.Path;
 import java.util.regex.Matcher;
@@ -43,8 +41,6 @@
     private static Logger LOG = LoggerFactory.getLogger(HelpServlet.class);
     private static final long serialVersionUID = -4285072760648493461L;
 
-    private static final boolean USE_FILESYSTEM = true;
-    private static final boolean USE_RESSOURCES = !USE_FILESYSTEM;
     private static final String BASEURI = "/help";
 
     private static final boolean REDIRECT_LINKS = true;
@@ -58,21 +54,14 @@
     }
 
     @Override
-    protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+    public void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         resp.addHeader("Access-Control-Allow-Origin", "*");
         resp.addHeader("Access-Control-Allow-Methods", "OPTIONS, HEAD, GET, POST, PUT, DELETE");
         resp.addHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type, Content-Length");
     }
 
-    /*
-     * (non-Javadoc)
-     *
-     * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest,
-     * javax.servlet.http.HttpServletResponse) Handle Get Request: if query=?meta=send json
-     * infrastructure for README.md else if file exist send file
-     */
     @Override
-    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
         String query = req.getQueryString();
         resp.addHeader("Access-Control-Allow-Origin", "*");
         resp.addHeader("Access-Control-Allow-Methods", "OPTIONS, HEAD, GET, POST, PUT, DELETE");
@@ -99,106 +88,70 @@
             } else {
                 LOG.debug("start walking from path=" + basePath.toAbsolutePath().toString());
                 HelpInfrastructureObject o = null;
-                if (USE_FILESYSTEM) {
-                    try {
-                        o = new HelpInfrastructureObject(this.basePath);
-                    } catch (URISyntaxException e) {
-                        LOG.debug("Can not relsolve URI. ", e);
-                    }
-                } else if (USE_RESSOURCES) {
-                    // o=new HelpInfrastructureObject()
+                try {
+                    o = new HelpInfrastructureObject(this.basePath);
+                } catch (URISyntaxException e) {
+                    LOG.debug("Can not relsolve URI. ", e);
                 }
                 resp.getOutputStream().println(o != null ? o.toString() : "");
             }
             resp.setHeader("Content-Type", "application/json");
-       } else {
+        } else {
             LOG.debug("received get with uri=" + req.getRequestURI());
             String uri = URLDecoder.decode(req.getRequestURI().substring(BASEURI.length()), "UTF-8");
             if (uri.startsWith("/")) {
                 uri = uri.substring(1);
             }
             Path p = basePath.resolve(uri);
-            if (USE_FILESYSTEM) {
-                File f = p.toFile();
-                if (f.isFile() && f.exists()) {
-                    LOG.debug("found file for request");
-                    if (this.isTextFile(f)) {
-                        resp.setHeader("Content-Type", "application/text");
-                        resp.setHeader("charset", "utf-8");
-                    } else if (this.isImageFile(f)) {
-                        resp.setHeader("Content-Type", "image/*");
-                    } else if (this.ispdf(f)) {
-                        resp.setHeader("Content-Type", "application/pdf");
-                    } else {
-                        LOG.debug("file is not allowed to deliver");
-                        resp.setStatus(404);
-                        return;
-                    }
-                    LOG.debug("delivering file");
-                    OutputStream out = resp.getOutputStream();
-                    String version = null;
-                    if (REDIRECT_LINKS) {
-                        version = getVersionFromRequestedUri(uri);
-                    }
-                    if (this.isTextFile(f) && REDIRECT_LINKS && version != null) {
-                        final String regex =
-                                "(!?\\[[^\\]]*?\\])\\(((?:(?!http|www\\.|\\#|\\.com|\\.net|\\.info|\\.org|\\.svg|\\.png|\\.jpg|\\.gif|\\.jpeg|\\.pdf).)*?)\\)";
-                        final Pattern pattern = Pattern.compile(regex);
-                        Matcher matcher;
-                        String line;
-                        try (BufferedReader br = new BufferedReader(new FileReader(f))) {
-                            line = br.readLine();
-                            while (line != null) {
-                                // check line for internal link
-                                matcher = pattern.matcher(line);
-                                if (matcher.find()) {
-                                    // extend link with specific version
-                                    line = line.replace(matcher.group(2),
-                                            "../" + matcher.group(2) + version + "/README.md");
-                                }
-                                out.write((line + "\n").getBytes());
-                                line = br.readLine();
-
-                            }
-                            out.flush();
-                            out.close();
-                            br.close();
-                        }
-
-                    } else {
-                        try (FileInputStream in = new FileInputStream(f)) {
-
-                            byte[] buffer = new byte[1024];
-                            int len;
-                            while ((len = in.read(buffer)) != -1) {
-                                out.write(buffer, 0, len);
-                            }
-                            in.close();
-                            out.flush();
-                            out.close();
-                        }
-                    }
+            File f = p.toFile();
+            if (f.isFile() && f.exists()) {
+                LOG.debug("found file for request");
+                if (this.isTextFile(f)) {
+                    resp.setHeader("Content-Type", "application/text");
+                    resp.setHeader("charset", "utf-8");
+                } else if (this.isImageFile(f)) {
+                    resp.setHeader("Content-Type", "image/*");
+                } else if (this.ispdf(f)) {
+                    resp.setHeader("Content-Type", "application/pdf");
                 } else {
-                    LOG.debug("found not file for request");
+                    LOG.debug("file is not allowed to deliver");
                     resp.setStatus(404);
+                    return;
                 }
-            } else if (USE_RESSOURCES) {
-                URL resurl = this.getClass().getResource(p.toString());
-                if (resurl != null)// resource file found
-                {
-                    if (this.isTextFile(resurl)) {
-                        resp.setHeader("Content-Type", "application/text");
-                        resp.setHeader("charset", "utf-8");
-                    } else if (this.isImageFile(resurl)) {
-                        resp.setHeader("Content-Type", "image/*");
-                    } else if (this.ispdf(resurl)) {
-                        resp.setHeader("Content-Type", "application/pdf");
-                    } else {
-                        resp.setStatus(404);
-                        return;
+                LOG.debug("delivering file");
+                OutputStream out = resp.getOutputStream();
+                String version = null;
+                if (REDIRECT_LINKS) {
+                    version = getVersionFromRequestedUri(uri);
+                }
+                if (this.isTextFile(f) && REDIRECT_LINKS && version != null) {
+                    final String regex =
+                            "(!?\\[[^\\]]*?\\])\\(((?:(?!http|www\\.|\\#|\\.com|\\.net|\\.info|\\.org|\\.svg|\\.png|\\.jpg|\\.gif|\\.jpeg|\\.pdf).)*?)\\)";
+                    final Pattern pattern = Pattern.compile(regex);
+                    Matcher matcher;
+                    String line;
+                    try (BufferedReader br = new BufferedReader(new FileReader(f))) {
+                        line = br.readLine();
+                        while (line != null) {
+                            // check line for internal link
+                            matcher = pattern.matcher(line);
+                            if (matcher.find()) {
+                                // extend link with specific version
+                                line = line.replace(matcher.group(2),
+                                        "../" + matcher.group(2) + version + "/README.md");
+                            }
+                            out.write((line + "\n").getBytes());
+                            line = br.readLine();
+
+                        }
+                        out.flush();
+                        out.close();
+                        br.close();
                     }
-                    try (InputStream in = this.getClass().getResourceAsStream(p.toString())) {
-                        OutputStream out = resp.getOutputStream();
+
+                } else {
+                    try (FileInputStream in = new FileInputStream(f)) {
+
                         byte[] buffer = new byte[1024];
                         int len;
                         while ((len = in.read(buffer)) != -1) {
@@ -208,18 +161,18 @@
                         out.flush();
                         out.close();
                     }
-
-                } else // resource file not found
-                {
-                    resp.setStatus(404);
                 }
+            } else {
+                LOG.debug("found not file for request");
+                resp.setStatus(404);
             }
         }
     }
 
-    /*
-     *
-     * uri = "help/folder1/folder2/version/README.md"
+    /**
+     * Extract version from URI string
+     * @param uri = "help/folder1/folder2/version/README.md"
+     * @return version as a string
      */
     private static String getVersionFromRequestedUri(String uri) {
         if (uri == null) {
@@ -237,18 +190,6 @@
 
     }
 
-    private boolean isTextFile(URL url) {
-        return url != null ? this.isTextFile(url.toString()) : false;
-    }
-
-    private boolean ispdf(URL url) {
-        return url != null ? this.ispdf(url.toString()) : false;
-    }
-
-    private boolean isImageFile(URL url) {
-        return url != null ? this.isImageFile(url.toString()) : false;
-    }
-
     private boolean ispdf(File f) {
         return f != null ? this.ispdf(f.getName()) : false;
     }
@@ -284,8 +225,5 @@
     }
 
     @Override
-    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {}
-
-    @Override
     public void close() throws Exception {}
 }
diff --git a/sdnr/wt/helpserver/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/helpserver/data/Environment.java b/sdnr/wt/helpserver/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/helpserver/data/Environment.java
deleted file mode 100644
index bbbccdb..0000000
--- a/sdnr/wt/helpserver/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/helpserver/data/Environment.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*******************************************************************************
- * ============LICENSE_START========================================================================
- * ONAP : ccsdk feature sdnr wt
- * =================================================================================================
- * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
- * =================================================================================================
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
- * in compliance with the License. You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software distributed under the License
- * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
- * or implied. See the License for the specific language governing permissions and limitations under
- * the License.
- * ============LICENSE_END==========================================================================
- ******************************************************************************/
-package org.onap.ccsdk.features.sdnr.wt.helpserver.data;
-
-import java.net.Inet4Address;
-import java.net.UnknownHostException;
-import java.util.Map;
-
-public class Environment {
-
-	public static String getVar(String v)
-	{
-		if(v.equals("$HOSTNAME"))
-			try {
-				return Inet4Address.getLocalHost().getHostName();
-			} catch (UnknownHostException e) {
-
-			}
-		Map<String, String> env = System.getenv();
-        for (String envName : env.keySet()) {
-           if(envName!=null && envName.equals(v))
-              return env.get(envName);
-        }
-        return null;
-	}
-}
diff --git a/sdnr/wt/helpserver/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/helpserver/data/ExtactBundleResource.java b/sdnr/wt/helpserver/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/helpserver/data/ExtactBundleResource.java
index ac99849..975f898 100644
--- a/sdnr/wt/helpserver/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/helpserver/data/ExtactBundleResource.java
+++ b/sdnr/wt/helpserver/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/helpserver/data/ExtactBundleResource.java
@@ -23,39 +23,43 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Enumeration;
-
 import org.osgi.framework.Bundle;
 
 /**
  * Extract subtree with resources from Opendaylight/Karaf/OSGi bundle into Karaf directory<br>
  *
- * Reference: Eclipsezone @see <a href="https://www.eclipsezone.com/eclipse/forums/t101557.html">https://www.eclipszone.com</a>
- * <br><br>
- * Example for resource and directory path from karaf log.
- *     write resource: help/FAQ/0.4.0/README.md
- *   Create directories for: data/cache/com.highstreet.technologies.help/help/FAQ/0.4.0/README.md
- *   Open the file: data/cache/com.highstreet.technologies.help/help/FAQ/0.4.0/README.md
- *   Problem: Binary, JPG files => do not use buffer related functions
+ * Reference: Eclipsezone @see
+ * <a href="https://www.eclipsezone.com/eclipse/forums/t101557.html">https://www.eclipszone.com</a>
+ * <br>
+ * <br>
+ * Example for resource and directory path from karaf log. write resource: help/FAQ/0.4.0/README.md
+ * Create directories for: data/cache/com.highstreet.technologies.help/help/FAQ/0.4.0/README.md Open
+ * the file: data/cache/com.highstreet.technologies.help/help/FAQ/0.4.0/README.md Problem: Binary,
+ * JPG files => do not use buffer related functions
  *
- * Hint: Werify with file manager the content of the bundle.jar file to see the location of the resources.
- * There is no need to mark them via the classpath.
+ * Hint: Verify with file manager the content of the bundle.jar file to see the location of the
+ * resources. There is no need to mark them via the classpath.
  */
 
 public class ExtactBundleResource {
 
     /**
      * Extract resources from Karaf/OSGi bundle into karaf directory structure.
+     *
      * @param bundle Karaf/OSGi bundle with resources
-     * @param filePrefix prefix in karaf file system for destination e.g. "data/cache/com.highstreet.technologies."
+     * @param filePrefix prefix in karaf file system for destination e.g.
+     *        "data/cache/com.highstreet.technologies."
      * @param ressoureRoot root name of ressources, with leading "/". e.g. "/help"
      * @throws IOException In case of problems.
      */
-    public static void copyBundleResoucesRecursively(Bundle bundle, String filePrefix, String ressoureRoot) throws IOException {
-         copyResourceTreeRecurse(bundle, filePrefix, bundle.getEntryPaths(ressoureRoot));
+    public static void copyBundleResoucesRecursively(Bundle bundle, String filePrefix, String ressoureRoot)
+            throws IOException {
+        copyResourceTreeRecurse(bundle, filePrefix, bundle.getEntryPaths(ressoureRoot));
     }
 
     /**
      * Delete a file or a directory and its children.
+     *
      * @param file The directory to delete.
      * @throws IOException Exception when problem occurs during deleting the directory.
      */
@@ -63,18 +67,13 @@
 
         if (file.isDirectory()) {
             for (File childFile : file.listFiles()) {
-                if (childFile.isDirectory()) {
-                    deleteRecursively(childFile);
-                } else {
-                    if (!childFile.delete()) {
-                        throw new IOException();
-                    }
-                }
+                deleteRecursively(childFile);
             }
         }
-
-        if (!file.delete()) {
-            throw new IOException();
+        if (file.exists()) {
+            if (!file.delete()) {
+                throw new IOException("No file " + file.getName());
+            }
         }
     }
 
@@ -82,24 +81,26 @@
 
     /**
      * Recurse function to steps through the resource element tree
+     *
      * @param b Bundle index for bundle with resourcs
      * @param filePrefix
      * @param resource
      * @throws IOException
      */
-    private static void copyResourceTreeRecurse(Bundle b, String filePrefix, Enumeration<String> resource) throws IOException {
+    private static void copyResourceTreeRecurse(Bundle b, String filePrefix, Enumeration<String> resource)
+            throws IOException {
         while (resource.hasMoreElements()) {
             String name = resource.nextElement();
             Enumeration<String> list = b.getEntryPaths(name);
             if (list != null) {
                 copyResourceTreeRecurse(b, filePrefix, list);
             } else {
-                //Read
-                File targetFile = new File(filePrefix+name);
+                // Read
+                File targetFile = new File(filePrefix + name);
                 targetFile.getParentFile().mkdirs();
 
-                try(InputStream in = b.getEntry(name).openStream();
-                    OutputStream outStream = new FileOutputStream(targetFile);) {
+                try (InputStream in = b.getEntry(name).openStream();
+                        OutputStream outStream = new FileOutputStream(targetFile);) {
 
                     int theInt;
                     while ((theInt = in.read()) >= 0) {
diff --git a/sdnr/wt/helpserver/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/helpserver/data/HelpInfrastructureObject.java b/sdnr/wt/helpserver/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/helpserver/data/HelpInfrastructureObject.java
index 11042d1..2c79645 100644
--- a/sdnr/wt/helpserver/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/helpserver/data/HelpInfrastructureObject.java
+++ b/sdnr/wt/helpserver/provider/src/main/java/org/onap/ccsdk/features/sdnr/wt/helpserver/data/HelpInfrastructureObject.java
@@ -103,8 +103,8 @@
 
     }
 
-    public HelpInfrastructureObject(Path proot) throws URISyntaxException {
-        File root = proot.toFile();
+    public HelpInfrastructureObject(Path pRoot) throws URISyntaxException {
+        File root = pRoot.toFile();
         File[] list = root.listFiles();
         if (list == null) {
             return;
@@ -113,35 +113,11 @@
             if (f.isDirectory()) {
                 ArrayList<VersionObject> versions = findReadmeVersionFolders(root.toPath(), f.toPath(), true);
                 if (versions != null && versions.size() > 0) {
-                    NodeObject o = new NodeObject(proot, f, f.getName(), versions);
+                    NodeObject o = new NodeObject(pRoot, f, f.getName(), versions);
                     this.put(o.getString("label").toLowerCase(), o);
                 }
             }
         }
-
-
-    }
-
-    public static void walk(ArrayList<File> results, String path) {
-
-        File root = new File(path);
-        File[] list = root.listFiles();
-
-        if (list == null) {
-            return;
-        }
-
-        for (File f : list) {
-            if (f.isDirectory()) {
-                walk(results, f.getAbsolutePath());
-                // System.out.println( "Dir:" + f.getAbsoluteFile() );
-            } else {
-                // System.out.println( "File:" + f.getAbsoluteFile() );
-                if (f.isFile() && f.getName().endsWith(".md")) {
-                    results.add(f);
-                }
-            }
-        }
     }
 
     private static ArrayList<VersionObject> findReadmeVersionFolders(Path base, Path root, boolean appendCurrent) {
diff --git a/sdnr/wt/helpserver/provider/src/main/resources/help/sdnr/0.4.0/about.md b/sdnr/wt/helpserver/provider/src/main/resources/help/sdnr/0.4.0/about.md
index 856d69a..31fd5fe 100644
--- a/sdnr/wt/helpserver/provider/src/main/resources/help/sdnr/0.4.0/about.md
+++ b/sdnr/wt/helpserver/provider/src/main/resources/help/sdnr/0.4.0/about.md
@@ -1 +1 @@
-Version: @buildtime@
\ No newline at end of file
+ONAP SDN-R | ONF Wireless for ${distversion} - Build: ${buildtime} (${buildno})
\ No newline at end of file
diff --git a/sdnr/wt/helpserver/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/helpserver/test/TestExtract.java b/sdnr/wt/helpserver/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/helpserver/test/TestExtract.java
new file mode 100644
index 0000000..5f85582
--- /dev/null
+++ b/sdnr/wt/helpserver/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/helpserver/test/TestExtract.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ ******************************************************************************/
+package org.onap.ccsdk.features.sdnr.wt.helpserver.test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import java.io.File;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.ccsdk.features.sdnr.wt.helpserver.data.ExtactBundleResource;
+import org.osgi.framework.Bundle;
+
+public class TestExtract extends Mockito {
+
+    private boolean called = false;
+    private String testFile;
+
+    @Test
+    public void test() {
+
+        Bundle myBundle = mock(Bundle.class);
+
+        final ClassLoader loader = this.getClass().getClassLoader();
+        try {
+            when(myBundle.getEntryPaths(anyString())).thenAnswer(invocation -> {
+                if (!called) {
+                    Object[] args = invocation.getArguments();
+                    System.out.println("Get files from: " + args[0]);
+                    Enumeration<URL> e = loader.getResources((String) args[0]);
+                    List<String> res = new ArrayList<>();
+                    while (e.hasMoreElements()) {
+                        String resourceFileName = e.nextElement().toString();
+                        System.out.println("is file: " + resourceFileName);
+                        res.add(resourceFileName);
+                    }
+                    called = true;
+                    return Collections.enumeration(res);
+                } else {
+                    return null;
+                }
+            });
+            when(myBundle.getEntry(anyString())).thenAnswer(invocation -> {
+                Object[] args = invocation.getArguments();
+                System.out.println("GetEntrye input: "+args[0]);
+                return new URL(testFile = (String) args[0]);
+            });
+
+            String TMPDATAFOLDER = "tmpData";
+
+            ExtactBundleResource.copyBundleResoucesRecursively(myBundle, TMPDATAFOLDER, "help/meta.json");
+
+            assertTrue("Test file not found: "+testFile, new File(TMPDATAFOLDER+testFile).exists());
+
+            ExtactBundleResource.deleteRecursively(new File(TMPDATAFOLDER+"file:"));
+
+            assertFalse("Test not deleted: "+testFile, new File(TMPDATAFOLDER+"file:").exists());
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            fail("Exception" + e);
+        }
+
+
+
+    }
+
+}
diff --git a/sdnr/wt/helpserver/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/helpserver/test/TestHelpInfObject.java b/sdnr/wt/helpserver/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/helpserver/test/TestHelpInfObject.java
new file mode 100644
index 0000000..9d63da5
--- /dev/null
+++ b/sdnr/wt/helpserver/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/helpserver/test/TestHelpInfObject.java
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ ******************************************************************************/
+package org.onap.ccsdk.features.sdnr.wt.helpserver.test;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.ccsdk.features.sdnr.wt.helpserver.data.ExtactBundleResource;
+import org.onap.ccsdk.features.sdnr.wt.helpserver.data.HelpInfrastructureObject;
+
+public class TestHelpInfObject {
+
+    private static final String GETHELPDIRECTORYBASE = "data";
+    private static final String ROOT = "tmp";
+    private static final String CONTENT = "abc";
+
+    @Before
+    public void init() {
+        try {
+            ExtactBundleResource.deleteRecursively(new File(GETHELPDIRECTORYBASE));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+    @After
+    public void deinit() {
+        this.init();
+    }
+    @Test
+    public void test() {
+        File root=new File(HelpInfrastructureObject.getHelpDirectoryBase()+"/"+ROOT);
+        TestMyServlet.createHelpFile("/"+ROOT+"/test/0.4.0/README.md", CONTENT);
+        TestMyServlet.createHelpFile("/"+ROOT+"/test2/0.4.0/README.md", CONTENT);
+        TestMyServlet.createHelpFile("/"+ROOT+"/test3/abc/0.4.0/README.md", CONTENT);
+        TestMyServlet.createHelpFile("/"+ROOT+"/test3/abc1/0.4.0/README.md", CONTENT);
+        TestMyServlet.createHelpFile("/"+ROOT+"/test5/0.4.0/README.md", CONTENT);
+
+        try {
+            new HelpInfrastructureObject(root.toPath());
+        } catch (URISyntaxException e) {
+            fail(e.getMessage());
+        }
+
+
+    }
+
+
+}
diff --git a/sdnr/wt/helpserver/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/helpserver/test/TestHelpServer.java b/sdnr/wt/helpserver/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/helpserver/test/TestHelpInfrastructure.java
similarity index 64%
rename from sdnr/wt/helpserver/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/helpserver/test/TestHelpServer.java
rename to sdnr/wt/helpserver/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/helpserver/test/TestHelpInfrastructure.java
index db6d783..dfe649a 100644
--- a/sdnr/wt/helpserver/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/helpserver/test/TestHelpServer.java
+++ b/sdnr/wt/helpserver/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/helpserver/test/TestHelpInfrastructure.java
@@ -1,4 +1,3 @@
-package org.onap.ccsdk.features.sdnr.wt.helpserver.test;
 /*******************************************************************************
  * ============LICENSE_START========================================================================
  * ONAP : ccsdk feature sdnr wt
@@ -16,20 +15,33 @@
  * the License.
  * ============LICENSE_END==========================================================================
  ******************************************************************************/
-import static org.junit.Assert.assertNotNull;
-import org.junit.Test;
-import org.onap.ccsdk.features.sdnr.wt.helpserver.HelpServlet;
+package org.onap.ccsdk.features.sdnr.wt.helpserver.test;
 
-public class TestHelpServer {
+import static org.junit.Assert.fail;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import org.junit.Test;
+import org.onap.ccsdk.features.sdnr.wt.helpserver.data.HelpInfrastructureObject;
+
+public class TestHelpInfrastructure {
 
     @Test
-    public void test() throws Exception {
+    public void test() {
 
-        HelpServlet helpServelet = new HelpServlet();
+        final ClassLoader loader = this.getClass().getClassLoader();
+        URL url = loader.getResource("help/meta.json");
+        Path path;
+        try {
+            path = Paths.get(url.toURI());
+            HelpInfrastructureObject helpInfrastuctureObject = new HelpInfrastructureObject(path);
+            System.out.println("Help: "+helpInfrastuctureObject);
+        } catch (URISyntaxException e) {
+            fail(e.getMessage());
+        }
 
-        assertNotNull("Helpservelet created", helpServelet);
 
-        helpServelet.close();
     }
 
 }
diff --git a/sdnr/wt/helpserver/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/helpserver/test/TestMyServlet.java b/sdnr/wt/helpserver/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/helpserver/test/TestMyServlet.java
new file mode 100644
index 0000000..e51cc68
--- /dev/null
+++ b/sdnr/wt/helpserver/provider/src/test/java/org/onap/ccsdk/features/sdnr/wt/helpserver/test/TestMyServlet.java
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * ============LICENSE_START========================================================================
+ * ONAP : ccsdk feature sdnr wt
+ * =================================================================================================
+ * Copyright (C) 2019 highstreet technologies GmbH Intellectual Property. All rights reserved.
+ * =================================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ * ============LICENSE_END==========================================================================
+ ******************************************************************************/
+package org.onap.ccsdk.features.sdnr.wt.helpserver.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.nio.file.Files;
+import java.nio.file.OpenOption;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.ccsdk.features.sdnr.wt.helpserver.HelpServlet;
+import org.onap.ccsdk.features.sdnr.wt.helpserver.data.ExtactBundleResource;
+import org.onap.ccsdk.features.sdnr.wt.helpserver.data.HelpInfrastructureObject;
+import static java.nio.file.StandardOpenOption.CREATE_NEW;
+import static java.nio.file.StandardOpenOption.WRITE;
+import static java.nio.file.StandardOpenOption.CREATE;
+import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
+
+public class TestMyServlet extends Mockito {
+
+    private static final String GETHELPDIRECTORYBASE = "data";
+    private static final String CONTENT = "abbccdfkamaosie aksdmais";
+
+    public static void createHelpFile(String filename,String content) {
+        File file=new File(HelpInfrastructureObject.getHelpDirectoryBase() + filename);
+        File folder = file.getParentFile();
+        if(!folder.exists()) {
+            folder.mkdirs();
+        }
+        try {
+            if(file.exists()) {
+                file.delete();
+            }
+            Files.write( file.toPath(),content.getBytes(),new OpenOption[] { WRITE, CREATE_NEW , CREATE, TRUNCATE_EXISTING});
+        } catch (IOException e1) {
+            fail(e1.getMessage());
+        }
+    }
+
+    @Before
+    public void init() {
+        try {
+            ExtactBundleResource.deleteRecursively(new File(GETHELPDIRECTORYBASE));
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+    @After
+    public void deinit() {
+        this.init();
+    }
+
+    @Test
+    public void testServlet() throws Exception {
+
+        System.out.println("Test get");
+
+        HttpServletRequest request = mock(HttpServletRequest.class);
+        HttpServletResponse response = mock(HttpServletResponse.class);
+
+        when(request.getRequestURI()).thenReturn("help/");
+        when(request.getQueryString()).thenReturn("?meta");
+
+        StringWriter stringWriter = new StringWriter();
+        ServletOutputStream out=new ServletOutputStream() {
+
+            @Override
+            public void write(int arg0) throws IOException {
+                stringWriter.write(arg0);
+            }
+        };
+        when(response.getOutputStream()).thenReturn(out);
+
+        HelpServlet helpServlet=null;
+        try {
+            helpServlet = new HelpServlet();
+            System.out.println("Server created");
+            createHelpFile("/meta.json",CONTENT);
+
+            helpServlet.doOptions(request, response);
+            System.out.println("Get calling");
+            helpServlet.doGet(request, response);
+            System.out.println("Get called");
+        } catch (Exception e) {
+            fail(e.getMessage());
+        }
+        if (helpServlet != null) {
+            helpServlet.close();
+        }
+
+        String result = stringWriter.toString().trim();
+        System.out.println("Result: '" + result + "'");
+        assertEquals(CONTENT,result);
+    }
+
+    @Test
+    public void testServlet2() {
+        this.testGetRequest("test/0.4.0/test.txt");
+        this.testGetRequest("test.css");
+        this.testGetRequest("test.eps");
+        this.testGetRequest("test.pdf");
+    }
+
+    private void testGetRequest(String fn) {
+        HelpServlet helpServlet = new HelpServlet();
+        createHelpFile("/"+fn,CONTENT);
+        HttpServletRequest request = mock(HttpServletRequest.class);
+        HttpServletResponse response = mock(HttpServletResponse.class);
+
+        when(request.getRequestURI()).thenReturn("help/"+fn);
+        StringWriter sw = new StringWriter();
+        ServletOutputStream out = new ServletOutputStream() {
+
+            @Override
+            public void write(int arg0) throws IOException {
+                sw.write(arg0);
+            }
+        };
+        try {
+            when(response.getOutputStream()).thenReturn(out);
+            helpServlet.doGet(request, response);
+        } catch (ServletException | IOException e) {
+            fail(e.getMessage());
+        }
+        try {
+            out.close();
+        } catch (Exception e) {
+        }
+        try {
+            helpServlet.close();
+        } catch (Exception e) {
+        }
+
+        assertEquals(CONTENT,sw.toString().trim());
+    }
+}
diff --git a/sdnr/wt/helpserver/provider/src/test/resources/log4j.properties b/sdnr/wt/helpserver/provider/src/test/resources/log4j.properties
deleted file mode 100644
index 142663b..0000000
--- a/sdnr/wt/helpserver/provider/src/test/resources/log4j.properties
+++ /dev/null
@@ -1,12 +0,0 @@
-log4j.rootLogger=INFO, out
-
-log4j.logger.org.apache.camel.impl.converter=WARN
-log4j.logger.org.apache.camel.management=WARN
-log4j.logger.org.apache.camel.impl.DefaultPackageScanClassResolver=WARN
-log4j.logger.org.springframework=ERROR
-
-# CONSOLE appender not used by default
-log4j.appender.out=org.apache.log4j.ConsoleAppender
-log4j.appender.out.layout=org.apache.log4j.PatternLayout
-log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
-
diff --git a/sdnr/wt/helpserver/provider/src/test/resources/simplelogger.properties b/sdnr/wt/helpserver/provider/src/test/resources/simplelogger.properties
new file mode 100644
index 0000000..6f38b50
--- /dev/null
+++ b/sdnr/wt/helpserver/provider/src/test/resources/simplelogger.properties
@@ -0,0 +1,37 @@
+# SLF4J's SimpleLogger configuration file
+# Simple implementation of Logger that sends all enabled log messages, for all defined loggers, to System.err.
+
+# Default logging detail level for all instances of SimpleLogger.
+# Must be one of ("trace", "debug", "info", "warn", or "error").
+# If not specified, defaults to "info".
+org.slf4j.simpleLogger.defaultLogLevel=trace
+
+# Logging detail level for a SimpleLogger instance named "xxx.yyy.zzz".
+# Must be one of ("trace", "debug", "info", "warn", or "error").
+# If not specified, the default logging detail level is used.
+# org.slf4j.simpleLogger.log.xxx.yyy=debug
+org.slf4j.simpleLogger.log.org.onap.ccsdk.features.sdnr.wt.devicemanager=debug
+org.slf4j.simpleLogger.log.org.onap.ccsdk.features.sdnr.wt.devicemanager.base.internalTypes.Resources=info
+org.slf4j.simpleLogger.log.org.onap.ccsdk.features.sdnr.wt.devicemanager.base.netconf.container=trace
+
+# Set to true if you want the current date and time to be included in output messages.
+# Default is false, and will output the number of milliseconds elapsed since startup.
+#org.slf4j.simpleLogger.showDateTime=false
+
+# The date and time format to be used in the output messages.
+# The pattern describing the date and time format is the same that is used in java.text.SimpleDateFormat.
+# If the format is not specified or is invalid, the default format is used.
+# The default format is yyyy-MM-dd HH:mm:ss:SSS Z.
+#org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss:SSS Z
+
+# Set to true if you want to output the current thread name.
+# Defaults to true.
+#org.slf4j.simpleLogger.showThreadName=true
+
+# Set to true if you want the Logger instance name to be included in output messages.
+# Defaults to true.
+#org.slf4j.simpleLogger.showLogName=true
+
+# Set to true if you want the last component of the name to be included in output messages.
+# Defaults to false.
+#org.slf4j.simpleLogger.showShortLogName=false