You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2008/09/10 11:58:26 UTC
svn commit: r693761 - in /incubator/sling/trunk/extensions/jcrinstall/src:
main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/
test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/
Author: bdelacretaz
Date: Wed Sep 10 02:58:25 2008
New Revision: 693761
URL: http://svn.apache.org/viewvc?rev=693761&view=rev
Log:
SLING-646 - work in progress, ResourceDetectionTest implemented
Added:
incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FileDataProvider.java (with props)
incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ContentHelper.java (with props)
incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/EventHelper.java (with props)
incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MiscHelper.java (with props)
incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java (with props)
Modified:
incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java
incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/WatchedFolder.java
incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FindWatchedFoldersTest.java
Added: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FileDataProvider.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FileDataProvider.java?rev=693761&view=auto
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FileDataProvider.java (added)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FileDataProvider.java Wed Sep 10 02:58:25 2008
@@ -0,0 +1,67 @@
+/*
+ * 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
+ *
+ * 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.sling.jcr.jcrinstall.jcr.impl;
+
+import java.io.InputStream;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+/** Provides data (InputStream, last modified data) about
+ * JCR nodes which are files.
+ * TODO: Yes, this should be a generic JCR utility.
+ */
+class FileDataProvider {
+ /**
+ * The relative path of the data and last modified date of an nt:file node
+ */
+ public static final String JCR_CONTENT = "jcr:content";
+ public static final String JCR_CONTENT_DATA = JCR_CONTENT + "/jcr:data";
+ public static final String JCR_LAST_MODIFIED = "jcr:lastModified";
+ public static final String JCR_CONTENT_LAST_MODIFIED = JCR_CONTENT + "/" + JCR_LAST_MODIFIED;
+
+ private final InputStream inputStream;
+ private final long lastModified;
+
+ FileDataProvider(Node n) throws RepositoryException {
+ if (n.hasProperty(JCR_CONTENT_LAST_MODIFIED)) {
+ lastModified = n.getProperty(JCR_CONTENT_LAST_MODIFIED).getDate().getTimeInMillis();
+ } else {
+ lastModified = -1;
+ }
+
+ if(n.hasProperty(JCR_CONTENT_DATA)) {
+ inputStream = n.getProperty(JCR_CONTENT_DATA).getStream();
+ } else {
+ inputStream = null;
+ }
+ }
+
+ boolean isFile() {
+ return inputStream != null && lastModified != -1;
+ }
+
+ InputStream getInputStream() {
+ return inputStream;
+ }
+
+ long getLastModified() {
+ return lastModified;
+ }
+}
Propchange: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FileDataProvider.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FileDataProvider.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java?rev=693761&r1=693760&r2=693761&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/RepositoryObserver.java Wed Sep 10 02:58:25 2008
@@ -63,6 +63,9 @@
/** Default regexp for watched folders */
public static final String DEFAULT_FOLDER_NAME_REGEXP = ".*/install$";
+ /** Scan delay for watched folders */
+ private final long scanDelayMsec = 1000L;
+
protected static final Logger log = LoggerFactory.getLogger(WatchedFolder.class);
/** Upon activation, find folders to watch under our roots, and observe those
@@ -118,12 +121,12 @@
}
/** Add WatchedFolders that have been discovered by our WatchedFolderCreationListeners, if any */
- void addNewWatchedFolders() {
+ void addNewWatchedFolders() throws RepositoryException {
for(WatchedFolderCreationListener w : listeners) {
final Set<String> paths = w.getAndClearPaths();
if(paths != null) {
for(String path : paths) {
- folders.add(new WatchedFolder(path, osgiController));
+ folders.add(new WatchedFolder(repository, path, osgiController, scanDelayMsec));
}
}
}
@@ -160,7 +163,7 @@
void findWatchedFolders(Node n, Set<WatchedFolder> setToUpdate) throws RepositoryException
{
if (folderNameFilter.accept(n.getPath())) {
- setToUpdate.add(new WatchedFolder(n.getPath(), osgiController));
+ setToUpdate.add(new WatchedFolder(repository, n.getPath(), osgiController, scanDelayMsec));
}
final NodeIterator it = n.getNodes();
while (it.hasNext()) {
@@ -177,4 +180,11 @@
}
return path;
}
+
+ /** Let our WatchedFolders run their scanning cycles */
+ void runOneCycle() throws Exception {
+ for(WatchedFolder wf : folders) {
+ wf.scanIfNeeded();
+ }
+ }
}
Modified: incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/WatchedFolder.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/WatchedFolder.java?rev=693761&r1=693760&r2=693761&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/WatchedFolder.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/main/java/org/apache/sling/jcr/jcrinstall/jcr/impl/WatchedFolder.java Wed Sep 10 02:58:25 2008
@@ -18,6 +18,20 @@
*/
package org.apache.sling.jcr.jcrinstall.jcr.impl;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.jcr.Item;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventIterator;
+import javax.jcr.observation.EventListener;
+
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.jcrinstall.osgi.JcrInstallException;
import org.apache.sling.jcr.jcrinstall.osgi.OsgiController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -26,20 +40,43 @@
* to it (non-recursively) and sending the appropriate messages
* to the OsgiController service.
*/
-class WatchedFolder {
+class WatchedFolder implements EventListener {
private final String path;
private final OsgiController controller;
+ private long nextScan;
+ private final Session session;
protected static final Logger log = LoggerFactory.getLogger(WatchedFolder.class);
- WatchedFolder(String path, OsgiController ctrl) {
+ /**
+ * After receiving JCR events, we wait for this many msec before
+ * re-scanning the folder, as events often come in bursts.
+ */
+ private final long scanDelayMsec;
+
+ WatchedFolder(SlingRepository repository, String path, OsgiController ctrl, long scanDelayMsec) throws RepositoryException {
this.path = path;
this.controller = ctrl;
+ this.scanDelayMsec = scanDelayMsec;
+ session = repository.loginAdministrative(repository.getDefaultWorkspace());
+
+ // observe any changes in our folder, but not recursively
+ final int eventTypes = Event.NODE_ADDED | Event.NODE_REMOVED
+ | Event.PROPERTY_ADDED | Event.PROPERTY_CHANGED | Event.PROPERTY_REMOVED;
+ final boolean isDeep = false;
+ final boolean noLocal = true;
+ session.getWorkspace().getObservationManager().addEventListener(this, eventTypes, path,
+ isDeep, null, null, noLocal);
log.info("Watching folder " + path);
}
void cleanup() {
- // TODO stop listening to events
+ try {
+ session.getWorkspace().getObservationManager().removeEventListener(this);
+ session.logout();
+ } catch(RepositoryException re) {
+ log.warn("RepositoryException in cleanup()", re);
+ }
}
@Override
@@ -65,4 +102,68 @@
String getPath() {
return path;
}
+
+ /** Set our timer whenever an event occurs, to wait
+ * a bit before processing event bursts.
+ */
+ public void onEvent(EventIterator it) {
+ nextScan = System.currentTimeMillis() + scanDelayMsec;
+ }
+
+ /**
+ * If our timer allows it, scan our folder Node for updates
+ * and deletes.
+ */
+ void scanIfNeeded() throws Exception {
+ if (nextScan != -1 && System.currentTimeMillis() > nextScan) {
+ nextScan = -1;
+ }
+ scan();
+ }
+
+ /** Scan our folder and inform OsgiController of any changes */
+ protected void scan() throws Exception {
+ log.debug("Scanning {}", path);
+
+ Node folder = null;
+ if(session.itemExists(path)) {
+ Item i = session.getItem(path);
+ if(i.isNode()) {
+ folder = (Node)i;
+ }
+ }
+
+ if(folder == null) {
+ log.info("Folder {} does not exist (or not anymore), cannot scan", path);
+ return;
+ }
+
+
+ // TODO: check deletions
+
+ // Check adds and updates, for all child nodes that are files
+ final NodeIterator it = folder.getNodes();
+ while(it.hasNext()) {
+ final Node n = it.nextNode();
+ final FileDataProvider dp = new FileDataProvider(n);
+ if(!dp.isFile()) {
+ log.debug("Node {} does not seem to be a file, ignored", n.getPath());
+ }
+ installOrUpdate(n.getPath(), dp.getInputStream(), dp.getLastModified());
+ }
+ }
+
+ /** Install or update the given resource, as needed */
+ protected void installOrUpdate(String path, InputStream data, Long lastModified) throws IOException, JcrInstallException {
+ final long currentLastModified = controller.getLastModified(path);
+ if(currentLastModified == -1) {
+ log.info("Resource {} was not installed yet, installing in OsgiController", path);
+ controller.installOrUpdate(path, lastModified, data);
+ } else if(currentLastModified < lastModified) {
+ log.info("Resource {} has been updated, updating in OsgiController", path);
+ controller.installOrUpdate(path, lastModified, data);
+ } else {
+ log.info("Resource {} not modified, ignoring", path);
+ }
+ }
}
Added: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ContentHelper.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ContentHelper.java?rev=693761&view=auto
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ContentHelper.java (added)
+++ incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ContentHelper.java Wed Sep 10 02:58:25 2008
@@ -0,0 +1,105 @@
+/*
+ * 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
+ *
+ * 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.sling.jcr.jcrinstall.jcr.impl;
+
+import java.io.InputStream;
+import java.util.Calendar;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+class ContentHelper {
+ public static final String NT_FOLDER = "nt:folder";
+ public static final String NT_FILE = "nt:file";
+ public static final String NT_RESOURCE = "nt:resource";
+ public static final String JCR_CONTENT = "jcr:content";
+ public static final String JCR_LASTMODIFIED = "jcr:lastModified";
+ public static final String JCR_MIMETYPE = "jcr:mimeType";
+ public static final String JCR_ENCODING = "jcr:encoding";
+ public static final String JCR_DATA = "jcr:data";
+
+ final String [] WATCHED_FOLDERS = {
+ "libs/foo/bar/install",
+ "libs/foo/wii/install",
+ "apps/install"
+ };
+
+ final String [] IGNORED_FOLDERS = {
+ "libs/foo/bar/installed",
+ "apps/noninstall"
+ };
+
+ private final Session session;
+
+ ContentHelper(Session s) {
+ session = s;
+ }
+
+ void cleanupContent() throws Exception {
+ final String [] paths = { "libs", "apps" };
+ for(String path : paths) {
+ if(session.getRootNode().hasNode(path)) {
+ session.getRootNode().getNode(path).remove();
+ }
+ }
+ }
+
+ void setupContent() throws Exception {
+ cleanupContent();
+ for(String folder : WATCHED_FOLDERS) {
+ createFolder(folder);
+ }
+ for(String folder : IGNORED_FOLDERS) {
+ createFolder(folder);
+ }
+ }
+
+ void createFolder(String path) throws Exception {
+ final String [] parts = path.split("/");
+ Node n = session.getRootNode();
+ for(String part : parts) {
+ if(n.hasNode(part)) {
+ n = n.getNode(part);
+ } else {
+ n = n.addNode(part);
+ }
+ }
+ session.save();
+ }
+
+ void createOrUpdateFile(String path, InputStream data, long lastModified) throws RepositoryException {
+ final String relPath = path.substring(1);
+ Node f = null;
+ Node res = null;
+ if(session.getRootNode().hasNode(relPath)) {
+ f = session.getRootNode().getNode(relPath);
+ res = f.getNode(JCR_CONTENT);
+ } else {
+ f = session.getRootNode().addNode(relPath);
+ res = f.addNode(JCR_CONTENT);
+ }
+
+ final Calendar c = Calendar.getInstance();
+ c.setTimeInMillis(lastModified);
+ res.setProperty(JCR_LASTMODIFIED, c);
+ res.setProperty(JCR_DATA, data);
+ f.getParent().save();
+ }
+}
\ No newline at end of file
Propchange: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ContentHelper.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ContentHelper.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/EventHelper.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/EventHelper.java?rev=693761&view=auto
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/EventHelper.java (added)
+++ incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/EventHelper.java Wed Sep 10 02:58:25 2008
@@ -0,0 +1,85 @@
+/*
+ * 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
+ *
+ * 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.sling.jcr.jcrinstall.jcr.impl;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.observation.Event;
+import javax.jcr.observation.EventIterator;
+import javax.jcr.observation.EventListener;
+
+/** Used by tests to wait until JCR notification events
+ * have been delivered.
+ */
+class EventHelper implements EventListener {
+ private final Session session;
+ private int eventCount;
+ public static final String WAIT_NODE_FOLDER = "WAIT_NODE";
+ public static final String WAIT_NODE_NODE = EventHelper.class.getSimpleName();
+ private final Node waitNodeFolder;
+
+ EventHelper(Session s) throws RepositoryException {
+ session = s;
+
+ final int eventTypes = Event.NODE_ADDED | Event.NODE_REMOVED;
+ final boolean isDeep = true;
+ final boolean noLocal = false;
+ session.getWorkspace().getObservationManager().addEventListener(
+ this, eventTypes, "/" + WAIT_NODE_FOLDER, isDeep, null, null, noLocal);
+
+ if(session.getRootNode().hasNode(WAIT_NODE_FOLDER)) {
+ waitNodeFolder = session.getRootNode().getNode(WAIT_NODE_FOLDER);
+ } else {
+ waitNodeFolder = session.getRootNode().addNode(WAIT_NODE_FOLDER, "nt:unstructured");
+ }
+ session.save();
+ }
+
+ public void onEvent(EventIterator it) {
+ eventCount++;
+ }
+
+ /** To make sure observation events have been delivered,
+ * create or delete a a node and wait for the corresponding
+ * events to be received.
+ */
+ void waitForEvents(long timeoutMsec) throws RepositoryException {
+ final int targetEventCount = eventCount + 1;
+
+ if(waitNodeFolder.hasNode(WAIT_NODE_NODE)) {
+ waitNodeFolder.getNode(WAIT_NODE_NODE).remove();
+ } else {
+ waitNodeFolder.addNode(WAIT_NODE_NODE);
+ }
+ session.save();
+
+ final long end = System.currentTimeMillis() + timeoutMsec;
+ while(eventCount < targetEventCount && System.currentTimeMillis() < end) {
+ try {
+ Thread.sleep(100);
+ } catch(InterruptedException ignored) {
+ }
+ }
+
+ if(eventCount < targetEventCount) {
+ throw new IllegalStateException("Event counter did not reach " + targetEventCount + ", waited " + timeoutMsec + " msec");
+ }
+ }
+}
Propchange: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/EventHelper.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/EventHelper.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Modified: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FindWatchedFoldersTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FindWatchedFoldersTest.java?rev=693761&r1=693760&r2=693761&view=diff
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FindWatchedFoldersTest.java (original)
+++ incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/FindWatchedFoldersTest.java Wed Sep 10 02:58:25 2008
@@ -18,44 +18,28 @@
*/
package org.apache.sling.jcr.jcrinstall.jcr.impl;
-import java.lang.reflect.Field;
import java.util.Set;
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
import javax.jcr.Session;
-import javax.jcr.observation.Event;
-import javax.jcr.observation.EventIterator;
-import javax.jcr.observation.EventListener;
import org.apache.sling.commons.testing.jcr.RepositoryTestBase;
import org.apache.sling.jcr.api.SlingRepository;
/** Test the "find watched folders" feature of the RepositoryObserver */
-public class FindWatchedFoldersTest extends RepositoryTestBase implements EventListener {
+public class FindWatchedFoldersTest extends RepositoryTestBase {
SlingRepository repo;
Session session;
- String eventPathToWatch;
- int eventCount;
-
- private static final String [] WATCHED_FOLDERS = {
- "libs/foo/bar/install",
- "libs/foo/wii/install",
- "apps/install"
- };
-
- private static final String [] IGNORED_FOLDERS = {
- "libs/foo/bar/installed",
- "apps/noninstall"
- };
+ private EventHelper eventHelper;
+ private ContentHelper contentHelper;
@Override
protected void tearDown() throws Exception {
super.tearDown();
- session.getWorkspace().getObservationManager().removeEventListener(this);
- cleanupContent();
+ contentHelper.cleanupContent();
session.logout();
+ eventHelper = null;
+ contentHelper = null;
}
@Override
@@ -63,140 +47,42 @@
super.setUp();
repo = getRepository();
session = repo.loginAdministrative(repo.getDefaultWorkspace());
- cleanupContent();
-
- final int eventTypes = Event.NODE_ADDED;
- final boolean isDeep = true;
- final boolean noLocal = false;
- session.getWorkspace().getObservationManager().addEventListener(
- this, eventTypes, "/", isDeep, null, null, noLocal);
- }
-
- void cleanupContent() throws Exception {
- final String [] paths = { "libs", "apps" };
- for(String path : paths) {
- if(session.getRootNode().hasNode(path)) {
- session.getRootNode().getNode(path).remove();
- }
- }
- }
-
- void setupContent() throws Exception {
- cleanupContent();
- for(String folder : WATCHED_FOLDERS) {
- createFolder(folder);
- }
- for(String folder : IGNORED_FOLDERS) {
- createFolder(folder);
- }
+ eventHelper = new EventHelper(session);
+ contentHelper = new ContentHelper(session);
+ contentHelper.cleanupContent();
}
- public void onEvent(EventIterator it) {
- try {
- while(it.hasNext()) {
- final Event e = it.nextEvent();
- if(e.getPath().equals(eventPathToWatch)) {
- eventCount++;
- }
- }
- } catch(RepositoryException ignored) {
- // ignore
- }
- }
-
- @SuppressWarnings("unchecked")
public void testInitialFind() throws Exception {
- setupContent();
- final RepositoryObserver ro = createRepositoryObserver();
+ contentHelper.setupContent();
+ final RepositoryObserver ro = MiscHelper.createRepositoryObserver(repo, null);
ro.activate(null);
- final Set<WatchedFolder> wfSet = getWatchedFolders(ro);
- assertEquals("activate() must find all watched folders", WATCHED_FOLDERS.length, wfSet.size());
+ final Set<WatchedFolder> wfSet = MiscHelper.getWatchedFolders(ro);
+ assertEquals("activate() must find all watched folders", contentHelper.WATCHED_FOLDERS.length, wfSet.size());
- for(String folder : WATCHED_FOLDERS) {
+ for(String folder : contentHelper.WATCHED_FOLDERS) {
assertTrue("Folder " + folder + " must be watched (watched=" + wfSet + ")",
- folderIsWatched(ro, folder));
+ MiscHelper.folderIsWatched(ro, folder));
}
}
public void testNewWatchedFolderDetection() throws Exception {
- setupContent();
- final RepositoryObserver ro = createRepositoryObserver();
+ contentHelper.setupContent();
+ final RepositoryObserver ro = MiscHelper.createRepositoryObserver(repo, null);
ro.activate(null);
final String newPaths [] = { "libs/tnwf/install", "apps/tnwf/install" };
for(String newPath : newPaths) {
- assertFalse(newPath + " must not be watched before test", folderIsWatched(ro, newPath));
+ assertFalse(newPath + " must not be watched before test", MiscHelper.folderIsWatched(ro, newPath));
// Create folder, wait for observation event and check that
// it is detected
- final int ec = eventCount;
- eventPathToWatch = "/" + newPath;
- createFolder(newPath);
- waitForEventCount(ec + 1, 5000L);
- assertFalse(newPath + " must not be watched before calling addNewWatchedFolders()", folderIsWatched(ro, newPath));
+ contentHelper.createFolder(newPath);
+ eventHelper.waitForEvents(5000L);
+ assertFalse(newPath + " must not be watched before calling addNewWatchedFolders()", MiscHelper.folderIsWatched(ro, newPath));
ro.addNewWatchedFolders();
- assertTrue(newPath + " must be watched before calling addNewWatchedFolders()", folderIsWatched(ro, newPath));
- }
- }
-
- void waitForEventCount(int count, long timeoutMsec) {
- final long end = System.currentTimeMillis() + timeoutMsec;
- while(eventCount < count && System.currentTimeMillis() < end) {
- try {
- Thread.sleep(100);
- } catch(InterruptedException ignored) {
- }
- }
-
- if(eventCount < count) {
- throw new IllegalStateException("Event counter did not reach " + count + ", waited " + timeoutMsec + " msec");
- }
- }
-
- @SuppressWarnings("unchecked")
- Set<WatchedFolder> getWatchedFolders(RepositoryObserver ro) throws Exception {
- final Field f = ro.getClass().getDeclaredField("folders");
- f.setAccessible(true);
- return (Set<WatchedFolder>)f.get(ro);
- }
-
- boolean folderIsWatched(RepositoryObserver ro, String path) throws Exception {
- boolean result = false;
- final Set<WatchedFolder> wfSet = getWatchedFolders(ro);
- for(WatchedFolder wf : wfSet) {
- if(wf.getPath().equals("/" + path)) {
- result = true;
- break;
- }
- }
- return result;
- }
-
- void createFolder(String path) throws Exception {
- final String [] parts = path.split("/");
- Node n = session.getRootNode();
- for(String part : parts) {
- if(n.hasNode(part)) {
- n = n.getNode(part);
- } else {
- n = n.addNode(part);
- }
+ assertTrue(newPath + " must be watched before calling addNewWatchedFolders()", MiscHelper.folderIsWatched(ro, newPath));
}
- session.save();
- }
-
- RepositoryObserver createRepositoryObserver() throws Exception {
- final RepositoryObserver result = new RepositoryObserver();
- setField(result, "repository", repo);
- return result;
- }
-
- static void setField(Object target, String name, Object value) throws Exception, IllegalAccessException {
- final Field f = target.getClass().getDeclaredField(name);
- f.setAccessible(true);
- f.set(target, value);
-
- }
-}
+ }
+}
\ No newline at end of file
Added: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MiscHelper.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MiscHelper.java?rev=693761&view=auto
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MiscHelper.java (added)
+++ incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MiscHelper.java Wed Sep 10 02:58:25 2008
@@ -0,0 +1,62 @@
+/*
+ * 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
+ *
+ * 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.sling.jcr.jcrinstall.jcr.impl;
+
+import java.lang.reflect.Field;
+import java.util.Set;
+
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.jcrinstall.osgi.OsgiController;
+
+/** Miscellaneous test helper functions */
+class MiscHelper {
+ static boolean folderIsWatched(RepositoryObserver ro, String path) throws Exception {
+ boolean result = false;
+ final Set<WatchedFolder> wfSet = getWatchedFolders(ro);
+ for(WatchedFolder wf : wfSet) {
+ if(wf.getPath().equals("/" + path)) {
+ result = true;
+ break;
+ }
+ }
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ static Set<WatchedFolder> getWatchedFolders(RepositoryObserver ro) throws Exception {
+ final Field f = ro.getClass().getDeclaredField("folders");
+ f.setAccessible(true);
+ return (Set<WatchedFolder>)f.get(ro);
+ }
+
+ static RepositoryObserver createRepositoryObserver(SlingRepository repo, OsgiController c) throws Exception {
+ final RepositoryObserver result = new RepositoryObserver();
+ setField(result, "repository", repo);
+ setField(result, "osgiController", c);
+ return result;
+ }
+
+ static void setField(Object target, String name, Object value) throws Exception, IllegalAccessException {
+ final Field f = target.getClass().getDeclaredField(name);
+ f.setAccessible(true);
+ f.set(target, value);
+
+ }
+
+}
Propchange: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MiscHelper.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/MiscHelper.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java
URL: http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java?rev=693761&view=auto
==============================================================================
--- incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java (added)
+++ incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java Wed Sep 10 02:58:25 2008
@@ -0,0 +1,163 @@
+/*
+ * 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
+ *
+ * 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.sling.jcr.jcrinstall.jcr.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+import javax.jcr.Session;
+
+import org.apache.sling.commons.testing.jcr.RepositoryTestBase;
+import org.apache.sling.jcr.api.SlingRepository;
+import org.apache.sling.jcr.jcrinstall.osgi.OsgiController;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.Sequence;
+
+/** Test that added/updated/removed resources are
+ * correctly translated to OsgiController calls.
+ */
+public class ResourceDetectionTest extends RepositoryTestBase {
+ SlingRepository repo;
+ Session session;
+ private EventHelper eventHelper;
+ private ContentHelper contentHelper;
+ private Mockery mockery;
+ private Sequence sequence;
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ contentHelper.cleanupContent();
+ session.logout();
+ eventHelper = null;
+ contentHelper = null;
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ repo = getRepository();
+ session = repo.loginAdministrative(repo.getDefaultWorkspace());
+ eventHelper = new EventHelper(session);
+ contentHelper = new ContentHelper(session);
+ contentHelper.cleanupContent();
+
+ mockery = new Mockery();
+ sequence = mockery.sequence(getClass().getSimpleName());
+ }
+
+ protected String getOsgiResourceLocation(String uri) {
+ return "jcrinstall://" + uri;
+ }
+
+ /** Add, update and remove resources from the repository
+ * and verify that the OsgiController receives the
+ * correct messages
+ */
+ public void testSingleResourceDetection() throws Exception {
+ contentHelper.setupContent();
+
+ final String dummyJar = "/libs/foo/bar/install/dummy.jar";
+ final InputStream data = new ByteArrayInputStream(dummyJar.getBytes());
+ final long lastModifiedA = System.currentTimeMillis();
+ final long lastModifiedB = lastModifiedA + 1;
+
+ final OsgiController c = mockery.mock(OsgiController.class);
+ final RepositoryObserver ro = MiscHelper.createRepositoryObserver(repo, c);
+ ro.activate(null);
+
+ // Define the whole sequence of calls to OsgiController,
+ // Using getLastModified calls to mark the test phases
+ mockery.checking(new Expectations() {{
+ one(c).getLastModified("phase1");
+ inSequence(sequence);
+ one(c).getLastModified(dummyJar); will(returnValue(-1L));
+ inSequence(sequence);
+ one(c).installOrUpdate(with(equal(dummyJar)), with(equal(lastModifiedA)), with(any(InputStream.class)));
+ inSequence(sequence);
+
+ one(c).getLastModified("phase2");
+ inSequence(sequence);
+ one(c).getLastModified(dummyJar); will(returnValue(lastModifiedA));
+ inSequence(sequence);
+
+ one(c).getLastModified("phase3");
+ inSequence(sequence);
+ one(c).getLastModified(dummyJar); will(returnValue(lastModifiedA));
+ inSequence(sequence);
+ one(c).installOrUpdate(with(equal(dummyJar)), with(equal(lastModifiedB)), with(any(InputStream.class)));
+ inSequence(sequence);
+ }});
+
+ // Add two files, run one cycle must install the bundles
+ c.getLastModified("phase1");
+ contentHelper.createOrUpdateFile(dummyJar, data, lastModifiedA);
+ eventHelper.waitForEvents(5000L);
+ ro.runOneCycle();
+
+ // Updating with the same timestamp must not call install again
+ c.getLastModified("phase2");
+ contentHelper.createOrUpdateFile(dummyJar, data, lastModifiedA);
+ eventHelper.waitForEvents(5000L);
+ ro.runOneCycle();
+
+ // Updating with a new timestamp must call install again
+ c.getLastModified("phase3");
+ contentHelper.createOrUpdateFile(dummyJar, data, lastModifiedB);
+ eventHelper.waitForEvents(5000L);
+ ro.runOneCycle();
+
+ mockery.assertIsSatisfied();
+ }
+
+ public void testMultipleResourceDetection() throws Exception {
+ contentHelper.setupContent();
+
+ final String [] resources = {
+ "/libs/foo/bar/install/dummy.jar",
+ "/libs/foo/bar/install/dummy.cfg",
+ "/libs/foo/bar/install/dummy.dp"
+ };
+ final InputStream data = new ByteArrayInputStream("hello".getBytes());
+ final long lastModifiedA = System.currentTimeMillis();
+
+ final OsgiController c = mockery.mock(OsgiController.class);
+ final RepositoryObserver ro = MiscHelper.createRepositoryObserver(repo, c);
+ ro.activate(null);
+
+ // Define the whole sequence of calls to OsgiController,
+ // Using getLastModified calls to mark the test phases
+ mockery.checking(new Expectations() {{
+ allowing(c).getLastModified(with(any(String.class))); will(returnValue(-1L));
+ one(c).installOrUpdate(with(equal(resources[0])), with(equal(lastModifiedA)), with(any(InputStream.class)));
+ one(c).installOrUpdate(with(equal(resources[1])), with(equal(lastModifiedA)), with(any(InputStream.class)));
+ one(c).installOrUpdate(with(equal(resources[2])), with(equal(lastModifiedA)), with(any(InputStream.class)));
+ }});
+
+ // Add two files, run one cycle must install the bundles
+ for(String file : resources) {
+ contentHelper.createOrUpdateFile(file, data, lastModifiedA);
+ }
+ eventHelper.waitForEvents(5000L);
+ ro.runOneCycle();
+
+ mockery.assertIsSatisfied();
+ }
+}
Propchange: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/sling/trunk/extensions/jcrinstall/src/test/java/org/apache/sling/jcr/jcrinstall/jcr/impl/ResourceDetectionTest.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL