Author: frm
Date: Mon Aug 22 11:47:05 2016
New Revision: 1757149
URL: http://svn.apache.org/viewvc?rev=1757149&view=rev
Log:
OAK-4683 - Add a store version to the manifest file
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/Manifest.java
(with props)
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/ManifestTest.java
(with props)
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/InvalidFileStoreVersionException.java
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java?rev=1757149&r1=1757148&r2=1757149&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/FileStore.java
Mon Aug 22 11:47:05 2016
@@ -76,7 +76,6 @@ import com.google.common.base.Predicate;
import com.google.common.base.Stopwatch;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
-import com.google.common.io.Files;
import org.apache.commons.math3.stat.descriptive.DescriptiveStatistics;
import org.apache.jackrabbit.oak.api.jmx.CacheStatsMBean;
import org.apache.jackrabbit.oak.plugins.blob.ReferenceCollector;
@@ -114,6 +113,19 @@ public class FileStore implements Segmen
private static final int MB = 1024 * 1024;
+ /**
+ * This value can be used as an invalid store version, since the store
+ * version is defined to be strictly greater than zero.
+ */
+ private static final int INVALID_STORE_VERSION = 0;
+
+ /**
+ * The store version is an always incrementing number, strictly greater
than
+ * zero, that is changed every time there is a backwards incompatible
+ * modification to the format of the segment store.
+ */
+ private static final int CURRENT_STORE_VERSION = 1;
+
private static final Pattern FILE_NAME_PATTERN =
Pattern.compile("(data|bulk)((0|[1-9][0-9]*)[0-9]{4})([a-z])?.tar");
@@ -281,17 +293,13 @@ public class FileStore implements Segmen
Map<Integer, Map<Character, File>> map = collectFiles(directory);
- File manifest = new File(directory, MANIFEST_FILE_NAME);
+ Manifest manifest = Manifest.empty();
if (map.size() > 0) {
- if (manifest.exists()) {
- log.debug("The store folder is non empty and has a valid
manifest file");
- } else {
- throw new InvalidFileStoreVersionException();
- }
+ manifest = checkManifest(openManifest());
}
- Files.touch(manifest);
+ saveManifest(manifest);
this.readers = newArrayListWithCapacity(map.size());
Integer[] indices = map.keySet().toArray(new Integer[map.size()]);
@@ -391,6 +399,51 @@ public class FileStore implements Segmen
return this;
}
+ private File getManifestFile() {
+ return new File(directory, MANIFEST_FILE_NAME);
+ }
+
+ private Manifest openManifest() throws IOException {
+ File file = getManifestFile();
+
+ if (file.exists()) {
+ return Manifest.load(file);
+ }
+
+ return null;
+ }
+
+ private Manifest checkManifest(Manifest manifest) throws
InvalidFileStoreVersionException {
+ if (manifest == null) {
+ throw new InvalidFileStoreVersionException("Using oak-segment-tar,
but oak-segment should be used");
+ }
+
+ int storeVersion = manifest.getStoreVersion(INVALID_STORE_VERSION);
+
+ // A store version less than or equal to the highest invalid value
means
+ // that something or someone is messing up with the manifest. This
error
+ // is not recoverable and is thus represented as an ISE.
+
+ if (storeVersion <= INVALID_STORE_VERSION) {
+ throw new IllegalStateException("Invalid store version");
+ }
+
+ if (storeVersion < CURRENT_STORE_VERSION) {
+ throw new InvalidFileStoreVersionException("Using a too recent
version of oak-segment-tar");
+ }
+
+ if (storeVersion > CURRENT_STORE_VERSION) {
+ throw new InvalidFileStoreVersionException("Using a too old
version of oak-segment tar");
+ }
+
+ return manifest;
+ }
+
+ private void saveManifest(Manifest manifest) throws IOException {
+ manifest.setStoreVersion(CURRENT_STORE_VERSION);
+ manifest.save(getManifestFile());
+ }
+
@Nonnull
private Supplier<RecordId> initialNode() {
return new Supplier<RecordId>() {
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/InvalidFileStoreVersionException.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/InvalidFileStoreVersionException.java?rev=1757149&r1=1757148&r2=1757149&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/InvalidFileStoreVersionException.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/InvalidFileStoreVersionException.java
Mon Aug 22 11:47:05 2016
@@ -24,4 +24,11 @@ package org.apache.jackrabbit.oak.segmen
*/
public class InvalidFileStoreVersionException extends Exception {
+ public InvalidFileStoreVersionException() {
+ }
+
+ public InvalidFileStoreVersionException(String message) {
+ super(message);
+ }
+
}
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/Manifest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/Manifest.java?rev=1757149&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/Manifest.java
(added)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/Manifest.java
Mon Aug 22 11:47:05 2016
@@ -0,0 +1,108 @@
+/*
+ * 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.jackrabbit.oak.segment.file;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Properties;
+
+class Manifest {
+
+ private static final String STORE_VERSION = "store.version";
+
+ /**
+ * Loads the manifest from a file.
+ *
+ * @param file The file to load the manifest from.
+ * @return A manifest file.
+ * @throws IOException If any error occurs when loading the manifest.
+ */
+ static Manifest load(File file) throws IOException {
+ Properties properties = new Properties();
+ properties.load(new FileReader(file));
+ return new Manifest(properties);
+ }
+
+ /**
+ * Creates an empty manifest file.
+ *
+ * @return A manifest file.
+ */
+ static Manifest empty() {
+ return new Manifest(new Properties());
+ }
+
+ private final Properties properties;
+
+ private Manifest(Properties properties) {
+ this.properties = properties;
+ }
+
+ /**
+ * Return the store version saved in this manifest or a user provided value
+ * if no valid store version is saved in the manifest.
+ *
+ * @param otherwise The value that will be returned if no valid store
+ * version is saved in this manifest.
+ * @return The store version stored in this manifest or the user provided
+ * default value.
+ */
+ int getStoreVersion(int otherwise) {
+ return getIntegerProperty(STORE_VERSION, otherwise);
+ }
+
+ /**
+ * Set the store version in this manifest.
+ *
+ * @param version The store version.
+ */
+ void setStoreVersion(int version) {
+ setIntegerProperty(STORE_VERSION, version);
+ }
+
+ /**
+ * Save the manifest to the specified file.
+ *
+ * @param file The file to save the manifest to.
+ * @throws IOException if an error occurs while saving the manifest.
+ */
+ void save(File file) throws IOException {
+ properties.store(new FileWriter(file), null);
+ }
+
+ private int getIntegerProperty(String name, int otherwise) {
+ Object value = properties.get(name);
+
+ if (value == null) {
+ return otherwise;
+ }
+
+ try {
+ return Integer.parseInt(value.toString());
+ } catch (NumberFormatException e) {
+ return otherwise;
+ }
+ }
+
+ private void setIntegerProperty(String name, int value) {
+ properties.put(name, Integer.toString(value));
+ }
+
+}
Propchange:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/Manifest.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/ManifestTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/ManifestTest.java?rev=1757149&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/ManifestTest.java
(added)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/ManifestTest.java
Mon Aug 22 11:47:05 2016
@@ -0,0 +1,50 @@
+/*
+ * 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.jackrabbit.oak.segment.file;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+public class ManifestTest {
+
+ @Rule
+ public TemporaryFolder folder = new TemporaryFolder(new File("target"));
+
+ @Test
+ public void defaultStoreVersionShouldBeReturned() throws Exception {
+ assertEquals(42, Manifest.load(folder.newFile()).getStoreVersion(42));
+ }
+
+ @Test
+ public void storeVersionShouldBeReturned() throws Exception {
+ File file = folder.newFile();
+
+ Manifest write = Manifest.empty();
+ write.setStoreVersion(42);
+ write.save(file);
+
+ Manifest read = Manifest.load(file);
+ assertEquals(42, read.getStoreVersion(0));
+ }
+
+}
Propchange:
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/ManifestTest.java
------------------------------------------------------------------------------
svn:eol-style = native