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 2014/01/29 18:45:24 UTC
svn commit: r1562522 - in /jackrabbit/oak/trunk:
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/
oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/
oak-http/src/main/java/org/apache/jackrabbit/oak/http/segment/
Author: jukka
Date: Wed Jan 29 17:45:24 2014
New Revision: 1562522
URL: http://svn.apache.org/r1562522
Log:
OAK-1309: TarMK master-slave clustering
Add a basic HTTP interface to SegmentStore
Added:
jackrabbit/oak/trunk/oak-http/src/main/java/org/apache/jackrabbit/oak/http/segment/
jackrabbit/oak/trunk/oak-http/src/main/java/org/apache/jackrabbit/oak/http/segment/SegmentServlet.java (with props)
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java?rev=1562522&r1=1562521&r2=1562522&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/Segment.java Wed Jan 29 17:45:24 2014
@@ -24,9 +24,13 @@ import static com.google.common.collect.
import static org.apache.jackrabbit.oak.plugins.segment.SegmentIdFactory.isDataSegmentId;
import static org.apache.jackrabbit.oak.plugins.segment.SegmentWriter.BLOCK_SIZE;
+import java.io.IOException;
+import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.WritableByteChannel;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
@@ -218,6 +222,20 @@ public class Segment {
return data.remaining();
}
+ /**
+ * Writes this segment to the given output stream.
+ *
+ * @param stream stream to which this segment will be written
+ * @throws IOException on an IO error
+ */
+ public void writeTo(OutputStream stream) throws IOException {
+ ByteBuffer buffer = data.duplicate();
+ WritableByteChannel channel = Channels.newChannel(stream);
+ while (buffer.hasRemaining()) {
+ channel.write(buffer);
+ }
+ }
+
byte readByte(int offset) {
return data.get(pos(offset, 1));
}
@@ -240,12 +258,14 @@ public class Segment {
* @param uuid segment identifier
* @return identified segment
*/
+ @Nonnull
Segment getSegment(UUID uuid) {
if (equal(uuid, this.uuid)) {
return this; // optimization for the common case (OAK-1031)
- } else {
- return store.readSegment(uuid);
}
+ Segment segment = store.readSegment(uuid);
+ checkState(segment != null); // sanity check
+ return segment;
}
/**
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java?rev=1562522&r1=1562521&r2=1562522&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentNodeStore.java Wed Jan 29 17:45:24 2014
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.oak.plugin
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
import static java.lang.System.currentTimeMillis;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
@@ -76,6 +77,7 @@ public class SegmentNodeStore implements
public SegmentNodeStore(SegmentStore store, String journal) {
this.store = store;
this.journal = store.getJournal(journal);
+ checkState(this.journal != null);
this.head = new AtomicReference<SegmentNodeState>(new SegmentNodeState(
store.getWriter().getDummySegment(), this.journal.getHead()));
this.changeDispatcher = new ChangeDispatcher(getRoot());
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java?rev=1562522&r1=1562521&r2=1562522&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/SegmentStore.java Wed Jan 29 17:45:24 2014
@@ -16,15 +16,30 @@
*/
package org.apache.jackrabbit.oak.plugins.segment;
-import javax.annotation.Nullable;
import java.util.UUID;
+import javax.annotation.CheckForNull;
+
public interface SegmentStore {
SegmentWriter getWriter();
+ /**
+ * Returns the named journal.
+ *
+ * @param name journal name
+ * @return named journal, or {@code null} if not found
+ */
+ @CheckForNull
Journal getJournal(String name);
+ /**
+ * Reads the identified segment from this store.
+ *
+ * @param segmentId segment identifier
+ * @return identified segment, or {@code null} if not found
+ */
+ @CheckForNull
Segment readSegment(UUID segmentId);
/**
Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java?rev=1562522&r1=1562521&r2=1562522&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/segment/file/FileStore.java Wed Jan 29 17:45:24 2014
@@ -277,19 +277,12 @@ public class FileStore extends AbstractS
@Override @Nonnull
protected Segment loadSegment(UUID id) {
- for (TarFile file : dataFiles) {
- try {
- ByteBuffer buffer = file.readEntry(id);
- if (buffer != null) {
- return createSegment(id, buffer);
- }
- } catch (IOException e) {
- throw new RuntimeException(
- "Failed to access data file " + file, e);
- }
+ LinkedList<TarFile> files = dataFiles;
+ if (isBulkSegmentId(id)) {
+ files = bulkFiles;
}
- for (TarFile file : bulkFiles) {
+ for (TarFile file : files) {
try {
ByteBuffer buffer = file.readEntry(id);
if (buffer != null) {
@@ -297,7 +290,7 @@ public class FileStore extends AbstractS
}
} catch (IOException e) {
throw new RuntimeException(
- "Failed to access bulk file " + file, e);
+ "Failed to access file " + file, e);
}
}
Added: jackrabbit/oak/trunk/oak-http/src/main/java/org/apache/jackrabbit/oak/http/segment/SegmentServlet.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-http/src/main/java/org/apache/jackrabbit/oak/http/segment/SegmentServlet.java?rev=1562522&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-http/src/main/java/org/apache/jackrabbit/oak/http/segment/SegmentServlet.java (added)
+++ jackrabbit/oak/trunk/oak-http/src/main/java/org/apache/jackrabbit/oak/http/segment/SegmentServlet.java Wed Jan 29 17:45:24 2014
@@ -0,0 +1,160 @@
+/*
+ * 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.http.segment;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.util.UUID;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.jackrabbit.oak.plugins.segment.Journal;
+import org.apache.jackrabbit.oak.plugins.segment.RecordId;
+import org.apache.jackrabbit.oak.plugins.segment.Segment;
+import org.apache.jackrabbit.oak.plugins.segment.SegmentStore;
+
+import com.google.common.io.ByteStreams;
+
+public abstract class SegmentServlet extends HttpServlet {
+
+ protected abstract SegmentStore getSegmentStore();
+
+ private UUID getSegmentId(String info) {
+ try {
+ return UUID.fromString(info);
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
+ }
+
+ private RecordId getRecordId(BufferedReader reader) throws IOException {
+ try {
+ return RecordId.fromString(reader.readLine());
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
+ }
+
+ @Override
+ protected void doGet(
+ HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+ String info = request.getPathInfo();
+ if (info == null) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ } else if (info.startsWith("/s/")) {
+ doGetSegment(info.substring(3, info.length()), response);
+ } else if (info.startsWith("/j/")) {
+ doGetJournal(info.substring(3, info.length()), response);
+ } else {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ }
+ }
+
+ @Override
+ protected void doPut(
+ HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+ String info = request.getPathInfo();
+ if (info == null) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ } else if (info.startsWith("/s/")) {
+ doPutSegment(info.substring(3, info.length()), request, response);
+ } else if (info.startsWith("/j/")) {
+ doPutJournal(info.substring(3, info.length()), request, response);
+ } else {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ }
+ }
+
+ private void doGetSegment(
+ String info, HttpServletResponse response)
+ throws ServletException, IOException {
+ UUID uuid = getSegmentId(info);
+ if (uuid == null) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+
+ Segment segment = getSegmentStore().readSegment(uuid);
+ if (segment == null) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+
+ response.setContentType("application/octet-stream");
+ segment.writeTo(response.getOutputStream());
+ }
+
+ private void doPutSegment(
+ String info,
+ HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+ UUID uuid = getSegmentId(info);
+ if (uuid == null) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ } else if (getSegmentStore().readSegment(uuid) != null) {
+ // can't modify an existing segment
+ response.sendError(HttpServletResponse.SC_FORBIDDEN);
+ } else {
+ // TODO: sanity check the segment data?
+ byte[] data = ByteStreams.toByteArray(request.getInputStream());
+ getSegmentStore().writeSegment(uuid, data, 0, data.length);
+ response.setStatus(HttpServletResponse.SC_OK);
+ }
+ }
+
+ private void doGetJournal(
+ String info, HttpServletResponse response)
+ throws ServletException, IOException {
+ Journal journal = getSegmentStore().getJournal(info);
+ if (journal == null) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+
+ response.setContentType("text/plain; charset=UTF-8");
+ response.getWriter().write(journal.getHead().toString());
+ }
+
+ private void doPutJournal(
+ String info,
+ HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+ Journal journal = getSegmentStore().getJournal(info);
+ if (journal == null) {
+ response.sendError(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
+
+ RecordId head = getRecordId(request.getReader());
+ if (head == null) {
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST);
+ return;
+ }
+
+ if (journal.setHead(journal.getHead(), head)) {
+ response.setStatus(HttpServletResponse.SC_OK);
+ } else {
+ response.sendError(HttpServletResponse.SC_CONFLICT);
+ }
+ }
+
+}
Propchange: jackrabbit/oak/trunk/oak-http/src/main/java/org/apache/jackrabbit/oak/http/segment/SegmentServlet.java
------------------------------------------------------------------------------
svn:eol-style = native