/* * ModeShape (http://www.modeshape.org) * * Licensed 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.modeshape.jcr; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsNull.notNullValue; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import java.io.File; import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.jcr.Binary; import javax.jcr.Node; import javax.jcr.NodeIterator; import javax.jcr.Session; import javax.jcr.nodetype.NodeType; import javax.jcr.query.Query; import javax.jcr.query.QueryResult; import org.junit.Before; import org.junit.Test; import org.modeshape.common.FixFor; import org.modeshape.common.util.IoUtil; import org.modeshape.jcr.api.JcrTools; import org.modeshape.jcr.api.NamespaceRegistry; /** * A test the verifies that a repository will persist content (including binaries). */ public class RepositoryPersistenceTest extends MultiPassAbstractTest { @Before public void before() { TestingUtil.waitUntilFolderCleanedUp("target/persistent_repository"); } @Test public void shouldPersistBinariesAcrossRestart() throws Exception { String repositoryConfigFile = "config/repo-config-binaries-fs.json"; assertDataPersistenceAcrossRestarts(repositoryConfigFile); } @FixFor( "MODE-2212" ) @Test public void shouldPersistGeneratedNamespacesAcrossRestart() throws Exception { String repositoryConfigFile = "config/repo-config-binaries-fs.json"; startRunStop(repository -> { Session session = repository.login(); final NamespaceRegistry namespaceRegistry = (NamespaceRegistry)session.getWorkspace().getNamespaceRegistry(); namespaceRegistry.registerNamespace("info:a#"); namespaceRegistry.registerNamespace("info:b#"); namespaceRegistry.registerNamespace("info:c#"); assertEquals("ns001", namespaceRegistry.getPrefix("info:a#")); assertEquals("ns002", namespaceRegistry.getPrefix("info:b#")); assertEquals("ns003", namespaceRegistry.getPrefix("info:c#")); final Node node = session.getRootNode().addNode("ns001:xyz", NodeType.NT_UNSTRUCTURED); node.setProperty("ns002:abc", "abc"); node.setProperty("ns003:def", "def"); session.save(); session.logout(); }, repositoryConfigFile); startRunStop(repository -> { Session session = repository.login(); final NamespaceRegistry namespaceRegistry = (NamespaceRegistry)session.getWorkspace().getNamespaceRegistry(); assertEquals("ns001", namespaceRegistry.getPrefix("info:a#")); assertEquals("ns002", namespaceRegistry.getPrefix("info:b#")); assertEquals("ns003", namespaceRegistry.getPrefix("info:c#")); session.save(); session.logout(); }, repositoryConfigFile); } @Test public void shouldPersistDataUsingDB() throws Exception { // make sure the DB is clean (empty) when running this test; there is no effective teardown assertDataPersistenceAcrossRestarts("config/db/repo-config-jdbc.json"); } private void assertDataPersistenceAcrossRestarts( String repositoryConfigFile ) throws Exception { final List<File> testFiles = new ArrayList<>(); final Map<String, Long> testFileSizesInBytes = new HashMap<>(); testFiles.add(getFile("mimetype/test.xml")); testFiles.add(getFile("mimetype/modeshape.doc")); testFiles.add(getFile("mimetype/log4j.properties")); for (File testFile : testFiles) { assertThat(testFile.getPath() + " should exist", testFile.exists(), is(true)); assertThat(testFile.getPath() + " should be a file", testFile.isFile(), is(true)); assertThat(testFile.getPath() + " should be readable", testFile.canRead(), is(true)); testFileSizesInBytes.put(testFile.getName(), testFile.length()); } final JcrTools tools = new JcrTools(); startRunStop(repository -> { Session session = repository.login(); // Add some content ... session.getRootNode().addNode("testNode"); for (File testFile : testFiles) { String name = testFile.getName(); Node fileNode = tools.uploadFile(session, "/testNode/" + name, testFile); Binary binary = fileNode.getNode("jcr:content").getProperty("jcr:data").getBinary(); assertThat(binary.getSize(), is(testFileSizesInBytes.get(name))); } session.save(); Node testNode = session.getNode("/testNode"); for (File testFile : testFiles) { String name = testFile.getName(); Node fileNode = testNode.getNode(name); assertThat(fileNode, is(notNullValue())); Binary binary = fileNode.getNode("jcr:content").getProperty("jcr:data").getBinary(); byte[] expectedBytes = IoUtil.readBytes(testFile); byte[] actualBytes = IoUtil.readBytes(binary.getStream()); assertArrayEquals(expectedBytes, actualBytes); } Query query = session.getWorkspace().getQueryManager().createQuery("SELECT * FROM [nt:file]", Query.JCR_SQL2); QueryResult results = query.execute(); NodeIterator iter = results.getNodes(); while (iter.hasNext()) { Node fileNode = iter.nextNode(); assertThat(fileNode, is(notNullValue())); String name = fileNode.getName(); Binary binary = fileNode.getNode("jcr:content").getProperty("jcr:data").getBinary(); assertThat(binary.getSize(), is(testFileSizesInBytes.get(name))); } session.logout(); }, repositoryConfigFile); startRunStop(repository -> { Session session = repository.login(); assertNotNull(session.getNode("/testNode")); for (File testFile : testFiles) { String name = testFile.getName(); Node fileNode = session.getNode("/testNode/" + name); assertNotNull(fileNode); Binary binary = fileNode.getNode("jcr:content").getProperty("jcr:data").getBinary(); assertThat(binary.getSize(), is(testFileSizesInBytes.get(name))); } Query query = session.getWorkspace().getQueryManager().createQuery("SELECT * FROM [nt:file]", Query.JCR_SQL2); QueryResult results = query.execute(); NodeIterator iter = results.getNodes(); while (iter.hasNext()) { Node fileNode = iter.nextNode(); String name = fileNode.getName(); Binary binary = fileNode.getNode("jcr:content").getProperty("jcr:data").getBinary(); assertThat(binary.getSize(), is(testFileSizesInBytes.get(name))); } session.getNode("/testNode").remove(); session.save(); query = session.getWorkspace().getQueryManager().createQuery("SELECT * FROM [nt:file]", Query.JCR_SQL2); results = query.execute(); assertFalse(results.getNodes().hasNext()); session.logout(); }, repositoryConfigFile); } protected File getFile( String resourcePath ) throws URISyntaxException { URL resource = getClass().getClassLoader().getResource(resourcePath); assertNotNull(resourcePath + " not found", resource); return new File(resource.toURI()); } }