Search in sources :

Example 11 with EventIterator

use of javax.jcr.observation.EventIterator in project jackrabbit by apache.

the class Locked method with.

/**
 * Executes the method {@link #run} within the scope of a lock held on
 * <code>lockable</code>.
 *
 * @param lockable the node where the lock is obtained from.
 * @param isDeep   <code>true</code> if <code>lockable</code> will be locked
 *                 deep.
 * @param timeout  time in milliseconds to wait at most to acquire the lock.
 * @param isSessionScoped <code>true</code> if the lock is session scoped.
 * @return the object returned by {@link #run} or {@link #TIMED_OUT} if the
 *         lock on <code>lockable</code> could not be acquired within the
 *         specified timeout.
 * @throws IllegalArgumentException if <code>timeout</code> is negative or
 *                                  <code>lockable</code> is not
 *                                  <i>mix:lockable</i>.
 * @throws RepositoryException      if {@link #run} throws an exception.
 * @throws UnsupportedRepositoryOperationException
 *                                  if this repository does not support
 *                                  locking.
 * @throws InterruptedException     if this thread is interrupted while
 *                                  waiting for the lock on node
 *                                  <code>lockable</code>.
 */
public Object with(Node lockable, boolean isDeep, long timeout, boolean isSessionScoped) throws UnsupportedRepositoryOperationException, RepositoryException, InterruptedException {
    if (timeout < 0) {
        throw new IllegalArgumentException("timeout must be >= 0");
    }
    Session session = lockable.getSession();
    EventListener listener = null;
    try {
        // check whether the lockable can be locked at all
        String mix = session.getNamespacePrefix(MIX);
        if (!lockable.isNodeType(mix + ":lockable")) {
            throw new IllegalArgumentException("Node is not lockable");
        }
        Lock lock = tryLock(lockable, isDeep, timeout, isSessionScoped);
        if (lock != null) {
            return runAndUnlock(lock);
        }
        if (timeout == 0) {
            return TIMED_OUT;
        }
        long timelimit;
        if (timeout == Long.MAX_VALUE) {
            timelimit = Long.MAX_VALUE;
        } else {
            timelimit = System.currentTimeMillis() + timeout;
        }
        // node is locked by other session -> register event listener if possible
        if (isObservationSupported(session)) {
            ObservationManager om = session.getWorkspace().getObservationManager();
            listener = new EventListener() {

                public void onEvent(EventIterator events) {
                    synchronized (Locked.this) {
                        Locked.this.notify();
                    }
                }
            };
            om.addEventListener(listener, Event.PROPERTY_REMOVED, lockable.getPath(), false, null, null, true);
        }
        // the current thread when the lockable node is possibly unlocked
        for (; ; ) {
            synchronized (this) {
                lock = tryLock(lockable, isDeep, timeout, isSessionScoped);
                if (lock != null) {
                    return runAndUnlock(lock);
                } else {
                    // check timeout
                    if (System.currentTimeMillis() > timelimit) {
                        return TIMED_OUT;
                    }
                    if (listener != null) {
                        // event listener *should* wake us up, however
                        // there is a chance that removal of the lockOwner
                        // property is notified before the node is acutally
                        // unlocked. therefore we use a safety net to wait
                        // at most 1000 millis.
                        this.wait(Math.min(1000, timeout));
                    } else {
                        // repository does not support observation
                        // wait at most 50 millis then retry
                        this.wait(Math.min(50, timeout));
                    }
                }
            }
        }
    } finally {
        if (listener != null) {
            session.getWorkspace().getObservationManager().removeEventListener(listener);
        }
    }
}
Also used : ObservationManager(javax.jcr.observation.ObservationManager) EventListener(javax.jcr.observation.EventListener) EventIterator(javax.jcr.observation.EventIterator) Session(javax.jcr.Session) Lock(javax.jcr.lock.Lock)

Example 12 with EventIterator

use of javax.jcr.observation.EventIterator in project jackrabbit by apache.

the class CachingHierarchyManagerConsistencyTest method testObservation.

public void testObservation() throws Exception {
    final List<Exception> exceptions = new ArrayList<Exception>();
    Thread writer = new Thread(new Runnable() {

        public void run() {
            try {
                long end = System.currentTimeMillis() + TEST_DURATION * 1000;
                Session s = getHelper().getSuperuserSession();
                try {
                    log.info("Starting to replace nodes");
                    int i = 0;
                    while (System.currentTimeMillis() < end) {
                        replaceNodes(s, i++);
                    }
                } finally {
                    s.logout();
                }
            } catch (RepositoryException e) {
                exceptions.add(e);
            }
        }
    });
    List<EventListener> listeners = new ArrayList<EventListener>();
    for (int i = 0; i < NUM_LISTENERS; i++) {
        final Session session = getHelper().getSuperuserSession();
        listeners.add(new EventListener() {

            public void onEvent(EventIterator events) {
                while (events.hasNext()) {
                    Event event = events.nextEvent();
                    String path = "n/a";
                    try {
                        if (event.getType() == Event.NODE_ADDED || event.getType() == Event.PROPERTY_ADDED) {
                            path = event.getPath();
                            session.getItem(path);
                        }
                    } catch (PathNotFoundException e) {
                    // ignore
                    } catch (RepositoryException e) {
                        log.error(e.toString() + " Unable to get item with path: " + path);
                        exceptions.add(e);
                    }
                }
            }
        });
    }
    for (EventListener listener : listeners) {
        superuser.getWorkspace().getObservationManager().addEventListener(listener, ALL_EVENTS, "/", true, null, null, false);
    }
    writer.start();
    writer.join();
    for (EventListener listener : listeners) {
        superuser.getWorkspace().getObservationManager().removeEventListener(listener);
    }
    log.info("" + exceptions.size() + " exception(s) occurred.");
    if (!exceptions.isEmpty()) {
        throw exceptions.get(0);
    }
}
Also used : ArrayList(java.util.ArrayList) RepositoryException(javax.jcr.RepositoryException) PathNotFoundException(javax.jcr.PathNotFoundException) RepositoryException(javax.jcr.RepositoryException) Event(javax.jcr.observation.Event) EventListener(javax.jcr.observation.EventListener) PathNotFoundException(javax.jcr.PathNotFoundException) EventIterator(javax.jcr.observation.EventIterator) Session(javax.jcr.Session)

Example 13 with EventIterator

use of javax.jcr.observation.EventIterator in project jackrabbit by apache.

the class EventConsumer method consumeEvents.

/**
 * Dispatches the events to the <code>EventListener</code>.
 *
 * @param events a collection of {@link EventState}s
 *               to dispatch.
 */
void consumeEvents(EventStateCollection events) throws RepositoryException {
    // Set of ItemIds of denied ItemStates
    Set<ItemId> denied = accessDenied.remove(events);
    if (denied == null) {
        denied = new HashSet<ItemId>();
    }
    // check permissions
    for (Iterator<EventState> it = events.iterator(); it.hasNext() && session.isLive(); ) {
        EventState state = it.next();
        if (state.getType() == Event.NODE_ADDED || state.getType() == Event.PROPERTY_ADDED || state.getType() == Event.PROPERTY_CHANGED) {
            ItemId targetId = state.getTargetId();
            if (!canRead(state)) {
                denied.add(targetId);
            }
        }
    }
    // only deliver if session is still live
    if (!session.isLive()) {
        return;
    }
    // check if filtered iterator has at least one event
    EventIterator it = new FilteredEventIterator(session, events.iterator(), events.getTimestamp(), events.getUserData(), filter, denied, false);
    if (it.hasNext()) {
        long time = System.currentTimeMillis();
        listener.onEvent(it);
        time = System.currentTimeMillis() - time;
        if (log.isDebugEnabled()) {
            log.debug("listener {} processed events in {} ms.", listener.getClass().getName(), time);
        }
    } else {
    // otherwise skip this listener
    }
}
Also used : EventIterator(javax.jcr.observation.EventIterator) ItemId(org.apache.jackrabbit.core.id.ItemId)

Example 14 with EventIterator

use of javax.jcr.observation.EventIterator in project jackrabbit by apache.

the class ListenerTracker method getTrackedListener.

public EventListener getTrackedListener() {
    return new EventListener() {

        @Override
        public void onEvent(EventIterator events) {
            eventDeliveries.incrementAndGet();
            final long start = nanoTime();
            try {
                beforeEventDelivery();
                listener.onEvent(new EventIteratorAdapter(events) {

                    long t0 = start;

                    private void recordTime(TimeSeriesRecorder recorder) {
                        recorder.getCounter().addAndGet(-(t0 - (t0 = nanoTime())));
                    }

                    @Override
                    public Object next() {
                        recordTime(eventConsumerTime);
                        eventsDelivered.incrementAndGet();
                        eventCount.getCounter().incrementAndGet();
                        Object object = super.next();
                        if (object instanceof JackrabbitEvent) {
                            object = new JackrabbitEventTracker(ListenerTracker.this, (JackrabbitEvent) object);
                        } else if (object instanceof Event) {
                            object = new EventTracker(ListenerTracker.this, (Event) object);
                        }
                        recordTime(eventProducerTime);
                        return object;
                    }

                    @Override
                    public boolean hasNext() {
                        recordTime(eventConsumerTime);
                        boolean result = super.hasNext();
                        recordTime(eventProducerTime);
                        return result;
                    }
                });
            } finally {
                afterEventDelivery();
                eventDeliveryTime.addAndGet(nanoTime() - start);
            }
        }

        @Override
        public String toString() {
            return ListenerTracker.this.toString();
        }
    };
}
Also used : EventIteratorAdapter(org.apache.jackrabbit.commons.iterator.EventIteratorAdapter) JackrabbitEvent(org.apache.jackrabbit.api.observation.JackrabbitEvent) Event(javax.jcr.observation.Event) JackrabbitEvent(org.apache.jackrabbit.api.observation.JackrabbitEvent) TimeSeriesRecorder(org.apache.jackrabbit.stats.TimeSeriesRecorder) EventListener(javax.jcr.observation.EventListener) EventIterator(javax.jcr.observation.EventIterator)

Example 15 with EventIterator

use of javax.jcr.observation.EventIterator in project jackrabbit by apache.

the class Locked method with.

/**
 * Executes the method {@link #run} within the scope of a lock held on
 * <code>lockable</code>.
 *
 * @param lockable the node where the lock is obtained from.
 * @param isDeep   <code>true</code> if <code>lockable</code> will be locked
 *                 deep.
 * @param timeout  time in milliseconds to wait at most to aquire the lock.
 * @return the object returned by {@link #run} or {@link #TIMED_OUT} if the
 *         lock on <code>lockable</code> could not be aquired within the
 *         specified timeout.
 * @throws IllegalArgumentException if <code>timeout</code> is negative or
 *                                  <code>lockable</code> is not
 *                                  <i>mix:lockable</i>.
 * @throws RepositoryException      if {@link #run} throws an exception.
 * @throws UnsupportedRepositoryOperationException
 *                                  if this repository does not support
 *                                  locking.
 * @throws InterruptedException     if this thread is interrupted while
 *                                  waiting for the lock on node
 *                                  <code>lockable</code>.
 */
public Object with(Node lockable, boolean isDeep, long timeout) throws UnsupportedRepositoryOperationException, RepositoryException, InterruptedException {
    if (timeout < 0) {
        throw new IllegalArgumentException("timeout must be >= 0");
    }
    Session session = lockable.getSession();
    NamePathResolver resolver = new DefaultNamePathResolver(session);
    Lock lock;
    EventListener listener = null;
    try {
        // check whether the lockable can be locked at all
        if (!lockable.isNodeType(resolver.getJCRName(NameConstants.MIX_LOCKABLE))) {
            throw new IllegalArgumentException("Node is not lockable");
        }
        lock = tryLock(lockable, isDeep);
        if (lock != null) {
            return runAndUnlock(lock);
        }
        if (timeout == 0) {
            return TIMED_OUT;
        }
        long timelimit;
        if (timeout == Long.MAX_VALUE) {
            timelimit = Long.MAX_VALUE;
        } else {
            timelimit = System.currentTimeMillis() + timeout;
        }
        // node is locked by other session -> register event listener if possible
        if (isObservationSupported(session)) {
            ObservationManager om = session.getWorkspace().getObservationManager();
            listener = new EventListener() {

                public void onEvent(EventIterator events) {
                    synchronized (this) {
                        this.notify();
                    }
                }
            };
            om.addEventListener(listener, Event.PROPERTY_REMOVED, lockable.getPath(), false, null, null, true);
        }
        // the current thread when the lockable node is possibly unlocked
        for (; ; ) {
            synchronized (this) {
                lock = tryLock(lockable, isDeep);
                if (lock != null) {
                    return runAndUnlock(lock);
                } else {
                    // check timeout
                    if (System.currentTimeMillis() > timelimit) {
                        return TIMED_OUT;
                    }
                    if (listener != null) {
                        // event listener *should* wake us up, however
                        // there is a chance that removal of the lockOwner
                        // property is notified before the node is acutally
                        // unlocked. therefore we use a safety net to wait
                        // at most 1000 millis.
                        this.wait(Math.min(1000, timeout));
                    } else {
                        // repository does not support observation
                        // wait at most 50 millis then retry
                        this.wait(Math.min(50, timeout));
                    }
                }
            }
        }
    } catch (NameException e) {
        throw new RepositoryException(e);
    } finally {
        if (listener != null) {
            session.getWorkspace().getObservationManager().removeEventListener(listener);
        }
    }
}
Also used : NamePathResolver(org.apache.jackrabbit.spi.commons.conversion.NamePathResolver) DefaultNamePathResolver(org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver) NameException(org.apache.jackrabbit.spi.commons.conversion.NameException) DefaultNamePathResolver(org.apache.jackrabbit.spi.commons.conversion.DefaultNamePathResolver) ObservationManager(javax.jcr.observation.ObservationManager) RepositoryException(javax.jcr.RepositoryException) EventListener(javax.jcr.observation.EventListener) EventIterator(javax.jcr.observation.EventIterator) Session(javax.jcr.Session) Lock(javax.jcr.lock.Lock)

Aggregations

EventIterator (javax.jcr.observation.EventIterator)26 Event (javax.jcr.observation.Event)14 EventListener (javax.jcr.observation.EventListener)12 RepositoryException (javax.jcr.RepositoryException)9 Session (javax.jcr.Session)9 Node (javax.jcr.Node)7 ObservationManager (javax.jcr.observation.ObservationManager)7 ArrayList (java.util.ArrayList)4 JackrabbitNode (org.apache.jackrabbit.api.JackrabbitNode)3 JackrabbitEvent (org.apache.jackrabbit.api.observation.JackrabbitEvent)3 Test (org.junit.Test)3 HashSet (java.util.HashSet)2 CountDownLatch (java.util.concurrent.CountDownLatch)2 PathNotFoundException (javax.jcr.PathNotFoundException)2 Lock (javax.jcr.lock.Lock)2 FilterProvider (org.apache.jackrabbit.oak.plugins.observation.filter.FilterProvider)2 File (java.io.File)1 IOException (java.io.IOException)1 RemoteException (java.rmi.RemoteException)1 HashMap (java.util.HashMap)1