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) {