aboutsummaryrefslogtreecommitdiffstats
path: root/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api
diff options
context:
space:
mode:
authorvempo <vitaliy.emporopulo@amdocs.com>2018-01-08 20:59:19 +0200
committerVitaly Emporopulo <Vitaliy.Emporopulo@amdocs.com>2018-01-09 13:41:15 +0000
commit1c1edf2e7b1ddef504d8b075b2763e0b0d83a2aa (patch)
tree9860b1a7eae0962db44d61118bae24eea8dc8d8b /openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api
parent6a96c39bf51c02fef0b35bba8b9e1430a18cbd2b (diff)
Added logging context service, refactoring
Change-Id: Ib040d4579107b60c8da2c7a6da829f49c1cd8dd4 Issue-ID: SDC-772 Signed-off-by: vempo <vitaliy.emporopulo@amdocs.com>
Diffstat (limited to 'openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api')
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggerFactory.java447
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggingContext.java109
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/ServiceBinder.java93
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/context/TaskFactory.java71
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/provider/LoggerCreationService.java (renamed from openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggerCreationService.java)5
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/provider/LoggingContextService.java70
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/provider/LoggingServiceProvider.java30
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggerFactoryTest.java74
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggingContextTest.java101
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/ServiceBinderTest.java (renamed from openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/context/ContextPropagationService.java)30
-rw-r--r--openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/context/TaskFactoryTest.java32
11 files changed, 689 insertions, 373 deletions
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggerFactory.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggerFactory.java
index 1be2fa21dc..b790a02042 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggerFactory.java
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggerFactory.java
@@ -4,9 +4,9 @@
* 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.
@@ -16,245 +16,244 @@
package org.openecomp.sdc.logging.api;
+import org.openecomp.sdc.logging.provider.LoggerCreationService;
+
+import java.util.Objects;
/**
* <a>Factory to hide a concrete, framework-specific implementation of logger creation.</a>
* <p>The service used by this factory must implement {@link LoggerCreationService}. If no
- * implementation has been configured or could not be instantiated, a <b>no-op logger</b> will be
+ * implementation has been configured or could be instantiated, a <b>no-op logger</b> will be
* used, and <b>no events</b> will be logged. This is done to prevent recursion if attempts are
* being made to log exceptions that resulted from logger initialization. </p>
*
* @author evitaliy
- * @see BaseFactory
- * @see LoggerCreationService
* @since 13/09/2016.
+ *
+ * @see ServiceBinder
+ * @see LoggerCreationService
*/
-@SuppressWarnings("ThrowableInstanceNeverThrown")
-public class LoggerFactory extends BaseFactory {
-
- private static final LoggerCreationService SERVICE;
+public class LoggerFactory {
- static {
- LoggerCreationService service;
+ // use the no-op service to prevent recursion in case of an attempt to log an exception as a
+ // result of a logger initialization error
+ private static final LoggerCreationService SERVICE = ServiceBinder.getCreationServiceBinding().orElse(
+ new NoOpLoggerCreationService());
- try {
- service = locateService(LoggerCreationService.class);
- } catch (Exception ex) {
- new RuntimeException("Failed to instantiate logger factory", ex).printStackTrace();
- // use the no-op service to prevent recursion in case of an attempt to log an exception as a
- // result of a logger initialization error
- service = new NoOpLoggerCreationService();
+ private LoggerFactory() {
+ // prevent instantiation
}
- SERVICE = service;
- }
-
- public static Logger getLogger(String clazzName) {
- return SERVICE.getLogger(clazzName);
- }
-
- public static Logger getLogger(Class<?> clazz) {
- return SERVICE.getLogger(clazz);
- }
-
- private static class NoOpLoggerCreationService implements LoggerCreationService {
- private static final Logger NO_OP_LOGGER = new NoOpLogger();
-
- private static class NoOpLogger implements Logger {
- @Override
- public String getName() {
- return "No-Op Logger";
- }
-
- @Override
- public boolean isMetricsEnabled() {
- return false;
- }
-
- @Override
- public void metrics(String msg) {
- //this is no_op_method
- }
-
- @Override
- public void metrics(String msg, Object arg) {
- //this is no_op_method
- }
-
- @Override
- public void metrics(String msg, Object arg1, Object arg2) {
- //this is no_op_method
- }
-
- @Override
- public void metrics(String msg, Object... arguments) {
- //this is no_op_method
- }
-
- @Override
- public void metrics(String msg, Throwable t) {
- //this is no_op_method
- }
-
- @Override
- public boolean isAuditEnabled() {
- return false;
- }
-
- @Override
- public void audit(String msg) {
- //this is no_op_method
- }
-
- @Override
- public void audit(String msg, Object arg) {
- //this is no_op_method
- }
-
- @Override
- public void audit(String msg, Object arg1, Object arg2) {
- //this is no_op_method
- }
-
- @Override
- public void audit(String msg, Object... arguments) {
- //this is no_op_method
- }
-
- @Override
- public void audit(String msg, Throwable t) {
- //this is no_op_method
- }
-
- @Override
- public boolean isDebugEnabled() {
- return false;
- }
-
- @Override
- public void debug(String msg) {
- //this is no_op_method
- }
-
- @Override
- public void debug(String msg, Object arg) {
- //this is no_op_method
- }
-
- @Override
- public void debug(String msg, Object arg1, Object arg2) {
- //this is no_op_method
- }
-
- @Override
- public void debug(String msg, Object... arguments) {
- //this is no_op_method
- }
-
- @Override
- public void debug(String msg, Throwable t) {
- //this is no_op_method
- }
-
- @Override
- public boolean isInfoEnabled() {
- return false;
- }
-
- @Override
- public void info(String msg) {
- //this is no_op_method
- }
-
- @Override
- public void info(String msg, Object arg) {
- //this is no_op_method
- }
-
- @Override
- public void info(String msg, Object arg1, Object arg2) {
- //this is no_op_method
- }
-
- @Override
- public void info(String msg, Object... arguments) {
- //this is no_op_method
- }
-
- @Override
- public void info(String msg, Throwable t) {
- //this is no_op_method
- }
-
- @Override
- public boolean isWarnEnabled() {
- return false;
- }
-
- @Override
- public void warn(String msg) {
- //this is no_op_method
- }
-
- @Override
- public void warn(String msg, Object arg) {
- //this is no_op_method
- }
-
- @Override
- public void warn(String msg, Object... arguments) {
- //this is no_op_method
- }
-
- @Override
- public void warn(String msg, Object arg1, Object arg2) {
- //this is no_op_method
- }
-
- @Override
- public void warn(String msg, Throwable t) {
- //this is no_op_method
- }
-
- @Override
- public boolean isErrorEnabled() {
- return false;
- }
-
- @Override
- public void error(String msg) {
- //this is no_op_method
- }
-
- @Override
- public void error(String msg, Object arg) {
- //this is no_op_method
- }
-
- @Override
- public void error(String msg, Object arg1, Object arg2) {
- //this is no_op_method
- }
-
- @Override
- public void error(String msg, Object... arguments) {
- //this is no_op_method
- }
-
- @Override
- public void error(String msg, Throwable t) {
- //this is no_op_method
- }
+ public static Logger getLogger(String clazzName) {
+ return SERVICE.getLogger(clazzName);
}
- @Override
- public Logger getLogger(String className) {
- return NO_OP_LOGGER;
+ public static Logger getLogger(Class<?> clazz) {
+ return SERVICE.getLogger(clazz);
}
- @Override
- public Logger getLogger(Class<?> clazz) {
- return NO_OP_LOGGER;
+ private static class NoOpLoggerCreationService implements LoggerCreationService {
+
+ private static final Logger NO_OP_LOGGER = new NoOpLogger();
+
+ private static class NoOpLogger implements Logger {
+
+ @Override
+ public String getName() {
+ return "No-Op Logger";
+ }
+
+ @Override
+ public boolean isMetricsEnabled() {
+ return false;
+ }
+
+ @Override
+ public void metrics(String msg) {
+ // no-op
+ }
+
+ @Override
+ public void metrics(String msg, Object arg) {
+ // no-op
+ }
+
+ @Override
+ public void metrics(String msg, Object arg1, Object arg2) {
+ // no-op
+ }
+
+ @Override
+ public void metrics(String msg, Object... arguments) {
+ // no-op
+ }
+
+ @Override
+ public void metrics(String msg, Throwable t) {
+ // no-op
+ }
+
+ @Override
+ public boolean isAuditEnabled() {
+ return false;
+ }
+
+ @Override
+ public void audit(String msg) {
+ // no-op
+ }
+
+ @Override
+ public void audit(String msg, Object arg) {
+ // no-op
+ }
+
+ @Override
+ public void audit(String msg, Object arg1, Object arg2) {
+ // no-op
+ }
+
+ @Override
+ public void audit(String msg, Object... arguments) {
+ // no-op
+ }
+
+ @Override
+ public void audit(String msg, Throwable t) {
+ // no-op
+ }
+
+ @Override
+ public boolean isDebugEnabled() {
+ return false;
+ }
+
+ @Override
+ public void debug(String msg) {
+ // no-op
+ }
+
+ @Override
+ public void debug(String msg, Object arg) {
+ // no-op
+ }
+
+ @Override
+ public void debug(String msg, Object arg1, Object arg2) {
+ // no-op
+ }
+
+ @Override
+ public void debug(String msg, Object... arguments) {
+ // no-op
+ }
+
+ @Override
+ public void debug(String msg, Throwable t) {
+ // no-op
+ }
+
+ @Override
+ public boolean isInfoEnabled() {
+ return false;
+ }
+
+ @Override
+ public void info(String msg) {
+ // no-op
+ }
+
+ @Override
+ public void info(String msg, Object arg) {
+ // no-op
+ }
+
+ @Override
+ public void info(String msg, Object arg1, Object arg2) {
+ // no-op
+ }
+
+ @Override
+ public void info(String msg, Object... arguments) {
+ // no-op
+ }
+
+ @Override
+ public void info(String msg, Throwable t) {
+ // no-op
+ }
+
+ @Override
+ public boolean isWarnEnabled() {
+ return false;
+ }
+
+ @Override
+ public void warn(String msg) {
+ // no-op
+ }
+
+ @Override
+ public void warn(String msg, Object arg) {
+ // no-op
+ }
+
+ @Override
+ public void warn(String msg, Object... arguments) {
+ // no-op
+ }
+
+ @Override
+ public void warn(String msg, Object arg1, Object arg2) {
+ // no-op
+ }
+
+ @Override
+ public void warn(String msg, Throwable t) {
+ // no-op
+ }
+
+ @Override
+ public boolean isErrorEnabled() {
+ return false;
+ }
+
+ @Override
+ public void error(String msg) {
+ // no-op
+ }
+
+ @Override
+ public void error(String msg, Object arg) {
+ // no-op
+ }
+
+ @Override
+ public void error(String msg, Object arg1, Object arg2) {
+ // no-op
+ }
+
+ @Override
+ public void error(String msg, Object... arguments) {
+ // no-op
+ }
+
+ @Override
+ public void error(String msg, Throwable t) {
+ // no-op
+ }
+ }
+
+ @Override
+ public Logger getLogger(String className) {
+ Objects.requireNonNull(className, "Name cannot be null");
+ return NO_OP_LOGGER;
+ }
+
+ @Override
+ public Logger getLogger(Class<?> clazz) {
+ Objects.requireNonNull(clazz, "Class cannot be null");
+ return NO_OP_LOGGER;
+ }
}
- }
}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggingContext.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggingContext.java
new file mode 100644
index 0000000000..542f709074
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggingContext.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * 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.
+ */
+
+package org.openecomp.sdc.logging.api;
+
+import org.openecomp.sdc.logging.provider.LoggingContextService;
+
+import java.util.Objects;
+import java.util.concurrent.Callable;
+
+/**
+ * <a>Factory to hide a concrete, framework-specific implementation of diagnostic context.</a>
+ * <p>The service used by this factory must implement {@link LoggingContextService}. If no
+ * implementation has been configured or could be instantiated, a <b>no-op context service</b> will be
+ * used, and <b>no context</b> will be stored or propagated. No errors will be generated, so that the application can
+ * still work (albeit without proper logging).</p>
+ *
+ * @author evitaliy
+ * @since 07/01/2018.
+ *
+ * @see ServiceBinder
+ * @see LoggingContextService
+ */
+public class LoggingContext {
+
+ private static final LoggingContextService SERVICE = ServiceBinder.getContextServiceBinding().orElse(
+ new NoOpLoggingContextService());
+
+ private LoggingContext() {
+ // prevent instantiation
+ }
+
+ public static void put(String key, String value) {
+ SERVICE.put(key, value);
+ }
+
+ public static String get(String key) {
+ return SERVICE.get(key);
+ }
+
+ public static void remove(String key) {
+ SERVICE.remove(key);
+ }
+
+ public static void clear() {
+ SERVICE.clear();
+ }
+
+ public static Runnable toRunnable(Runnable runnable) {
+ return SERVICE.toRunnable(runnable);
+ }
+
+ public static <V> Callable<V> toCallable(Callable<V> callable) {
+ return SERVICE.toCallable(callable);
+ }
+
+ private static class NoOpLoggingContextService implements LoggingContextService {
+
+ private static final String KEY_CANNOT_BE_NULL = "Key cannot be null";
+
+ @Override
+ public void put(String key, String value) {
+ Objects.requireNonNull(key, KEY_CANNOT_BE_NULL);
+ // no-op
+ }
+
+ @Override
+ public String get(String key) {
+ Objects.requireNonNull(key, KEY_CANNOT_BE_NULL);
+ return null;
+ }
+
+ @Override
+ public void remove(String key) {
+ Objects.requireNonNull(key, KEY_CANNOT_BE_NULL);
+ // no-op
+ }
+
+ @Override
+ public void clear() {
+ // no-op
+ }
+
+ @Override
+ public Runnable toRunnable(Runnable runnable) {
+ Objects.requireNonNull(runnable, "Runnable cannot be null");
+ return runnable;
+ }
+
+ @Override
+ public <V> Callable<V> toCallable(Callable<V> callable) {
+ Objects.requireNonNull(callable, "Callable cannot be null");
+ return callable;
+ }
+ }
+}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/ServiceBinder.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/ServiceBinder.java
new file mode 100644
index 0000000000..b16f3944e9
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/ServiceBinder.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * 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.
+ */
+
+package org.openecomp.sdc.logging.api;
+
+import org.openecomp.sdc.logging.provider.LoggerCreationService;
+import org.openecomp.sdc.logging.provider.LoggingContextService;
+import org.openecomp.sdc.logging.provider.LoggingServiceProvider;
+
+import java.util.Iterator;
+import java.util.Optional;
+import java.util.ServiceLoader;
+
+/**
+ * <p>Binds to a concrete implementation of logging services.</p>
+ *
+ * <p>In order to use the factory, a particular (e.g. framework-specific) implementation of a service must be
+ * configured as described in
+ * <a href="http://docs.oracle.com/javase/8/docs/api/java/util/ServiceLoader.html">java.util.ServiceLoader</a>).</p>
+ *
+ * @author evitaliy
+ * @since 13/09/2016.
+ *
+ * @see ServiceLoader
+ */
+
+// No advanced logging can be used here because we don't know
+// which underlying implementation will be used
+@SuppressWarnings({"UseOfSystemOutOrSystemErr", "squid:S106"})
+class ServiceBinder {
+
+ private static final LoggingServiceProvider PROVIDER = lookupProvider();
+
+ private ServiceBinder () {
+ // prevent instantiation
+ }
+
+ private static LoggingServiceProvider lookupProvider() {
+
+ ServiceLoader<LoggingServiceProvider> loader = ServiceLoader.load(LoggingServiceProvider.class);
+ Iterator<LoggingServiceProvider> iterator = loader.iterator();
+
+ if (!iterator.hasNext()) {
+ System.err.printf("[ERROR] No provider configured for logging services %s. " +
+ "Default implementation will be used.\n",
+ LoggingServiceProvider.class.getName());
+ return null;
+ }
+
+ try {
+
+ LoggingServiceProvider provider = iterator.next();
+ if (!iterator.hasNext()) {
+ return provider;
+ }
+
+ Logger logger = provider.getLogger(ServiceBinder.class);
+ if (logger.isWarnEnabled()) {
+ logger.warn("More than one provider for logging services {} found",
+ LoggingServiceProvider.class.getName());
+ }
+
+ return provider;
+
+ } catch (Exception e) {
+ // don't fail if the provider cannot be instantiated
+ e.printStackTrace(System.err);
+ return null;
+ }
+ }
+
+ static Optional<LoggingContextService> getContextServiceBinding() {
+ return Optional.ofNullable(PROVIDER);
+ }
+
+ static Optional<LoggerCreationService> getCreationServiceBinding() {
+ return Optional.ofNullable(PROVIDER);
+ }
+}
+
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/context/TaskFactory.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/context/TaskFactory.java
deleted file mode 100644
index 8621638460..0000000000
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/context/TaskFactory.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright © 2016-2017 European Support Limited
- *
- * 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.
- */
-
-package org.openecomp.sdc.logging.api.context;
-
-import org.openecomp.sdc.logging.api.BaseFactory;
-
-/**
- * <p>Should be used to propagate a diagnostic context (for instance <a
- * href="http://www.slf4j.org/manual.html#mdc">MDC</a>) to other threads.</p>
- * <p>Applicable when creating a child thread directly, or submitting tasks for potentially
- * postponed execution via an <a href="http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html">Executor</a>
- * (including any of the <a href="http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html">executor
- * services</a> and <a href="http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html">ForkJoinPool</a>).</p>
- * <p>The service used by this factory must implement {@link ContextPropagationService}.</p>
- *
- * @author evitaliy
- * @see ContextPropagationService
- * @since 12/09/2016.
- */
-@SuppressWarnings("ThrowableInstanceNeverThrown")
-public class TaskFactory extends BaseFactory {
-
- private static final ContextPropagationService SERVICE;
- private static final RuntimeException ERROR;
-
- static {
-
- ContextPropagationService service = null;
- RuntimeException error = null;
-
- try {
- service = locateService(ContextPropagationService.class);
- } catch (Exception ex) {
- error = new RuntimeException("Failed to instantiate task factory", ex);
- }
-
- SERVICE = service;
- ERROR = error;
- }
-
- /**
- * Modify a task so that a diagnostic context is propagated to the thread when the task runs. Done
- * in a logging-framework specific way.
- *
- * @param task any Runnable that will run in a thread
- * @return modified (wrapped) original task that runs the same business logic, but also takes care
- * of copying the diagnostic context for logging
- */
- public static Runnable create(Runnable task) {
-
- if (SERVICE == null) {
- throw ERROR;
- }
-
- return SERVICE.create(task);
- }
-}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggerCreationService.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/provider/LoggerCreationService.java
index 1d8eda255e..344d23688e 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/LoggerCreationService.java
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/provider/LoggerCreationService.java
@@ -14,7 +14,10 @@
* limitations under the License.
*/
-package org.openecomp.sdc.logging.api;
+package org.openecomp.sdc.logging.provider;
+
+import org.openecomp.sdc.logging.api.Logger;
+import org.openecomp.sdc.logging.api.LoggerFactory;
/**
*
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/provider/LoggingContextService.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/provider/LoggingContextService.java
new file mode 100644
index 0000000000..8e725e7cc5
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/provider/LoggingContextService.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * 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.
+ */
+
+package org.openecomp.sdc.logging.provider;
+
+import java.util.concurrent.Callable;
+
+/**
+ * Should be used to implement a framework-specific mechanism of managing a per-thread diagnostic context
+ * (for instance <a href="http://www.slf4j.org/manual.html#mdc">MDC</a>), and propagating it to child threads if needed.
+ * Context propagation should be used when creating a child thread directly, or submitting tasks for potentially
+ * postponed execution via an
+ * <a href="http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html">Executor</a> (including any of
+ * the
+ * <a href="http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html">executor services</a>
+ * and <a href="http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html">ForkJoinPool</a>).
+ *
+ * @author evitaliy
+ * @since 07/01/2018.
+ */
+
+public interface LoggingContextService {
+
+ /**
+ * Allows to store a key-value pair on thread context
+ */
+ void put(String key, String value);
+
+ /**
+ * Returns the value associated with a key stored on thread context
+ *
+ * @return value or <code>null</code> if the key does not exits
+ */
+ String get(String key);
+
+ /**
+ * Removes a particular key from thread context
+ */
+ void remove(String key);
+
+ /**
+ * Clear logging thread context
+ */
+ void clear();
+
+ /**
+ * Copies logging context of current thread onto a {@link Runnable}, so that the context is available
+ * when this {@link Runnable} runs in another thread.
+ */
+ Runnable toRunnable(Runnable runnable);
+
+ /**
+ * Copies logging context of current thread onto a {@link Callable}, so that the context is available
+ * when this {@link Callable} runs in another thread
+ */
+ <V> Callable<V> toCallable(Callable<V> callable);
+}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/provider/LoggingServiceProvider.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/provider/LoggingServiceProvider.java
new file mode 100644
index 0000000000..baf99f0e55
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/provider/LoggingServiceProvider.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * 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.
+ */
+
+package org.openecomp.sdc.logging.provider;
+
+/**
+ * <p>From the application code (consumer) perspective, logger creation (factory) and logging context are independent
+ * services. From the service provider perspective, however, these services are related and must be implemented together
+ * using the same underlying mechanism. Therefore, the service provider-facing interface combines the two services
+ * &mdash; to eliminate the chance that their implementations don't work well together.</p>
+ *
+ * @author EVITALIY
+ * @since 07 Jan 18
+ */
+public interface LoggingServiceProvider extends LoggerCreationService, LoggingContextService {
+ // single provider must implement two separate consumer services
+}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggerFactoryTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggerFactoryTest.java
index 4b3a1ba7c7..9fde4e5e6c 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggerFactoryTest.java
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggerFactoryTest.java
@@ -4,9 +4,9 @@
* 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.
@@ -19,10 +19,8 @@ package org.openecomp.sdc.logging.api;
import org.testng.annotations.Test;
import java.lang.reflect.Field;
-import java.util.ServiceLoader;
import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertNotNull;
/**
@@ -31,40 +29,48 @@ import static org.testng.Assert.assertNotNull;
*/
public class LoggerFactoryTest {
- @Test
- public void testNoOpLoggerService() throws Exception {
+ @Test
+ public void shouldHoldNoOpWhenNoBinding() throws Exception {
+
+ // set up to access the private static field
+ Field factory = LoggerFactory.class.getDeclaredField("SERVICE");
+ factory.setAccessible(true);
+ Object impl = factory.get(null);
- assertFalse(ServiceLoader.load(LoggerCreationService.class).iterator().hasNext());
+ assertEquals(impl.getClass().getName(),
+ "org.openecomp.sdc.logging.api.LoggerFactory$NoOpLoggerCreationService");
+ }
- LoggerFactory.getLogger(LoggerFactoryTest.class);
- Field factory = LoggerFactory.class.getDeclaredField("SERVICE");
- factory.setAccessible(true);
- Object impl = factory.get(null);
- assertEquals("org.openecomp.sdc.logging.api.LoggerFactory$NoOpLoggerCreationService",
- impl.getClass().getName());
- }
+ @Test
+ public void verifyNoOpLoggerWorksWhenGotByClass() {
+ Logger logger = LoggerFactory.getLogger(LoggerFactoryTest.class);
+ verifyLoggerWorks(logger);
+ }
- @Test
- public void testNoOpLoggerByClass() throws Exception {
- Logger logger = LoggerFactory.getLogger(LoggerFactoryTest.class);
- verifyLogger(logger);
- }
+ @Test
+ public void verifyNoOpLoggerWorksWhenGotByName() {
+ Logger logger = LoggerFactory.getLogger(LoggerFactoryTest.class.getName());
+ verifyLoggerWorks(logger);
+ }
- @Test
- public void testNoOpLoggerByName() throws Exception {
- Logger logger = LoggerFactory.getLogger(LoggerFactoryTest.class.getName());
- verifyLogger(logger);
- }
+ @Test(expectedExceptions = NullPointerException.class)
+ public void throwNpeWhenGetByNameWithNull() {
+ LoggerFactory.getLogger((String) null);
+ }
- private void verifyLogger(Logger logger) {
- assertNotNull(logger);
+ @Test(expectedExceptions = NullPointerException.class)
+ public void throwNpeWhenGetByClassWithNull() {
+ LoggerFactory.getLogger((Class<LoggerFactoryTest>) null);
+ }
- // make sure no exceptions are thrown
- logger.error("");
- logger.warn("");
- logger.info("");
- logger.debug("");
- logger.audit("");
- logger.metrics("");
- }
+ private void verifyLoggerWorks(Logger logger) {
+ assertNotNull(logger);
+ // make sure no exceptions are thrown
+ logger.error("");
+ logger.warn("");
+ logger.info("");
+ logger.debug("");
+ logger.audit("");
+ logger.metrics("");
+ }
}
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggingContextTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggingContextTest.java
new file mode 100644
index 0000000000..7899eebd51
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/LoggingContextTest.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright © 2016-2017 European Support Limited
+ *
+ * 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.
+ */
+
+package org.openecomp.sdc.logging.api;
+
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Field;
+import java.util.concurrent.Callable;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * @author EVITALIY
+ * @since 08 Jan 18
+ */
+public class LoggingContextTest {
+
+ @Test
+ public void shouldHoldNoOpWhenNoBinding() throws Exception {
+ Field factory = LoggingContext.class.getDeclaredField("SERVICE");
+ factory.setAccessible(true);
+ Object impl = factory.get(null);
+ assertEquals(impl.getClass().getName(),
+ "org.openecomp.sdc.logging.api.LoggingContext$NoOpLoggingContextService");
+ }
+
+ @Test
+ public void putDoesNotHaveEffectWhenNoBinding() {
+ final String key = "Key";
+ LoggingContext.put(key, "Dummy");
+ assertNull(LoggingContext.get(key));
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void throwNpeWhenPutWithKeyNull() {
+ LoggingContext.put(null, "value");
+ }
+
+ @Test
+ public void getAlwaysReturnsNull() {
+ assertNull(LoggingContext.get("GetKey"));
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void throwNpeWhenGetWithKeyNull() {
+ LoggingContext.get(null);
+ }
+
+ @Test
+ public void removeDoesNotFail() {
+ LoggingContext.remove("RemoveKey");
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void throwNpWhenRemoveWithKeyNull() {
+ LoggingContext.remove(null);
+ }
+
+ @Test
+ public void clearDoesNotFail() {
+ LoggingContext.clear();
+ }
+
+ @Test
+ public void toRunnableReturnsSameInstance() {
+ Runnable test = () -> { /* do nothing */ };
+ assertTrue(test == LoggingContext.toRunnable(test));
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void throwNpeWhenToRunnableWithNull() {
+ LoggingContext.toRunnable(null);
+ }
+
+ @Test
+ public void toCallableReturnsSameInstance() {
+ Callable<String> test = () -> "";
+ assertTrue(test == LoggingContext.toCallable(test));
+ }
+
+ @Test(expectedExceptions = NullPointerException.class)
+ public void throwNpeWhenToCallableWithNull() {
+ LoggingContext.toCallable(null);
+ }
+} \ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/context/ContextPropagationService.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/ServiceBinderTest.java
index 7207ea7610..1a5c81d90d 100644
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/main/java/org/openecomp/sdc/logging/api/context/ContextPropagationService.java
+++ b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/ServiceBinderTest.java
@@ -4,9 +4,9 @@
* 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.
@@ -14,17 +14,25 @@
* limitations under the License.
*/
-package org.openecomp.sdc.logging.api.context;
+package org.openecomp.sdc.logging.api;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
/**
- * Should be used to implement a framework-specific mechanism of propagation of a diagnostic context to child threads.
- *
- * @author evitaliy
- * @since 12/09/2016.
+ * @author EVITALIY
+ * @since 08 Jan 18
*/
+public class ServiceBinderTest {
-@FunctionalInterface
-public interface ContextPropagationService {
+ @Test
+ public void makeSureNoContextServiceBinding() {
+ assertFalse(ServiceBinder.getContextServiceBinding().isPresent());
+ }
- Runnable create(Runnable task);
-}
+ @Test
+ public void makeSureNoCreationServiceBinding() {
+ assertFalse(ServiceBinder.getCreationServiceBinding().isPresent());
+ }
+} \ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/context/TaskFactoryTest.java b/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/context/TaskFactoryTest.java
deleted file mode 100644
index f5c2187024..0000000000
--- a/openecomp-be/lib/openecomp-sdc-logging-lib/openecomp-sdc-logging-api/src/test/java/org/openecomp/sdc/logging/api/context/TaskFactoryTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package org.openecomp.sdc.logging.api.context;
-
-import org.testng.annotations.Test;
-
-import java.util.ServiceLoader;
-
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertTrue;
-
-/**
- * @author evitaliy
- * @since 14/09/2016.
- */
-public class TaskFactoryTest {
-
- @Test(expectedExceptions = RuntimeException.class)
- public void testNoImplementation() throws Exception {
-
- assertFalse(ServiceLoader.load(ContextPropagationService.class).iterator().hasNext());
-
- try {
- TaskFactory.create(() -> {
- });
- } catch (RuntimeException e) {
- Throwable cause = e.getCause();
- assertNotNull(cause);
- assertTrue(cause.getMessage().contains(ContextPropagationService.class.getName()));
- throw e;
- }
- }
-} \ No newline at end of file