killbill-memoizeit
Changes
osgi-bundles/bundles/logger/pom.xml 93(+93 -0)
osgi-bundles/bundles/logger/src/main/java/com/ning/billing/osgi/bundles/logger/Activator.java 102(+102 -0)
osgi-bundles/bundles/logger/src/main/java/com/ning/billing/osgi/bundles/logger/KillbillLogWriter.java 193(+193 -0)
osgi-bundles/bundles/pom.xml 1(+1 -0)
osgi-bundles/defaultbundles/pom.xml 8(+4 -4)
pom.xml 5(+5 -0)
Details
osgi-bundles/bundles/logger/pom.xml 93(+93 -0)
diff --git a/osgi-bundles/bundles/logger/pom.xml b/osgi-bundles/bundles/logger/pom.xml
new file mode 100644
index 0000000..496394e
--- /dev/null
+++ b/osgi-bundles/bundles/logger/pom.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright 2010-2013 Ning, Inc.
+ ~
+ ~ Ning licenses this file to you 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.
+ -->
+
+<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>com.ning.billing</groupId>
+ <artifactId>killbill-osgi-bundles</artifactId>
+ <version>0.1.56-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>killbill-osgi-bundles-logger</artifactId>
+ <name>Killbill billing platform: OSGI logger bundle</name>
+ <packaging>bundle</packaging>
+ <dependencies>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.compendium</artifactId>
+ </dependency>
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Bundle-Activator>com.ning.billing.osgi.bundles.logger.Activator</Bundle-Activator>
+ <Export-Package></Export-Package>
+ <Private-Package>com.ning.billing.osgi.bundles.logger.*</Private-Package>
+ <!-- Optional resolution because exported by the Felix system bundle -->
+ <Import-Package>*;resolution:=optional</Import-Package>
+ </instructions>
+ </configuration>
+ <executions>
+ <execution>
+ <phase>process-classes</phase>
+ <goals>
+ <goal>manifest</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>assemble-killbill-osgi-bundles-logger</id>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <createSourcesJar>true</createSourcesJar>
+ <shadedArtifactAttached>true</shadedArtifactAttached>
+ <shadedClassifierName>jar-with-dependencies</shadedClassifierName>
+ <filters>
+ <filter>
+ <artifact>${project.groupId}:${project.artifactId}</artifact>
+ </filter>
+ </filters>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/osgi-bundles/bundles/logger/src/main/java/com/ning/billing/osgi/bundles/logger/Activator.java b/osgi-bundles/bundles/logger/src/main/java/com/ning/billing/osgi/bundles/logger/Activator.java
new file mode 100644
index 0000000..7ab3d97
--- /dev/null
+++ b/osgi-bundles/bundles/logger/src/main/java/com/ning/billing/osgi/bundles/logger/Activator.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you 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 com.ning.billing.osgi.bundles.logger;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.log.LogListener;
+import org.osgi.service.log.LogReaderService;
+import org.osgi.util.tracker.ServiceTracker;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Activator implements BundleActivator {
+
+ private static final Logger logger = LoggerFactory.getLogger(Activator.class);
+
+ private final LogListener killbillLogListener = new KillbillLogWriter();
+ private final List<LogReaderService> logReaderServices = new LinkedList<LogReaderService>();
+
+ private final ServiceListener logReaderServiceListener = new ServiceListener() {
+ public void serviceChanged(final ServiceEvent event) {
+ final ServiceReference serviceReference = event.getServiceReference();
+ if (serviceReference == null || serviceReference.getBundle() == null) {
+ return;
+ }
+
+ final BundleContext bundleContext = serviceReference.getBundle().getBundleContext();
+ if (bundleContext == null) {
+ return;
+ }
+
+ final LogReaderService logReaderService = (LogReaderService) bundleContext.getService(serviceReference);
+ if (logReaderService != null) {
+ if (event.getType() == ServiceEvent.REGISTERED) {
+ registerLogReaderService(logReaderService);
+ } else if (event.getType() == ServiceEvent.UNREGISTERING) {
+ logReaderService.removeLogListener(killbillLogListener);
+ logReaderServices.remove(logReaderService);
+ }
+ }
+ }
+ };
+
+ @Override
+ public void start(final BundleContext context) throws Exception {
+ // Get a list of all the registered LogReaderService, and add the killbill listener
+ final ServiceTracker logReaderTracker = new ServiceTracker(context, LogReaderService.class.getName(), null);
+ logReaderTracker.open();
+ final Object[] readers = logReaderTracker.getServices();
+ if (readers != null) {
+ for (final Object reader : readers) {
+ final LogReaderService service = (LogReaderService) reader;
+ registerLogReaderService(service);
+ }
+ }
+ logReaderTracker.close();
+
+ // Add the ServiceListener
+ final String filter = "(objectclass=" + LogReaderService.class.getName() + ")";
+ try {
+ context.addServiceListener(logReaderServiceListener, filter);
+ } catch (InvalidSyntaxException e) {
+ logger.warn("Unable to register the killbill LogReaderService listener", e);
+ }
+ }
+
+ @Override
+ public void stop(final BundleContext context) throws Exception {
+ for (final Iterator<LogReaderService> iterator = logReaderServices.iterator(); iterator.hasNext(); ) {
+ final LogReaderService service = iterator.next();
+ service.removeLogListener(killbillLogListener);
+ iterator.remove();
+ }
+ }
+
+ private void registerLogReaderService(final LogReaderService service) {
+ logReaderServices.add(service);
+ service.addLogListener(killbillLogListener);
+ }
+}
diff --git a/osgi-bundles/bundles/logger/src/main/java/com/ning/billing/osgi/bundles/logger/KillbillLogWriter.java b/osgi-bundles/bundles/logger/src/main/java/com/ning/billing/osgi/bundles/logger/KillbillLogWriter.java
new file mode 100644
index 0000000..eea8293
--- /dev/null
+++ b/osgi-bundles/bundles/logger/src/main/java/com/ning/billing/osgi/bundles/logger/KillbillLogWriter.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright 2010-2013 Ning, Inc.
+ *
+ * Ning licenses this file to you 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 com.ning.billing.osgi.bundles.logger;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.Version;
+import org.osgi.service.log.LogEntry;
+import org.osgi.service.log.LogListener;
+import org.osgi.service.log.LogService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+// Inspired by osgi-over-slf4j
+public class KillbillLogWriter implements LogListener {
+
+ private static final String UNKNOWN = "[Unknown]";
+
+ private final Map<String, Logger> delegates = new HashMap<String, Logger>();
+
+ // Invoked by the log service implementation for each log entry
+ public void logged(final LogEntry entry) {
+ final Bundle bundle = entry.getBundle();
+ final Logger delegate = getDelegateForBundle(bundle);
+
+ final ServiceReference serviceReference = entry.getServiceReference();
+ final int level = entry.getLevel();
+ final String message = entry.getMessage();
+ final Throwable exception = entry.getException();
+
+ if (serviceReference != null && exception != null) {
+ log(delegate, serviceReference, level, message, exception);
+ } else if (serviceReference != null) {
+ log(delegate, serviceReference, level, message);
+ } else if (exception != null) {
+ log(delegate, level, message, exception);
+ } else {
+ log(delegate, level, message);
+ }
+ }
+
+ private Logger getDelegateForBundle(/* @Nullable */ final Bundle bundle) {
+ final String loggerName;
+ if (bundle != null) {
+ final String name = bundle.getSymbolicName();
+ Version version = bundle.getVersion();
+ if (version == null) {
+ version = Version.emptyVersion;
+ }
+ loggerName = name + '.' + version;
+ } else {
+ loggerName = KillbillLogWriter.class.getName();
+ }
+
+ if (delegates.get(loggerName) == null) {
+ synchronized (delegates) {
+ if (delegates.get(loggerName) == null) {
+ delegates.put(loggerName, LoggerFactory.getLogger(loggerName));
+ }
+ }
+ }
+
+ return delegates.get(loggerName);
+ }
+
+ private void log(final Logger delegate, final int level, final String message) {
+ switch (level) {
+ case LogService.LOG_DEBUG:
+ delegate.debug(message);
+ break;
+ case LogService.LOG_ERROR:
+ delegate.error(message);
+ break;
+ case LogService.LOG_INFO:
+ delegate.info(message);
+ break;
+ case LogService.LOG_WARNING:
+ delegate.warn(message);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void log(final Logger delegate, final int level, final String message, final Throwable exception) {
+ switch (level) {
+ case LogService.LOG_DEBUG:
+ delegate.debug(message, exception);
+ break;
+ case LogService.LOG_ERROR:
+ delegate.error(message, exception);
+ break;
+ case LogService.LOG_INFO:
+ delegate.info(message, exception);
+ break;
+ case LogService.LOG_WARNING:
+ delegate.warn(message, exception);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void log(final Logger delegate, final ServiceReference sr, final int level, final String message) {
+ switch (level) {
+ case LogService.LOG_DEBUG:
+ if (delegate.isDebugEnabled()) {
+ delegate.debug(createMessage(sr, message));
+ }
+ break;
+ case LogService.LOG_ERROR:
+ if (delegate.isErrorEnabled()) {
+ delegate.error(createMessage(sr, message));
+ }
+ break;
+ case LogService.LOG_INFO:
+ if (delegate.isInfoEnabled()) {
+ delegate.info(createMessage(sr, message));
+ }
+ break;
+ case LogService.LOG_WARNING:
+ if (delegate.isWarnEnabled()) {
+ delegate.warn(createMessage(sr, message));
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void log(final Logger delegate, final ServiceReference sr, final int level, final String message, final Throwable exception) {
+ switch (level) {
+ case LogService.LOG_DEBUG:
+ if (delegate.isDebugEnabled()) {
+ delegate.debug(createMessage(sr, message), exception);
+ }
+ break;
+ case LogService.LOG_ERROR:
+ if (delegate.isErrorEnabled()) {
+ delegate.error(createMessage(sr, message), exception);
+ }
+ break;
+ case LogService.LOG_INFO:
+ if (delegate.isInfoEnabled()) {
+ delegate.info(createMessage(sr, message), exception);
+ }
+ break;
+ case LogService.LOG_WARNING:
+ if (delegate.isWarnEnabled()) {
+ delegate.warn(createMessage(sr, message), exception);
+ }
+ 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(final ServiceReference sr, final String message) {
+ final StringBuilder output = new StringBuilder();
+ if (sr != null) {
+ output.append('[').append(sr.toString()).append(']');
+ } else {
+ output.append(UNKNOWN);
+ }
+ output.append(message);
+
+ return output.toString();
+ }
+}
osgi-bundles/bundles/pom.xml 1(+1 -0)
diff --git a/osgi-bundles/bundles/pom.xml b/osgi-bundles/bundles/pom.xml
index eaeeee5..ddb3703 100644
--- a/osgi-bundles/bundles/pom.xml
+++ b/osgi-bundles/bundles/pom.xml
@@ -28,6 +28,7 @@
<packaging>pom</packaging>
<modules>
<module>jruby</module>
+ <module>logger</module>
<module>meter</module>
<module>webconsolebranding</module>
</modules>
osgi-bundles/defaultbundles/pom.xml 8(+4 -4)
diff --git a/osgi-bundles/defaultbundles/pom.xml b/osgi-bundles/defaultbundles/pom.xml
index ee54038..ec98490 100644
--- a/osgi-bundles/defaultbundles/pom.xml
+++ b/osgi-bundles/defaultbundles/pom.xml
@@ -34,6 +34,10 @@
</dependency>
<dependency>
<groupId>com.ning.billing</groupId>
+ <artifactId>killbill-osgi-bundles-logger</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.ning.billing</groupId>
<artifactId>killbill-osgi-bundles-webconsolebranding</artifactId>
</dependency>
<dependency>
@@ -126,10 +130,6 @@
<artifactId>org.apache.felix.webconsole</artifactId>
<version>3.1.8</version>
</dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>osgi-over-slf4j</artifactId>
- </dependency>
</dependencies>
<build>
<plugins>
pom.xml 5(+5 -0)
diff --git a/pom.xml b/pom.xml
index 4ba75e5..3e80817 100644
--- a/pom.xml
+++ b/pom.xml
@@ -286,6 +286,11 @@
</dependency>
<dependency>
<groupId>com.ning.billing</groupId>
+ <artifactId>killbill-osgi-bundles-logger</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>com.ning.billing</groupId>
<artifactId>killbill-osgi-bundles-test-beatrix</artifactId>
<version>${project.version}</version>
</dependency>