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/05/03 18:27:42 UTC
svn commit: r1478866 - in
/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins:
observation/ observation2/
Author: jukka
Date: Fri May 3 16:27:41 2013
New Revision: 1478866
URL: http://svn.apache.org/r1478866
Log:
OAK-144: Implement observation
Track which parts of observation events are being accessed and log warnings accordingly
Modified:
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/observation2/EventCollector.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation2/EventImpl.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation2/EventQueueReader.java
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=1478866&r1=1478865&r2=1478866&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 Fri May 3 16:27:41 2013
@@ -42,13 +42,19 @@ import org.apache.jackrabbit.oak.spi.sta
import org.apache.jackrabbit.oak.util.TODO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
/**
* TODO document
*/
class ChangeProcessor implements Runnable {
- private static final Logger log = LoggerFactory.getLogger(ChangeProcessor.class);
+ private static final Logger log =
+ LoggerFactory.getLogger(ChangeProcessor.class);
+
+ private static final Marker DEPRECATED =
+ MarkerFactory.getMarker("deprecated");
private static final String DUMMY_USER_ID = TODO.dummyImplementation().returnValueOrNull("oak:unknown");
private final ObservationManagerImpl observationManager;
@@ -60,6 +66,12 @@ class ChangeProcessor implements Runnabl
private volatile boolean stopping;
private ScheduledFuture<?> future;
+ private boolean userIDAccessed = false;
+ private boolean userDataAccessed = false;
+ private boolean isExternalAccessed = false;
+ private boolean userInfoAccessedWithoutExternalsCheck = false;
+ private boolean userInfoAccessedFromExternalEvent = false;
+
public ChangeProcessor(ObservationManagerImpl observationManager, EventListener listener, ChangeFilter filter) {
this.observationManager = observationManager;
this.namePathMapper = observationManager.getNamePathMapper();
@@ -128,6 +140,37 @@ class ChangeProcessor implements Runnabl
}
}
+ synchronized void userIDAccessed() {
+ userIDAccessed = true;
+ }
+
+ synchronized void userDataAccessed() {
+ userDataAccessed = true;
+ }
+
+ synchronized void externalAccessed() {
+ isExternalAccessed = true;
+ }
+
+ synchronized void userInfoAccessedWithoutExternalCheck() {
+ if (!userInfoAccessedWithoutExternalsCheck) {
+ log.warn(DEPRECATED,
+ "Event listener " + listener + " is trying to access"
+ + " event user information without checking for whether"
+ + " the event is external");
+ userInfoAccessedWithoutExternalsCheck = true;
+ }
+ }
+
+ synchronized void userInfoAccessedFromExternalEvent() {
+ if (!userInfoAccessedFromExternalEvent) {
+ log.warn(DEPRECATED,
+ "Event listener " + listener + " is trying to access"
+ + " event user information from an external event");
+ userInfoAccessedFromExternalEvent = true;
+ }
+ }
+
//------------------------------------------------------------< private >---
private class EventGeneratingNodeStateDiff implements NodeStateDiff {
@@ -240,7 +283,7 @@ class ChangeProcessor implements Runnabl
String jcrPath = namePathMapper.getJcrPath(PathUtils.concat(parentPath, property.getName()));
// TODO support userId, identifier, info, date
- return new EventImpl(eventType, jcrPath, DUMMY_USER_ID, null, null, 0);
+ return new EventImpl(ChangeProcessor.this, eventType, jcrPath, DUMMY_USER_ID, null, null, 0, null, false);
}
private Iterator<Event> generateNodeEvents(int eventType, String parentPath, String name, NodeState node) {
@@ -252,7 +295,7 @@ class ChangeProcessor implements Runnabl
Iterator<Event> nodeEvent;
if (filter.include(eventType, jcrParentPath, associatedParentNode)) {
// TODO support userId, identifier, info, date
- Event event = new EventImpl(eventType, jcrPath, DUMMY_USER_ID, null, null, 0);
+ Event event = new EventImpl(ChangeProcessor.this, eventType, jcrPath, DUMMY_USER_ID, null, null, 0, null, false);
nodeEvent = Iterators.singletonIterator(event);
} else {
nodeEvent = Iterators.emptyIterator();
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=1478866&r1=1478865&r2=1478866&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 Fri May 3 16:27:41 2013
@@ -1,18 +1,20 @@
/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF 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
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF 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
+ * 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.
+ * 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.apache.jackrabbit.oak.plugins.observation;
@@ -20,18 +22,16 @@ import java.util.Collections;
import java.util.Map;
import javax.jcr.RepositoryException;
-import javax.jcr.UnsupportedRepositoryOperationException;
-import javax.jcr.observation.Event;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.slf4j.MarkerFactory;
+import org.apache.jackrabbit.api.observation.JackrabbitEvent;
/**
* TODO document
*/
-public class EventImpl implements Event {
- private static final Logger log = LoggerFactory.getLogger(EventImpl.class);
+public class EventImpl implements JackrabbitEvent {
+
+ private final ChangeProcessor collector;
+ private boolean externalAccessed = false;
private final int type;
private final String path;
@@ -39,14 +39,22 @@ public class EventImpl implements Event
private final String identifier;
private final Map<?, ?> info;
private final long date;
+ private final String userData;
+ private final boolean external;
- public EventImpl(int type, String path, String userID, String identifier, Map<?, ?> info, long date) {
+ public EventImpl(
+ ChangeProcessor collector,
+ int type, String path, String userID, String identifier,
+ Map<?, ?> info, long date, String userData, boolean external) {
+ this.collector = collector;
this.type = type;
this.path = path;
this.userID = userID;
this.identifier = identifier;
this.info = info == null ? Collections.emptyMap() : info;
this.date = date;
+ this.userData = userData;
+ this.external = external;
}
@Override
@@ -60,8 +68,14 @@ public class EventImpl implements Event
}
@Override
- public String getUserID() {
- log.warn(MarkerFactory.getMarker("deprecation"), "Call to deprecated method getUserId");
+ public synchronized String getUserID() {
+ if (!externalAccessed) {
+ collector.userInfoAccessedWithoutExternalCheck();
+ }
+ if (external) {
+ collector.userInfoAccessedFromExternalEvent();
+ }
+ collector.userIDAccessed();
return userID;
}
@@ -77,8 +91,14 @@ public class EventImpl implements Event
@Override
public String getUserData() throws RepositoryException {
- log.warn(MarkerFactory.getMarker("deprecation"), "Call to deprecated method getUserData");
- throw new UnsupportedRepositoryOperationException("User data not supported");
+ if (!externalAccessed) {
+ collector.userInfoAccessedWithoutExternalCheck();
+ }
+ if (external) {
+ collector.userInfoAccessedFromExternalEvent();
+ }
+ collector.userDataAccessed();
+ return userData;
}
@Override
@@ -87,6 +107,13 @@ public class EventImpl implements Event
}
@Override
+ public synchronized boolean isExternal() {
+ externalAccessed = true;
+ collector.externalAccessed();
+ return external;
+ }
+
+ @Override
public final boolean equals(Object other) {
if (this == other) {
return true;
@@ -100,7 +127,9 @@ public class EventImpl implements Event
(identifier == null ? that.identifier == null : identifier.equals(that.identifier)) &&
(info == null ? that.info == null : info.equals(that.info)) &&
(path == null ? that.path == null : path.equals(that.path)) &&
- (userID == null ? that.userID == null : userID.equals(that.userID));
+ (userID == null ? that.userID == null : userID.equals(that.userID)) &&
+ (userData == null ? that.userData == null : userData.equals(that.userData)) &&
+ external == that.external;
}
@@ -112,6 +141,7 @@ public class EventImpl implements Event
result = 31 * result + (identifier == null ? 0 : identifier.hashCode());
result = 31 * result + (info == null ? 0 : info.hashCode());
result = 31 * result + (int) (date ^ (date >>> 32));
+ result = 31 * result + (userData == null ? 0 : userData.hashCode());
return result;
}
@@ -124,6 +154,9 @@ public class EventImpl implements Event
", identifier='" + identifier + '\'' +
", info=" + info +
", date=" + date +
+ ", userData=" + userData +
+ ", external=" + external +
'}';
}
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation2/EventCollector.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation2/EventCollector.java?rev=1478866&r1=1478865&r2=1478866&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation2/EventCollector.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation2/EventCollector.java Fri May 3 16:27:41 2013
@@ -42,13 +42,20 @@ import org.apache.jackrabbit.oak.api.Roo
import org.apache.jackrabbit.oak.api.Tree;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
/**
* TODO document
* FIXME this implementation needs read/write access to /jcr:system/rep:observation
*/
class EventCollector implements Runnable {
- private static final Logger log = LoggerFactory.getLogger(EventCollector.class);
+
+ private static final Logger log =
+ LoggerFactory.getLogger(EventCollector.class);
+
+ private static final Marker DEPRECATED =
+ MarkerFactory.getMarker("deprecated");
private final ObservationManagerImpl2 observationManager;
private final EventQueueReader eventQueueReader;
@@ -57,6 +64,12 @@ class EventCollector implements Runnable
private ScheduledFuture<?> future;
private String id;
+ private boolean userIDAccessed = false;
+ private boolean userDataAccessed = false;
+ private boolean isExternalAccessed = false;
+ private boolean userInfoAccessedWithoutExternalsCheck = false;
+ private boolean userInfoAccessedFromExternalEvent = false;
+
public EventCollector(ObservationManagerImpl2 observationManager, EventListener listener, EventFilter filter)
throws CommitFailedException {
this.observationManager = observationManager;
@@ -120,7 +133,8 @@ class EventCollector implements Runnable
public void run() {
running = true;
try {
- Iterator<Event> bundle = eventQueueReader.getEventBundle(getId());
+ Iterator<Event> bundle =
+ eventQueueReader.getEventBundle(this, getId());
// FIXME filter by session specific access restrictions
if (bundle != null) {
observationManager.setHasEvents();
@@ -136,6 +150,37 @@ class EventCollector implements Runnable
}
}
+ synchronized void userIDAccessed() {
+ userIDAccessed = true;
+ }
+
+ synchronized void userDataAccessed() {
+ userDataAccessed = true;
+ }
+
+ synchronized void externalAccessed() {
+ isExternalAccessed = true;
+ }
+
+ synchronized void userInfoAccessedWithoutExternalCheck() {
+ if (!userInfoAccessedWithoutExternalsCheck) {
+ log.warn(DEPRECATED,
+ "Event listener " + listener + " is trying to access"
+ + " event user information without checking for whether"
+ + " the event is external");
+ userInfoAccessedWithoutExternalsCheck = true;
+ }
+ }
+
+ synchronized void userInfoAccessedFromExternalEvent() {
+ if (!userInfoAccessedFromExternalEvent) {
+ log.warn(DEPRECATED,
+ "Event listener " + listener + " is trying to access"
+ + " event user information from an external event");
+ userInfoAccessedFromExternalEvent = true;
+ }
+ }
+
//------------------------------------------------------------< private >---
private String getId() {
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation2/EventImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation2/EventImpl.java?rev=1478866&r1=1478865&r2=1478866&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation2/EventImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation2/EventImpl.java Fri May 3 16:27:41 2013
@@ -22,17 +22,16 @@ import java.util.Collections;
import java.util.Map;
import javax.jcr.RepositoryException;
-import javax.jcr.observation.Event;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.slf4j.MarkerFactory;
+import org.apache.jackrabbit.api.observation.JackrabbitEvent;
/**
* TODO document
*/
-public class EventImpl implements Event {
- private static final Logger log = LoggerFactory.getLogger(EventImpl.class);
+public class EventImpl implements JackrabbitEvent {
+
+ private final EventCollector collector;
+ private boolean externalAccessed = false;
private final int type;
private final String path;
@@ -41,8 +40,13 @@ public class EventImpl implements Event
private final Map<?, ?> info;
private final long date;
private final String userData;
+ private final boolean external;
- public EventImpl(int type, String path, String userID, String identifier, Map<?, ?> info, long date, String userData) {
+ public EventImpl(
+ EventCollector collector,
+ int type, String path, String userID, String identifier,
+ Map<?, ?> info, long date, String userData, boolean external) {
+ this.collector = collector;
this.type = type;
this.path = path;
this.userID = userID;
@@ -50,6 +54,7 @@ public class EventImpl implements Event
this.info = info == null ? Collections.emptyMap() : info;
this.date = date;
this.userData = userData;
+ this.external = external;
}
@Override
@@ -63,8 +68,14 @@ public class EventImpl implements Event
}
@Override
- public String getUserID() {
- log.warn(MarkerFactory.getMarker("deprecation"), "Call to deprecated method getUserId");
+ public synchronized String getUserID() {
+ if (!externalAccessed) {
+ collector.userInfoAccessedWithoutExternalCheck();
+ }
+ if (external) {
+ collector.userInfoAccessedFromExternalEvent();
+ }
+ collector.userIDAccessed();
return userID;
}
@@ -80,7 +91,13 @@ public class EventImpl implements Event
@Override
public String getUserData() throws RepositoryException {
- log.warn(MarkerFactory.getMarker("deprecation"), "Call to deprecated method getUserData");
+ if (!externalAccessed) {
+ collector.userInfoAccessedWithoutExternalCheck();
+ }
+ if (external) {
+ collector.userInfoAccessedFromExternalEvent();
+ }
+ collector.userDataAccessed();
return userData;
}
@@ -90,6 +107,13 @@ public class EventImpl implements Event
}
@Override
+ public synchronized boolean isExternal() {
+ externalAccessed = true;
+ collector.externalAccessed();
+ return external;
+ }
+
+ @Override
public final boolean equals(Object other) {
if (this == other) {
return true;
@@ -104,7 +128,8 @@ public class EventImpl implements Event
(info == null ? that.info == null : info.equals(that.info)) &&
(path == null ? that.path == null : path.equals(that.path)) &&
(userID == null ? that.userID == null : userID.equals(that.userID)) &&
- (userData == null ? that.userData == null : userData.equals(that.userData));
+ (userData == null ? that.userData == null : userData.equals(that.userData)) &&
+ external == that.external;
}
@@ -130,6 +155,8 @@ public class EventImpl implements Event
", info=" + info +
", date=" + date +
", userData=" + userData +
+ ", external=" + external +
'}';
}
+
}
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation2/EventQueueReader.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation2/EventQueueReader.java?rev=1478866&r1=1478865&r2=1478866&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation2/EventQueueReader.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/observation2/EventQueueReader.java Fri May 3 16:27:41 2013
@@ -55,7 +55,8 @@ public class EventQueueReader {
this.namePathMapper = namePathMapper;
}
- public Iterator<Event> getEventBundle(final String id) {
+ public Iterator<Event> getEventBundle(
+ final EventCollector collector, final String id) {
root.refresh();
Iterator<Tree> events = getEvents(nextBundleId, id);
@@ -66,7 +67,7 @@ public class EventQueueReader {
return Iterators.transform(events, new Function<Tree, Event>() {
@Override
public Event apply(Tree event) {
- return createEvent(event, id);
+ return createEvent(collector, event, id);
}
});
}
@@ -92,13 +93,15 @@ public class EventQueueReader {
return null;
}
- private Event createEvent(Tree event, String id) {
+ private Event createEvent(EventCollector collector, Tree event, String id) {
int type = (int) getLong(event, TYPE, 0);
String path = getJcrPath(event);
String userId = getString(event.getChild(id), USER_ID);
long date = getLong(event, DATE, 0);
String userData = getString(event.getChild(id), USER_DATA);
- return new EventImpl(type, path, userId, id, Collections.emptyMap(), date, userData);
+ return new EventImpl(
+ collector, type, path, userId, id, Collections.emptyMap(),
+ date, userData, false);
}
private String getJcrPath(Tree event) {