You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by ju...@apache.org on 2013/06/17 07:53:35 UTC
svn commit: r1493647 - in
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak: ./
plugins/observation/ spi/whiteboard/
Author: jukka
Date: Mon Jun 17 05:53:34 2013
New Revision: 1493647
URL: http://svn.apache.org/r1493647
Log:
OAK-804: MBean to track observation listeners
Add listener MBeans based on the work in JCR-3608
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ObservationManagerImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/whiteboard/WhiteboardUtils.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java?rev=1493647&r1=1493646&r2=1493647&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/Oak.java Mon Jun 17 05:53:34 2013
@@ -29,6 +29,9 @@ import java.util.concurrent.TimeUnit;
import javax.annotation.Nonnull;
import javax.jcr.NoSuchWorkspaceException;
+import javax.management.JMException;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
import javax.security.auth.login.LoginException;
import com.google.common.base.Function;
@@ -100,6 +103,8 @@ public class Oak {
private ScheduledExecutorService executor = newScheduledThreadPool(0);
+ private MBeanServer mbeanServer;
+
private String defaultWorkspaceName = DEFAULT_WORKSPACE_NAME;
@SuppressWarnings("unchecked")
@@ -128,7 +133,6 @@ public class Oak {
Long period =
getValue(properties, "scheduler.period", Long.class);
if (period != null) {
-
Boolean concurrent = getValue(
properties, "scheduler.concurrent",
Boolean.class, Boolean.FALSE);
@@ -142,13 +146,36 @@ public class Oak {
}
}
+ ObjectName objectName = null;
+ Object name = properties.get("jmx.objectname");
+ if (mbeanServer != null && name != null) {
+ try {
+ if (name instanceof ObjectName) {
+ objectName = (ObjectName) name;
+ } else {
+ objectName = new ObjectName(String.valueOf(name));
+ }
+ mbeanServer.registerMBean(service, objectName);
+ } catch (JMException e) {
+ // ignore
+ }
+ }
+
final Future<?> f = future;
+ final ObjectName on = objectName;
return new Registration() {
@Override
public void unregister() {
if (f != null) {
f.cancel(false);
}
+ if (on != null) {
+ try {
+ mbeanServer.unregisterMBean(on);
+ } catch (JMException e) {
+ // ignore
+ }
+ }
}
};
}
@@ -308,6 +335,12 @@ public class Oak {
}
@Nonnull
+ public Oak with(@Nonnull MBeanServer mbeanServer) {
+ this.mbeanServer = mbeanServer;
+ return this;
+ }
+
+ @Nonnull
public Oak with(@Nonnull Whiteboard whiteboard) {
this.whiteboard = whiteboard;
return this;
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java?rev=1493647&r1=1493646&r2=1493647&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ChangeProcessor.java Mon Jun 17 05:53:34 2013
@@ -33,7 +33,9 @@ import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterators;
import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.api.jmx.EventListenerMBean;
import org.apache.jackrabbit.commons.iterator.EventIteratorAdapter;
+import org.apache.jackrabbit.commons.observation.ListenerTracker;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.commons.PathUtils;
@@ -49,39 +51,37 @@ import org.apache.jackrabbit.oak.spi.whi
import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.slf4j.Marker;
-import org.slf4j.MarkerFactory;
class ChangeProcessor implements Runnable {
- private static final Logger log = LoggerFactory.getLogger(ChangeProcessor.class);
- private static final Marker DEPRECATED = MarkerFactory.getMarker("deprecated");
+
+ private static final Logger log =
+ LoggerFactory.getLogger(ChangeProcessor.class);
private final ObservationManagerImpl observationManager;
private final NamePathMapper namePathMapper;
- private final EventListener listener;
private final AtomicReference<EventFilter> filterRef;
private final AtomicReference<String> userDataRef = new AtomicReference<String>(null);
- private final Exception initStacktrace;
+ private final ListenerTracker tracker;
+ private final EventListener listener;
private volatile Thread running = null;
private volatile boolean stopping = false;
private Runnable deferredUnregister;
- private Registration registration;
+ private Registration runnable;
+ private Registration mbean;
private Listener changeListener;
- private boolean userInfoAccessedWithoutExternalsCheck;
- private boolean userInfoAccessedFromExternalEvent;
- private boolean dateAccessedWithoutExternalsCheck;
- private boolean dateAccessedFromExternalEvent;
-
- public ChangeProcessor(ObservationManagerImpl observationManager, EventListener listener, EventFilter filter) {
+ public ChangeProcessor(
+ ObservationManagerImpl observationManager,
+ ListenerTracker tracker,
+ EventFilter filter) {
this.observationManager = observationManager;
this.namePathMapper = observationManager.getNamePathMapper();
- this.listener = listener;
+ this.tracker = tracker;
+ this.listener = tracker.getTrackedListener();
filterRef = new AtomicReference<EventFilter>(filter);
- initStacktrace = log.isWarnEnabled(DEPRECATED) ? new Exception("Initialized here") : null;
}
public void setFilter(EventFilter filter) {
@@ -98,12 +98,14 @@ class ChangeProcessor implements Runnabl
* @throws IllegalStateException if started already
*/
public synchronized void start(Whiteboard whiteboard) {
- checkState(registration == null, "Change processor started already");
+ checkState(runnable == null, "Change processor started already");
stopping = false;
changeListener = observationManager.newChangeListener();
- registration =
- WhiteboardUtils.scheduleWithFixedDelay(whiteboard, this, 1);
+ runnable = WhiteboardUtils.scheduleWithFixedDelay(whiteboard, this, 1);
+ mbean = WhiteboardUtils.registerMBean(
+ whiteboard, EventListenerMBean.class, tracker.getListenerMBean(),
+ "ObservationListener", tracker.toString());
}
/**
@@ -140,9 +142,10 @@ class ChangeProcessor implements Runnabl
}
private void unregister() {
- checkState(registration != null, "Change processor not started");
+ checkState(runnable != null, "Change processor not started");
+ mbean.unregister();
+ runnable.unregister();
changeListener.dispose();
- registration.unregister();
}
@Override
@@ -177,48 +180,6 @@ class ChangeProcessor implements Runnabl
}
}
- synchronized void userInfoAccessedWithoutExternalCheck(Event event) {
- if (!userInfoAccessedWithoutExternalsCheck) {
- log.warn(DEPRECATED,
- "Event listener " + listener + " is trying to access"
- + " event user information on event " + event
- + " without checking whether the event is external."
- + " The event listener was registered here: ", initStacktrace);
- userInfoAccessedWithoutExternalsCheck = true;
- }
- }
-
- synchronized void userInfoAccessedFromExternalEvent(Event event) {
- if (!userInfoAccessedFromExternalEvent) {
- log.warn(DEPRECATED,
- "Event listener " + listener + " is trying to access"
- + " event user information for external event " + event + '.'
- + " The event listener was registered here: ", initStacktrace);
- userInfoAccessedFromExternalEvent = true;
- }
- }
-
- synchronized void dateAccessedWithoutExternalCheck(Event event) {
- if (!dateAccessedWithoutExternalsCheck) {
- log.warn(DEPRECATED,
- "Event listener " + listener + " is trying to access"
- + " event date information on event " + event
- + " without checking whether the event is external."
- + " The event listener was registered here: ", initStacktrace);
- dateAccessedWithoutExternalsCheck = true;
- }
- }
-
- synchronized void dateAccessedFromExternalEvent(Event event) {
- if (!dateAccessedFromExternalEvent) {
- log.warn(DEPRECATED,
- "Event listener " + listener + " is trying to access"
- + " event date information for external event " + event + '.'
- + " The event listener was registered here: ", initStacktrace);
- dateAccessedFromExternalEvent = true;
- }
- }
-
//------------------------------------------------------------< private >---
private class EventGeneratingNodeStateDiff extends RecursingNodeStateDiff {
@@ -339,8 +300,10 @@ class ChangeProcessor implements Runnabl
private EventImpl createEvent(int eventType, String jcrPath, String id) {
// TODO support info
- return new EventImpl(ChangeProcessor.this, eventType, jcrPath, changes.getUserId(),
- id, null, changes.getDate(), userDataRef.get(), changes.isExternal());
+ return new EventImpl(
+ eventType, jcrPath, changes.getUserId(),
+ id, null, changes.getDate(), userDataRef.get(),
+ changes.isExternal());
}
private String getRootId() {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventImpl.java?rev=1493647&r1=1493646&r2=1493647&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/EventImpl.java Mon Jun 17 05:53:34 2013
@@ -30,8 +30,6 @@ import org.apache.jackrabbit.api.observa
* TODO document
*/
public class EventImpl implements JackrabbitEvent {
- private final ChangeProcessor collector;
- private boolean externalAccessed;
private final int type;
private final String path;
@@ -43,10 +41,8 @@ public class EventImpl implements Jackra
private final boolean external;
public EventImpl(
- ChangeProcessor processor,
int type, String path, String userID, String identifier,
Map<?, ?> info, long date, String userData, boolean external) {
- this.collector = processor;
this.type = type;
this.path = path;
this.userID = userID;
@@ -68,51 +64,32 @@ public class EventImpl implements Jackra
}
@Override
- public synchronized String getUserID() {
- if (!externalAccessed) {
- collector.userInfoAccessedWithoutExternalCheck(this);
- }
- if (external) {
- collector.userInfoAccessedFromExternalEvent(this);
- }
+ public String getUserID() {
return userID;
}
@Override
- public String getIdentifier() throws RepositoryException {
+ public String getIdentifier() {
return identifier;
}
@Override
- public Map<?, ?> getInfo() throws RepositoryException {
+ public Map<?, ?> getInfo() {
return info;
}
@Override
- public String getUserData() throws RepositoryException {
- if (!externalAccessed) {
- collector.userInfoAccessedWithoutExternalCheck(this);
- }
- if (external) {
- collector.userInfoAccessedFromExternalEvent(this);
- }
+ public String getUserData() {
return userData;
}
@Override
- public long getDate() throws RepositoryException {
- if (!externalAccessed) {
- collector.dateAccessedWithoutExternalCheck(this);
- }
- if (external) {
- collector.dateAccessedFromExternalEvent(this);
- }
+ public long getDate() {
return date;
}
@Override
public synchronized boolean isExternal() {
- externalAccessed = true;
return external;
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ObservationManagerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ObservationManagerImpl.java?rev=1493647&r1=1493646&r2=1493647&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ObservationManagerImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation/ObservationManagerImpl.java Mon Jun 17 05:53:34 2013
@@ -35,6 +35,7 @@ import javax.jcr.observation.Observation
import com.google.common.base.Preconditions;
import org.apache.jackrabbit.commons.iterator.EventListenerIteratorAdapter;
+import org.apache.jackrabbit.commons.observation.ListenerTracker;
import org.apache.jackrabbit.oak.api.ContentSession;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
import org.apache.jackrabbit.oak.plugins.nodetype.ReadOnlyNodeTypeManager;
@@ -47,7 +48,12 @@ import org.slf4j.MarkerFactory;
public class ObservationManagerImpl implements ObservationManager {
private static final Logger log = LoggerFactory.getLogger(ObservationManagerImpl.class);
- public static final Marker OBSERVATION = MarkerFactory.getMarker("observation");
+
+ public static final Marker OBSERVATION =
+ MarkerFactory.getMarker("observation");
+
+ private static final Marker DEPRECATED =
+ MarkerFactory.getMarker("deprecated");
private final Map<EventListener, ChangeProcessor> processors = new HashMap<EventListener, ChangeProcessor>();
private final AtomicBoolean hasEvents = new AtomicBoolean(false);
@@ -96,8 +102,16 @@ public class ObservationManagerImpl impl
absPath, isDeep, uuid, nodeTypeName, noLocal);
ChangeProcessor processor = processors.get(listener);
if (processor == null) {
- log.error(OBSERVATION, "Registering event listener {} with filter {}", listener, filter);
- processor = new ChangeProcessor(this, listener, filter);
+ log.info(OBSERVATION, "Registering event listener {} with filter {}", listener, filter);
+ ListenerTracker tracker = new ListenerTracker(
+ listener, eventTypes, absPath, isDeep,
+ uuid, nodeTypeName, noLocal) {
+ @Override
+ protected void warn(String message) {
+ log.warn(DEPRECATED, message, initStackTrace);
+ }
+ };
+ processor = new ChangeProcessor(this, tracker, filter);
processors.put(listener, processor);
processor.start(whiteboard);
} else {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/whiteboard/WhiteboardUtils.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/whiteboard/WhiteboardUtils.java?rev=1493647&r1=1493646&r2=1493647&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/whiteboard/WhiteboardUtils.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/whiteboard/WhiteboardUtils.java Mon Jun 17 05:53:34 2013
@@ -16,10 +16,18 @@
*/
package org.apache.jackrabbit.oak.spi.whiteboard;
+import java.util.Hashtable;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
import com.google.common.collect.ImmutableMap;
public class WhiteboardUtils {
+ private static final AtomicLong COUNTER = new AtomicLong();
+
public static Registration scheduleWithFixedDelay(
Whiteboard whiteboard, Runnable runnable, long delay) {
return whiteboard.register(
@@ -29,4 +37,20 @@ public class WhiteboardUtils {
.build());
}
+ public static <T> Registration registerMBean(
+ Whiteboard whiteboard,
+ Class<T> iface, T bean, String type, String name) {
+ try {
+ Hashtable<String, String> table = new Hashtable<String, String>();
+ table.put("type", type);
+ table.put("name", name);
+ table.put("id", String.valueOf(COUNTER.incrementAndGet()));
+ return whiteboard.register(iface, bean, ImmutableMap.of(
+ "jmx.objectname",
+ new ObjectName("org.apache.jackrabbit.oak", table)));
+ } catch (MalformedObjectNameException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
}