Introduce mixed-osgi-over-slf4j module

mixed-osgi-over-slf4j modules solves conflict between log service provided by slf4j-over-osgi and Felix SRC implementation

Handle Mediator Log outputs
diff --git a/platform/tools/mixed-osgi-over-slf4j/pom.xml b/platform/tools/mixed-osgi-over-slf4j/pom.xml
new file mode 100644
index 0000000..7a8f568
--- /dev/null
+++ b/platform/tools/mixed-osgi-over-slf4j/pom.xml
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

+

+  <modelVersion>4.0.0</modelVersion>

+

+  <parent>

+	   <groupId>org.eclipse.sensinact.gateway.tools</groupId>

+	   <artifactId>platform.tools</artifactId>

+       <version>2.0-SNAPSHOT</version>

+  </parent>

+

+  <artifactId>mixed-osgi-over-slf4j</artifactId>

+

+  <packaging>bundle</packaging>

+  <name>sensiNact IoT Gateway - Felix SCR compatible LogService over SLF4J</name>

+

+  <dependencies>

+	 <dependency>

+	     <groupId>org.slf4j</groupId>

+	     <artifactId>slf4j-simple</artifactId>

+	     <scope>provided</scope>

+	 </dependency>

+	 <dependency>

+		 <groupId>org.osgi</groupId>

+		 <artifactId>org.osgi.annotation.versioning</artifactId>

+		 <version>1.0.0</version>

+		 <scope>provided</scope>

+	  </dependency>

+	  <dependency>

+		 <groupId>org.eclipse.sensinact.gateway</groupId>

+		 <artifactId>sensinact-utils</artifactId>

+		 <scope>provided</scope>

+	  </dependency>

+  </dependencies>

+

+    <build>

+        <plugins>

+            <plugin>

+                <groupId>org.apache.felix</groupId>

+                <artifactId>maven-bundle-plugin</artifactId>

+                <extensions>true</extensions>

+                <configuration>

+                    <instructions>

+                    	<Bundle-Activator>org.slf4j.osgi.logservice.impl.Activator</Bundle-Activator>

+                    </instructions>

+                </configuration>

+            </plugin>

+        </plugins>

+    </build>

+  

+</project>

diff --git a/platform/tools/mixed-osgi-over-slf4j/src/main/java/org/osgi/service/log/Logger.java b/platform/tools/mixed-osgi-over-slf4j/src/main/java/org/osgi/service/log/Logger.java
new file mode 100644
index 0000000..7d03e09
--- /dev/null
+++ b/platform/tools/mixed-osgi-over-slf4j/src/main/java/org/osgi/service/log/Logger.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2020 Kentyou.
+ * 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
+ *
+ * Contributors:
+ *    Kentyou - initial API and implementation
+ */
+package org.osgi.service.log;
+
+import org.osgi.annotation.versioning.ProviderType;
+
+/**
+ * This is a stripped down copy of the LogService 1.4 API (R7). It's
+ * trimmed down to the methods used by the optional support for
+ * R7 logging.
+ */
+@ProviderType
+public interface Logger {
+
+    String ROOT_LOGGER_NAME = "ROOT";
+
+	boolean isDebugEnabled();
+
+	void debug(String message);
+
+	void debug(String format, Object arg);
+
+	boolean isInfoEnabled();
+
+	void info(String message);
+
+	void info(String format, Object arg);
+
+	boolean isWarnEnabled();
+
+	void warn(String message);
+
+	void warn(String format, Object arg);
+
+	boolean isErrorEnabled();
+
+	void error(String message);
+
+	void error(String format, Object arg);
+}
diff --git a/platform/tools/mixed-osgi-over-slf4j/src/main/java/org/osgi/service/log/LoggerFactory.java b/platform/tools/mixed-osgi-over-slf4j/src/main/java/org/osgi/service/log/LoggerFactory.java
new file mode 100644
index 0000000..f6651cd
--- /dev/null
+++ b/platform/tools/mixed-osgi-over-slf4j/src/main/java/org/osgi/service/log/LoggerFactory.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2020 Kentyou.
+ * 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
+ *
+ * Contributors:
+ *    Kentyou - initial API and implementation
+ */
+package org.osgi.service.log;
+
+import org.osgi.annotation.versioning.ProviderType;
+
+/**
+ * This is a stripped down copy of the LogService 1.4 API (R7). It's
+ * trimmed down to the methods used by the optional support for
+ * R7 logging.
+ */
+@ProviderType
+public interface LoggerFactory {
+    <L extends Logger> L getLogger(String name, Class<L> loggerType);
+}
diff --git a/platform/tools/mixed-osgi-over-slf4j/src/main/java/org/slf4j/osgi/logservice/impl/Activator.java b/platform/tools/mixed-osgi-over-slf4j/src/main/java/org/slf4j/osgi/logservice/impl/Activator.java
new file mode 100644
index 0000000..6e2795a
--- /dev/null
+++ b/platform/tools/mixed-osgi-over-slf4j/src/main/java/org/slf4j/osgi/logservice/impl/Activator.java
@@ -0,0 +1,52 @@
+/*

+ * Copyright (c) 2020 Kentyou.

+ * 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

+ *

+ * Contributors:

+ *    Kentyou - initial API and implementation

+ */

+package org.slf4j.osgi.logservice.impl;

+

+import java.util.Dictionary;

+import java.util.Hashtable;

+

+import org.osgi.framework.BundleActivator;

+import org.osgi.framework.BundleContext;

+import org.osgi.framework.ServiceFactory;

+import org.osgi.service.log.LogService;

+

+/**

+ * Handles activation/deactivation of the bundle

+ */

+public class Activator implements BundleActivator {

+    /**

+     *

+     * Registers a LogServiceFactory.

+     *

+     * @param bundleContext the framework context for the bundle

+     * @throws Exception

+     */

+    public void start(BundleContext bundleContext) throws Exception {

+

+        Dictionary<String,Object> props = new Hashtable<String, Object>();

+        props.put("description", "An SLF4J LogService implementation.");

+        ServiceFactory factory = new LogServiceFactory();

+        bundleContext.registerService(LogService.class.getName(), factory, props);

+    }

+

+    /**

+     *

+     * Implements <code>BundleActivator.stop()</code>.

+     *

+     * @param bundleContext the framework context for the bundle

+     * @throws Exception

+     */

+    public void stop(BundleContext bundleContext) throws Exception {

+

+        // Note: It is not required that we remove the service here, since

+        // the framework will do it automatically.

+    }

+}

diff --git a/platform/tools/mixed-osgi-over-slf4j/src/main/java/org/slf4j/osgi/logservice/impl/LogServiceFactory.java b/platform/tools/mixed-osgi-over-slf4j/src/main/java/org/slf4j/osgi/logservice/impl/LogServiceFactory.java
new file mode 100644
index 0000000..6035a4b
--- /dev/null
+++ b/platform/tools/mixed-osgi-over-slf4j/src/main/java/org/slf4j/osgi/logservice/impl/LogServiceFactory.java
@@ -0,0 +1,31 @@
+/*

+ * Copyright (c) 2020 Kentyou.

+ * 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

+ *

+ * Contributors:

+ *    Kentyou - initial API and implementation

+ */

+package org.slf4j.osgi.logservice.impl;

+

+import org.osgi.framework.Bundle;

+import org.osgi.framework.ServiceFactory;

+import org.osgi.framework.ServiceRegistration;

+

+/**

+ * <code>LogServiceFactory</code> creates LogService implementations.

+ */

+public class LogServiceFactory implements ServiceFactory {

+

+	@Override

+    public Object getService(Bundle bundle, ServiceRegistration arg1) {

+        return new LogServiceImpl(bundle);

+    }

+

+	@Override

+    public void ungetService(Bundle bundle, ServiceRegistration arg1, Object arg2) {

+        // nothing to do.

+    }

+}

diff --git a/platform/tools/mixed-osgi-over-slf4j/src/main/java/org/slf4j/osgi/logservice/impl/LogServiceImpl.java b/platform/tools/mixed-osgi-over-slf4j/src/main/java/org/slf4j/osgi/logservice/impl/LogServiceImpl.java
new file mode 100644
index 0000000..56007ef
--- /dev/null
+++ b/platform/tools/mixed-osgi-over-slf4j/src/main/java/org/slf4j/osgi/logservice/impl/LogServiceImpl.java
@@ -0,0 +1,238 @@
+/*

+ * Copyright (c) 2020 Kentyou.

+ * 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

+ *

+ * Contributors:

+ *    Kentyou - initial API and implementation

+ */

+package org.slf4j.osgi.logservice.impl;

+

+import org.eclipse.sensinact.gateway.util.ReflectUtils;

+import org.osgi.framework.Bundle;

+import org.osgi.framework.ServiceReference;

+import org.osgi.framework.Version;

+import org.osgi.service.log.LogService;

+import org.slf4j.Logger;

+import org.slf4j.LoggerFactory;

+

+/**

+ * <code>LogServiceImpl</code> is a simple OSGi LogService implementation that delegates to a slf4j

+ * Logger.

+ */

+public class LogServiceImpl implements LogService {

+

+    private static final String UNKNOWN = "[Unknown]";

+

+    private final Logger delegate;

+

+    /**

+     * Creates a new instance of LogServiceImpl.

+     *

+     * @param bundle The bundle to create a new LogService for.

+     */

+    public LogServiceImpl(Bundle bundle) {

+

+        String name = bundle.getSymbolicName();

+        Version version = bundle.getVersion();

+        if (version == null) {

+            version = Version.emptyVersion;

+        }

+        delegate = LoggerFactory.getLogger(name + '.' + version);

+    }

+

+	@SuppressWarnings("unchecked")

+	@Override

+	public <L extends org.osgi.service.log.Logger> L getLogger(String name, Class<L> loggerType) {

+		if(loggerType == org.osgi.service.log.Logger.class) {

+			return (L) new org.osgi.service.log.Logger(){

+				private Logger delegate = LoggerFactory.getLogger(name);

+				

+				@Override

+				public boolean isDebugEnabled() {

+					return delegate.isDebugEnabled();

+				}

+

+				@Override

+				public void debug(String message) {

+					delegate.debug(message);

+				}

+

+				@Override

+				public void debug(String format, Object arg) {

+					delegate.debug(format, arg);

+				}

+

+				@Override

+				public boolean isInfoEnabled() {

+					return delegate.isInfoEnabled();

+				}

+

+				@Override

+				public void info(String message) {

+					delegate.info(message);

+				}

+

+				@Override

+				public void info(String format, Object arg) {

+					delegate.info(format, arg);

+				}

+

+				@Override

+				public boolean isWarnEnabled() {

+					return delegate.isWarnEnabled();

+				}

+

+				@Override

+				public void warn(String message) {

+					delegate.warn(message);

+				}

+

+				@Override

+				public void warn(String format, Object arg) {

+					delegate.warn(format,arg);

+				}

+

+				@Override

+				public boolean isErrorEnabled() {

+					return delegate.isErrorEnabled();

+				}

+

+				@Override

+				public void error(String message) {

+					delegate.error(message);

+				}

+

+				@Override

+				public void error(String format, Object arg) {

+					delegate.error(format, arg);

+				}

+			};

+		}

+		if(loggerType.isInterface())

+			return null;

+		return ReflectUtils.getTheBestInstance(loggerType, new Object[] {name});

+	}

+	

+	@Override

+    public void log(int level, String message) {

+

+        switch (level) {

+        case LOG_DEBUG:

+            delegate.debug(message);

+            break;

+        case LOG_ERROR:

+            delegate.error(message);

+            break;

+        case LOG_INFO:

+            delegate.info(message);

+            break;

+        case LOG_WARNING:

+            delegate.warn(message);

+            break;

+        default:

+            break;

+        }

+    }

+

+	@Override

+    public void log(int level, String message, Throwable exception) {

+

+        switch (level) {

+        case LOG_DEBUG:

+            delegate.debug(message, exception);

+            break;

+        case LOG_ERROR:

+            delegate.error(message, exception);

+            break;

+        case LOG_INFO:

+            delegate.info(message, exception);

+            break;

+        case LOG_WARNING:

+            delegate.warn(message, exception);

+            break;

+        default:

+            break;

+        }

+    }

+

+	@Override

+    public void log(ServiceReference sr, int level, String message) {

+

+        switch (level) {

+        case LOG_DEBUG:

+            if (delegate.isDebugEnabled()) {

+                delegate.debug(createMessage(sr, message));

+            }

+            break;

+        case LOG_ERROR:

+            if (delegate.isErrorEnabled()) {

+                delegate.error(createMessage(sr, message));

+            }

+            break;

+        case LOG_INFO:

+            if (delegate.isInfoEnabled()) {

+                delegate.info(createMessage(sr, message));

+            }

+            break;

+        case LOG_WARNING:

+            if (delegate.isWarnEnabled()) {

+                delegate.warn(createMessage(sr, message));

+            }

+            break;

+        default:

+            break;

+        }

+    }

+

+    /**

+     * Formats the log message to indicate the service sending it, if known.

+     *

+     * @param sr the ServiceReference sending the message.

+     * @param message The message to log.

+     * @return The formatted log message.

+     */

+    private String createMessage(ServiceReference sr, String message) {

+

+        StringBuilder output = new StringBuilder();

+        if (sr != null) {

+            output.append('[').append(sr.toString()).append(']');

+        } else {

+            output.append(UNKNOWN);

+        }

+        output.append(message);

+

+        return output.toString();

+    }

+

+	@Override

+    public void log(ServiceReference sr, int level, String message, Throwable exception) {

+

+        switch (level) {

+        case LOG_DEBUG:

+            if (delegate.isDebugEnabled()) {

+                delegate.debug(createMessage(sr, message), exception);

+            }

+            break;

+        case LOG_ERROR:

+            if (delegate.isErrorEnabled()) {

+                delegate.error(createMessage(sr, message), exception);

+            }

+            break;

+        case LOG_INFO:

+            if (delegate.isInfoEnabled()) {

+                delegate.info(createMessage(sr, message), exception);

+            }

+            break;

+        case LOG_WARNING:

+            if (delegate.isWarnEnabled()) {

+                delegate.warn(createMessage(sr, message), exception);

+            }

+            break;

+        default:

+            break;

+        }

+    }

+}

diff --git a/platform/tools/pom.xml b/platform/tools/pom.xml
index 57b8302..7c58b34 100644
--- a/platform/tools/pom.xml
+++ b/platform/tools/pom.xml
@@ -34,5 +34,7 @@
 		<module>swagger</module>
 		<module>mqtt-server</module>
 		<module>influxdb-connector</module>
+		<module>mongodb-connector</module>
+		<module>mixed-osgi-over-slf4j</module>
 	</modules>
 </project>