Author: frm
Date: Thu Sep 15 14:03:05 2016
New Revision: 1760934
URL: http://svn.apache.org/viewvc?rev=1760934&view=rev
Log:
OAK-4803 - Simplify the client side of the cold standby
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/GetBlobResponseHandler.java
(with props)
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/GetHeadResponseHandler.java
(with props)
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/GetSegmentResponseHandler.java
(with props)
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyClient.java
(with props)
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyDiff.java
- copied, changed from r1760420,
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyApplyDiff.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbySync.java
- copied, changed from r1760651,
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyClient.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbySyncExecution.java
(with props)
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetBlobRequestEncoder.java
(with props)
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetHeadRequestEncoder.java
(with props)
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentRequestEncoder.java
(with props)
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/RequestDecoder.java
(with props)
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/ResponseDecoder.java
(with props)
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/codec/RequestDecoderTest.java
(with props)
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/codec/ResponseDecoderTest.java
(with props)
Removed:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/FailedRequestListener.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/SegmentLoaderHandler.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyApplyDiff.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyClientHandler.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/BlobEncoder.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetBlobRequestDecoder.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetHeadRequestDecoder.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentRequestDecoder.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/IdArrayBasedBlob.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/RecordIdDecoder.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/RecordIdEncoder.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/ReplyDecoder.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/SegmentEncoder.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/SegmentReply.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/store/RemoteSegmentLoader.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/store/StandbyStore.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/codec/GetBlobRequestDecoderTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/codec/GetHeadRequestDecoderTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentRequestDecoderTest.java
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetBlobResponse.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetBlobResponseEncoder.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetHeadResponse.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetHeadResponseEncoder.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentRequest.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentResponse.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentResponseEncoder.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/Messages.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/DefaultStandbyBlobReader.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/DefaultStandbyHeadReader.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/DefaultStandbySegmentReader.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/GetBlobRequestHandler.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/GetHeadRequestHandler.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/GetSegmentRequestHandler.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/ResponseObserverHandler.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/StandbyBlobReader.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/StandbyHeadReader.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/StandbySegmentReader.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/StandbyServer.java
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/store/StandbyStoreService.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/BrokenNetworkTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/DataStoreTestBase.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/FailoverIPRangeTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/FailoverMultipleClientsTestIT.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/FailoverSslTestIT.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/MBeanTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/RecoverTestIT.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/StandbyTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/StandbyTestIT.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/TestBase.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/benchmark/BenchmarkBase.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/benchmark/BulkTransferBenchmark.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/codec/GetBlobResponseEncoderTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/codec/GetHeadResponseEncoderTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentResponseEncoderTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/server/GetBlobRequestHandlerTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/server/GetHeadRequestHandlerTest.java
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/server/GetSegmentRequestHandlerTest.java
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/GetBlobResponseHandler.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/GetBlobResponseHandler.java?rev=1760934&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/GetBlobResponseHandler.java
(added)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/GetBlobResponseHandler.java
Thu Sep 15 14:03:05 2016
@@ -0,0 +1,39 @@
+/*
+ * 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.standby.client;
+
+import java.util.concurrent.BlockingQueue;
+
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import org.apache.jackrabbit.oak.segment.standby.codec.GetBlobResponse;
+
+class GetBlobResponseHandler extends
SimpleChannelInboundHandler<GetBlobResponse> {
+
+ private final BlockingQueue<GetBlobResponse> queue;
+
+ GetBlobResponseHandler(BlockingQueue<GetBlobResponse> queue) {
+ this.queue = queue;
+ }
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, GetBlobResponse
msg) throws Exception {
+ queue.offer(msg);
+ }
+
+}
Propchange:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/GetBlobResponseHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/GetHeadResponseHandler.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/GetHeadResponseHandler.java?rev=1760934&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/GetHeadResponseHandler.java
(added)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/GetHeadResponseHandler.java
Thu Sep 15 14:03:05 2016
@@ -0,0 +1,39 @@
+/*
+ * 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.standby.client;
+
+import java.util.concurrent.BlockingQueue;
+
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import org.apache.jackrabbit.oak.segment.standby.codec.GetHeadResponse;
+
+class GetHeadResponseHandler extends
SimpleChannelInboundHandler<GetHeadResponse> {
+
+ private final BlockingQueue<GetHeadResponse> queue;
+
+ GetHeadResponseHandler(BlockingQueue<GetHeadResponse> queue) {
+ this.queue = queue;
+ }
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, GetHeadResponse
msg) throws Exception {
+ queue.offer(msg);
+ }
+
+}
Propchange:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/GetHeadResponseHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/GetSegmentResponseHandler.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/GetSegmentResponseHandler.java?rev=1760934&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/GetSegmentResponseHandler.java
(added)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/GetSegmentResponseHandler.java
Thu Sep 15 14:03:05 2016
@@ -0,0 +1,39 @@
+/*
+ * 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.standby.client;
+
+import java.util.concurrent.BlockingQueue;
+
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import org.apache.jackrabbit.oak.segment.standby.codec.GetSegmentResponse;
+
+class GetSegmentResponseHandler extends
SimpleChannelInboundHandler<GetSegmentResponse> {
+
+ private final BlockingQueue<GetSegmentResponse> queue;
+
+ GetSegmentResponseHandler(BlockingQueue<GetSegmentResponse> queue) {
+ this.queue = queue;
+ }
+
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, GetSegmentResponse
msg) throws Exception {
+ queue.offer(msg);
+ }
+
+}
Propchange:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/GetSegmentResponseHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyClient.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyClient.java?rev=1760934&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyClient.java
(added)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyClient.java
Thu Sep 15 14:03:05 2016
@@ -0,0 +1,180 @@
+/*
+ * 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.standby.client;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.TimeUnit;
+
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.ChannelPipeline;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.SocketChannel;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
+import io.netty.handler.codec.compression.SnappyFramedDecoder;
+import io.netty.handler.codec.string.StringEncoder;
+import io.netty.handler.ssl.SslContext;
+import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
+import io.netty.handler.timeout.ReadTimeoutHandler;
+import io.netty.util.CharsetUtil;
+import org.apache.jackrabbit.oak.segment.standby.codec.GetBlobRequest;
+import org.apache.jackrabbit.oak.segment.standby.codec.GetBlobRequestEncoder;
+import org.apache.jackrabbit.oak.segment.standby.codec.GetBlobResponse;
+import org.apache.jackrabbit.oak.segment.standby.codec.GetHeadRequest;
+import org.apache.jackrabbit.oak.segment.standby.codec.GetHeadRequestEncoder;
+import org.apache.jackrabbit.oak.segment.standby.codec.GetHeadResponse;
+import org.apache.jackrabbit.oak.segment.standby.codec.GetSegmentRequest;
+import
org.apache.jackrabbit.oak.segment.standby.codec.GetSegmentRequestEncoder;
+import org.apache.jackrabbit.oak.segment.standby.codec.GetSegmentResponse;
+import org.apache.jackrabbit.oak.segment.standby.codec.ResponseDecoder;
+
+class StandbyClient implements AutoCloseable {
+
+ private final BlockingQueue<GetHeadResponse> headQueue = new
LinkedBlockingDeque<>();
+
+ private final BlockingQueue<GetSegmentResponse> segmentQueue = new
LinkedBlockingDeque<>();
+
+ private final BlockingQueue<GetBlobResponse> blobQueue = new
LinkedBlockingDeque<>();
+
+ private final boolean secure;
+
+ private final int readTimeoutMs;
+
+ private String clientId;
+
+ private NioEventLoopGroup group;
+
+ private Channel channel;
+
+ StandbyClient(String clientId, boolean secure, int readTimeoutMs) {
+ this.clientId = clientId;
+ this.secure = secure;
+ this.readTimeoutMs = readTimeoutMs;
+ }
+
+ void connect(String host, int port) throws Exception {
+ group = new NioEventLoopGroup();
+
+ final SslContext sslContext;
+
+ if (secure) {
+ sslContext =
SslContext.newClientContext(InsecureTrustManagerFactory.INSTANCE);
+ } else {
+ sslContext = null;
+ }
+
+ Bootstrap b = new Bootstrap()
+ .group(group)
+ .channel(NioSocketChannel.class)
+ .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, readTimeoutMs)
+ .option(ChannelOption.TCP_NODELAY, true)
+ .option(ChannelOption.SO_REUSEADDR, true)
+ .option(ChannelOption.SO_KEEPALIVE, true)
+ .handler(new ChannelInitializer<SocketChannel>() {
+
+ @Override
+ public void initChannel(SocketChannel ch) throws Exception
{
+ ChannelPipeline p = ch.pipeline();
+
+ if (sslContext != null) {
+ p.addLast(sslContext.newHandler(ch.alloc()));
+ }
+
+ p.addLast(new ReadTimeoutHandler(readTimeoutMs,
TimeUnit.MILLISECONDS));
+
+ // Decoders
+
+ p.addLast(new SnappyFramedDecoder(true));
+
+ // Such a big max frame length is needed because blob
+ // values are sent in one big message. In future
+ // versions of the protocol, sending binaries in chunks
+ // should be considered instead.
+
+ p.addLast(new
LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4));
+ p.addLast(new ResponseDecoder());
+
+ // Encoders
+
+ p.addLast(new StringEncoder(CharsetUtil.UTF_8));
+ p.addLast(new GetHeadRequestEncoder());
+ p.addLast(new GetSegmentRequestEncoder());
+ p.addLast(new GetBlobRequestEncoder());
+
+ // Handlers
+
+ p.addLast(new GetHeadResponseHandler(headQueue));
+ p.addLast(new GetSegmentResponseHandler(segmentQueue));
+ p.addLast(new GetBlobResponseHandler(blobQueue));
+ }
+
+ });
+
+ channel = b.connect(host, port).sync().channel();
+ }
+
+ @Override
+ public void close() throws InterruptedException {
+ channel.close().sync();
+ channel = null;
+
+ group.shutdownGracefully();
+ group = null;
+ }
+
+ String getHead() throws InterruptedException {
+ channel.writeAndFlush(new GetHeadRequest(clientId));
+
+ GetHeadResponse response = headQueue.poll(readTimeoutMs,
TimeUnit.MILLISECONDS);
+
+ if (response == null) {
+ return null;
+ }
+
+ return response.getHeadRecordId();
+ }
+
+ byte[] getSegment(String segmentId) throws InterruptedException {
+ channel.writeAndFlush(new GetSegmentRequest(clientId, segmentId));
+
+ GetSegmentResponse response = segmentQueue.poll(readTimeoutMs,
TimeUnit.MILLISECONDS);
+
+ if (response == null) {
+ return null;
+ }
+
+ return response.getSegmentData();
+ }
+
+ byte[] getBlob(String blobId) throws InterruptedException {
+ channel.writeAndFlush(new GetBlobRequest(clientId, blobId));
+
+ GetBlobResponse response = blobQueue.poll(readTimeoutMs,
TimeUnit.MILLISECONDS);
+
+ if (response == null) {
+ return null;
+ }
+
+ return response.getBlobData();
+ }
+
+}
Propchange:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyClient.java
------------------------------------------------------------------------------
svn:eol-style = native
Copied:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyDiff.java
(from r1760420,
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyApplyDiff.java)
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyDiff.java?p2=jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyDiff.java&p1=jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyApplyDiff.java&r1=1760420&r2=1760934&rev=1760934&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyApplyDiff.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyDiff.java
Thu Sep 15 14:03:05 2016
@@ -22,8 +22,10 @@ package org.apache.jackrabbit.oak.segmen
import static org.apache.jackrabbit.oak.api.Type.BINARIES;
import static org.apache.jackrabbit.oak.api.Type.BINARY;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
+import com.google.common.base.Supplier;
import org.apache.jackrabbit.oak.api.Blob;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.Type;
@@ -31,29 +33,29 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.segment.RecordId;
import org.apache.jackrabbit.oak.segment.SegmentBlob;
import org.apache.jackrabbit.oak.segment.SegmentNodeState;
-import org.apache.jackrabbit.oak.segment.standby.store.RemoteSegmentLoader;
-import org.apache.jackrabbit.oak.segment.standby.store.StandbyStore;
+import org.apache.jackrabbit.oak.segment.file.FileStore;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.apache.jackrabbit.oak.spi.state.NodeState;
import org.apache.jackrabbit.oak.spi.state.NodeStateDiff;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-class StandbyApplyDiff implements NodeStateDiff {
+class StandbyDiff implements NodeStateDiff {
- private static final Logger log = LoggerFactory
- .getLogger(StandbyApplyDiff.class);
+ private static final Logger log =
LoggerFactory.getLogger(StandbyDiff.class);
private final NodeBuilder builder;
- private final StandbyStore store;
+ private final FileStore store;
- private final boolean hasDataStore;
+ private final StandbyClient client;
- private final RemoteSegmentLoader loader;
+ private final boolean hasDataStore;
private final String path;
+ private final Supplier<Boolean> running;
+
/**
* read-only traversal of the diff that has 2 properties: one is to log all
* the content changes, second is to drill down to properly level, so that
@@ -61,60 +63,70 @@ class StandbyApplyDiff implements NodeSt
*/
private final boolean logOnly;
- public StandbyApplyDiff(NodeBuilder builder, StandbyStore store,
- RemoteSegmentLoader loader) {
- this(builder, store, loader, "/", false);
+ StandbyDiff(NodeBuilder builder, FileStore store, StandbyClient client,
Supplier<Boolean> running) {
+ this(builder, store, client, "/", false, running);
}
- private StandbyApplyDiff(NodeBuilder builder, StandbyStore store,
- RemoteSegmentLoader loader, String path, boolean logOnly) {
+ private StandbyDiff(NodeBuilder builder, FileStore store, StandbyClient
client, String path, boolean logOnly, Supplier<Boolean> running) {
this.builder = builder;
this.store = store;
this.hasDataStore = store.getBlobStore() != null;
- this.loader = loader;
+ this.client = client;
this.path = path;
this.logOnly = logOnly;
+ this.running = running;
+ }
+
+ private boolean stop() {
+ return !running.get();
}
@Override
public boolean propertyAdded(PropertyState after) {
- if (!loader.isRunning()) {
+ if (stop()) {
return false;
}
- if (!logOnly) {
- builder.setProperty(binaryCheck(after));
- } else {
+
+ if (logOnly) {
binaryCheck(after);
+ } else {
+ builder.setProperty(binaryCheck(after));
}
+
return true;
}
@Override
public boolean propertyChanged(PropertyState before, PropertyState after) {
- if (!loader.isRunning()) {
+ if (stop()) {
return false;
}
- if (!logOnly) {
- builder.setProperty(binaryCheck(after));
- } else {
+
+ if (logOnly) {
binaryCheck(after);
+ } else {
+ builder.setProperty(binaryCheck(after));
}
+
return true;
}
@Override
public boolean propertyDeleted(PropertyState before) {
- if (!loader.isRunning()) {
+ if (stop()) {
return false;
}
+
if (!logOnly) {
builder.removeProperty(before.getName());
}
+
return true;
}
private PropertyState binaryCheck(PropertyState property) {
Type<?> type = property.getType();
+
if (type == BINARY) {
binaryCheck(property.getValue(Type.BINARY), property.getName());
} else if (type == BINARIES) {
@@ -122,93 +134,100 @@ class StandbyApplyDiff implements NodeSt
binaryCheck(blob, property.getName());
}
}
+
return property;
}
private void binaryCheck(Blob b, String pName) {
if (b instanceof SegmentBlob) {
- SegmentBlob sb = (SegmentBlob) b;
- // verify if the blob exists
- if (sb.isExternal() && hasDataStore && b.getReference() == null) {
- String blobId = sb.getBlobId();
- if (blobId != null) {
- readBlob(blobId, pName);
- }
- }
+ binaryCheck((SegmentBlob) b, pName);
} else {
- log.warn("Unknown Blob {} at {}, ignoring", b.getClass().getName(),
- path + "#" + pName);
+ log.warn("Unknown Blob {} at {}, ignoring",
b.getClass().getName(), path + "#" + pName);
}
}
- private void readBlob(String blobId, String pName) {
- Blob read = loader.readBlob(blobId);
- if (read != null) {
+ private void binaryCheck(SegmentBlob sb, String pName) {
+ if (sb.isExternal() && hasDataStore && sb.getReference() == null) {
+ String blobId = sb.getBlobId();
+
+ if (blobId == null) {
+ return;
+ }
+
try {
- store.getBlobStore().writeBlob(read.getNewStream());
- } catch (IOException f) {
- throw new IllegalStateException("Unable to persist blob "
- + blobId + " at " + path + "#" + pName, f);
+ readBlob(blobId, pName);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
}
- } else {
- throw new IllegalStateException("Unable to load remote blob "
- + blobId + " at " + path + "#" + pName);
+ }
+ }
+
+ private void readBlob(String blobId, String pName) throws
InterruptedException {
+ byte[] data = client.getBlob(blobId);
+
+ if (data == null) {
+ throw new IllegalStateException("Unable to load remote blob " +
blobId + " at " + path + "#" + pName);
+ }
+
+ try {
+ store.getBlobStore().writeBlob(new ByteArrayInputStream(data));
+ } catch (IOException f) {
+ throw new IllegalStateException("Unable to persist blob " + blobId
+ " at " + path + "#" + pName, f);
}
}
@Override
public boolean childNodeAdded(String name, NodeState after) {
- return process(name, "childNodeAdded", EmptyNodeState.EMPTY_NODE,
- after);
+ return process(name, "childNodeAdded", EmptyNodeState.EMPTY_NODE,
after);
}
@Override
- public boolean childNodeChanged(String name, NodeState before,
- NodeState after) {
+ public boolean childNodeChanged(String name, NodeState before, NodeState
after) {
return process(name, "childNodeChanged", before, after);
}
- private boolean process(String name, String op, NodeState before,
- NodeState after) {
- if (!loader.isRunning()) {
+ private boolean process(String name, String op, NodeState before,
NodeState after) {
+ if (stop()) {
return false;
}
+
if (after instanceof SegmentNodeState) {
if (log.isTraceEnabled()) {
- log.trace("{} {}, readonly binary check {}", op, path + name,
- logOnly);
+ log.trace("{} {}, readonly binary check {}", op, path + name,
logOnly);
}
+
if (!logOnly) {
RecordId id = ((SegmentNodeState) after).getRecordId();
- builder.setChildNode(name, store.newSegmentNodeState(id));
+ builder.setChildNode(name, store.getReader().readNode(id));
}
+
if ("checkpoints".equals(name)) {
// if we're on the /checkpoints path, there's no need for a
deep
// traversal to verify binaries
return true;
}
- if (hasDataStore) {
- // has external datastore, we need a deep
- // traversal to verify binaries
- return after.compareAgainstBaseState(before,
- new StandbyApplyDiff(builder.getChildNode(name), store,
- loader, path + name + "/", true));
- } else {
+
+ if (!hasDataStore) {
return true;
+
}
+ // has external datastore, we need a deep
+ // traversal to verify binaries
+ return after.compareAgainstBaseState(before, new
StandbyDiff(builder.getChildNode(name), store, client, path + name + "/", true,
running));
}
+
return false;
}
@Override
public boolean childNodeDeleted(String name, NodeState before) {
- if (!loader.isRunning()) {
- return false;
- }
log.trace("childNodeDeleted {}, RO:{}", path + name, logOnly);
+
if (!logOnly) {
builder.getChildNode(name).remove();
}
+
return true;
}
+
}
Copied:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbySync.java
(from r1760651,
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyClient.java)
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbySync.java?p2=jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbySync.java&p1=jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyClient.java&r1=1760651&r2=1760934&rev=1760934&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbyClient.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbySync.java
Thu Sep 15 14:03:05 2016
@@ -16,12 +16,15 @@
* specific language governing permissions and limitations
* under the License.
*/
+
package org.apache.jackrabbit.oak.segment.standby.client;
+import static org.apache.jackrabbit.oak.commons.IOUtils.humanReadableByteCount;
+
import java.io.Closeable;
+import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.util.UUID;
-import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.management.MBeanServer;
@@ -29,61 +32,51 @@ import javax.management.ObjectName;
import javax.management.StandardMBean;
import javax.net.ssl.SSLException;
-import io.netty.bootstrap.Bootstrap;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.ChannelOption;
-import io.netty.channel.ChannelPipeline;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.SocketChannel;
-import io.netty.channel.socket.nio.NioSocketChannel;
-import io.netty.handler.codec.compression.SnappyFramedDecoder;
-import io.netty.handler.codec.string.StringEncoder;
-import io.netty.handler.ssl.SslContext;
-import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
-import io.netty.handler.timeout.ReadTimeoutHandler;
-import io.netty.util.CharsetUtil;
-import org.apache.jackrabbit.oak.segment.SegmentStore;
+import com.google.common.base.Supplier;
import org.apache.jackrabbit.oak.segment.file.FileStore;
-import org.apache.jackrabbit.oak.segment.standby.codec.RecordIdDecoder;
import org.apache.jackrabbit.oak.segment.standby.jmx.ClientStandbyStatusMBean;
import org.apache.jackrabbit.oak.segment.standby.jmx.StandbyStatusMBean;
import org.apache.jackrabbit.oak.segment.standby.store.CommunicationObserver;
-import org.apache.jackrabbit.oak.segment.standby.store.StandbyStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public final class StandbyClient implements ClientStandbyStatusMBean,
Runnable, Closeable {
+public final class StandbySync implements ClientStandbyStatusMBean, Runnable,
Closeable {
+
public static final String CLIENT_ID_PROPERTY_NAME = "standbyID";
- private static final Logger log = LoggerFactory
- .getLogger(StandbyClient.class);
+ private static final Logger log =
LoggerFactory.getLogger(StandbySync.class);
private final String host;
+
private final int port;
+
private final int readTimeoutMs;
+
private final boolean autoClean;
- private final StandbyStore store;
private final CommunicationObserver observer;
- private StandbyClientHandler handler;
- private EventLoopGroup group;
- private SslContext sslContext;
+
+ private final boolean secure;
+
private boolean active = false;
+
private int failedRequests;
+
private long lastSuccessfulRequest;
+
private volatile String state;
+
private final Object sync = new Object();
+ private final FileStore fileStore;
+
private final AtomicBoolean running = new AtomicBoolean(true);
private long syncStartTimestamp;
+
private long syncEndTimestamp;
- public StandbyClient(String host, int port, FileStore store,
- boolean secure, int readTimeoutMs, boolean autoClean)
- throws SSLException {
+ public StandbySync(String host, int port, FileStore store, boolean secure,
int readTimeoutMs, boolean autoClean) throws SSLException {
this.state = STATUS_INITIALIZING;
this.lastSuccessfulRequest = -1;
this.syncStartTimestamp = -1;
@@ -91,20 +84,17 @@ public final class StandbyClient impleme
this.failedRequests = 0;
this.host = host;
this.port = port;
- if (secure) {
- this.sslContext =
SslContext.newClientContext(InsecureTrustManagerFactory.INSTANCE);
- }
+ this.secure = secure;
this.readTimeoutMs = readTimeoutMs;
this.autoClean = autoClean;
- this.store = new StandbyStore(store);
+ this.fileStore = store;
String s = System.getProperty(CLIENT_ID_PROPERTY_NAME);
this.observer = new CommunicationObserver((s == null || s.length() ==
0) ? UUID.randomUUID().toString() : s);
final MBeanServer jmxServer =
ManagementFactory.getPlatformMBeanServer();
try {
jmxServer.registerMBean(new StandardMBean(this,
ClientStandbyStatusMBean.class), new ObjectName(this.getMBeanName()));
- }
- catch (Exception e) {
+ } catch (Exception e) {
log.error("can register standby status mbean", e);
}
}
@@ -119,12 +109,10 @@ public final class StandbyClient impleme
final MBeanServer jmxServer =
ManagementFactory.getPlatformMBeanServer();
try {
jmxServer.unregisterMBean(new ObjectName(this.getMBeanName()));
- }
- catch (Exception e) {
+ } catch (Exception e) {
log.error("can unregister standby status mbean", e);
}
observer.unregister();
- shutdownNetty();
state = STATUS_CLOSED;
}
@@ -134,49 +122,33 @@ public final class StandbyClient impleme
return;
}
- Bootstrap b;
- synchronized (this.sync) {
- if (this.active) {
+ state = STATUS_STARTING;
+
+ synchronized (sync) {
+ if (active) {
return;
}
- state = STATUS_STARTING;
- handler = new StandbyClientHandler(this.store, observer, running,
- readTimeoutMs, autoClean);
- group = new NioEventLoopGroup();
-
- b = new Bootstrap();
- b.group(group);
- b.channel(NioSocketChannel.class);
- b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, readTimeoutMs);
- b.option(ChannelOption.TCP_NODELAY, true);
- b.option(ChannelOption.SO_REUSEADDR, true);
- b.option(ChannelOption.SO_KEEPALIVE, true);
-
- b.handler(new ChannelInitializer<SocketChannel>() {
- @Override
- public void initChannel(SocketChannel ch) throws Exception {
- ChannelPipeline p = ch.pipeline();
- if (sslContext != null) {
- p.addLast(sslContext.newHandler(ch.alloc()));
- }
- p.addLast("readTimeoutHandler", new ReadTimeoutHandler(
- readTimeoutMs, TimeUnit.MILLISECONDS));
- p.addLast(new StringEncoder(CharsetUtil.UTF_8));
- p.addLast(new SnappyFramedDecoder(true));
- p.addLast(new RecordIdDecoder(store));
- p.addLast(handler);
- }
- });
state = STATUS_RUNNING;
- this.active = true;
+ active = true;
}
try {
long startTimestamp = System.currentTimeMillis();
- // Start the client.
- ChannelFuture f = b.connect(host, port).sync();
- // Wait until the connection is closed.
- f.channel().closeFuture().sync();
+ try (StandbyClient client = new StandbyClient(observer.getID(),
secure, readTimeoutMs)) {
+ client.connect(host, port);
+
+ long sizeBefore = fileStore.getStats().getApproximateSize();
+ new StandbySyncExecution(fileStore, client,
newRunningSupplier()).execute();
+ long sizeAfter = fileStore.getStats().getApproximateSize();
+
+ if (autoClean && sizeBefore > 0) {
+ // if size gain is over 25% call cleanup
+ if (sizeAfter - sizeBefore > 0.25 * sizeBefore) {
+ log.info("Store size increased from {} to {}, will run
cleanup.", humanReadableByteCount(sizeBefore),
humanReadableByteCount(sizeAfter));
+ fileStore.cleanup();
+ }
+ }
+ }
this.failedRequests = 0;
this.syncStartTimestamp = startTimestamp;
this.syncEndTimestamp = System.currentTimeMillis();
@@ -187,20 +159,19 @@ public final class StandbyClient impleme
} finally {
synchronized (this.sync) {
this.active = false;
- shutdownNetty();
}
}
}
- private void shutdownNetty() {
- if (handler != null) {
- handler.close();
- handler = null;
- }
- if (group != null && !group.isShuttingDown()) {
- group.shutdownGracefully(0, 1,
TimeUnit.SECONDS).syncUninterruptibly();
- group = null;
- }
+ private Supplier<Boolean> newRunningSupplier() {
+ return new Supplier<Boolean>() {
+
+ @Override
+ public Boolean get() {
+ return running.get();
+ }
+
+ };
}
@Override
@@ -237,8 +208,10 @@ public final class StandbyClient impleme
@Override
public int getSecondsSinceLastSuccess() {
- if (this.lastSuccessfulRequest < 0) return -1;
- return (int)(System.currentTimeMillis() / 1000 -
this.lastSuccessfulRequest);
+ if (this.lastSuccessfulRequest < 0) {
+ return -1;
+ }
+ return (int) (System.currentTimeMillis() / 1000 -
this.lastSuccessfulRequest);
}
@Override
@@ -253,7 +226,11 @@ public final class StandbyClient impleme
@Override
public void cleanup() {
- store.cleanup();
+ try {
+ fileStore.cleanup();
+ } catch (IOException e) {
+ log.error("Error while cleaning up", e);
+ }
}
@Override
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbySyncExecution.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbySyncExecution.java?rev=1760934&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbySyncExecution.java
(added)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbySyncExecution.java
Thu Sep 15 14:03:05 2016
@@ -0,0 +1,166 @@
+/*
+ * 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.standby.client;
+
+import static com.google.common.collect.Maps.newHashMap;
+import static com.google.common.collect.Sets.newHashSet;
+
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.annotation.Nonnull;
+
+import com.google.common.base.Supplier;
+import org.apache.jackrabbit.oak.segment.RecordId;
+import org.apache.jackrabbit.oak.segment.Segment;
+import org.apache.jackrabbit.oak.segment.SegmentId;
+import org.apache.jackrabbit.oak.segment.SegmentNodeBuilder;
+import org.apache.jackrabbit.oak.segment.SegmentNodeState;
+import org.apache.jackrabbit.oak.segment.SegmentNotFoundException;
+import org.apache.jackrabbit.oak.segment.file.FileStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Encapsulates the algorithm for a single execution of the synchronization
+ * process between the primary and the standby instance. It also contains
+ * temporary state that is supposed to be used for the lifetime of a
+ * synchronization run.
+ */
+class StandbySyncExecution {
+
+ private static final Logger log =
LoggerFactory.getLogger(StandbySyncExecution.class);
+
+ private final FileStore store;
+
+ private final StandbyClient client;
+
+ private final Supplier<Boolean> running;
+
+ private final Set<UUID> visited = newHashSet();
+
+ private final Map<UUID, Segment> cache = newHashMap();
+
+ StandbySyncExecution(FileStore store, StandbyClient client,
Supplier<Boolean> running) {
+ this.store = store;
+ this.client = client;
+ this.running = running;
+ }
+
+ void execute() throws Exception {
+ RecordId remoteHead = getHead();
+
+ if (remoteHead.equals(store.getHead().getRecordId())) {
+ return;
+ }
+
+ long t = System.currentTimeMillis();
+ SegmentNodeState before = store.getHead();
+ SegmentNodeBuilder builder = before.builder();
+ SegmentNodeState current = newSegmentNodeState(remoteHead);
+ compareAgainstBaseState(current, before, builder);
+ boolean ok = setHead(before, builder.getNodeState());
+ log.debug("updated head state successfully: {} in {}ms.", ok,
System.currentTimeMillis() - t);
+ }
+
+ private RecordId getHead() throws Exception {
+ return RecordId.fromString(store, client.getHead());
+ }
+
+ private SegmentNodeState newSegmentNodeState(RecordId id) {
+ return store.getReader().readNode(id);
+ }
+
+ private boolean setHead(@Nonnull SegmentNodeState expected, @Nonnull
SegmentNodeState head) {
+ return store.getRevisions().setHead(expected.getRecordId(),
head.getRecordId());
+ }
+
+ private boolean compareAgainstBaseState(SegmentNodeState current,
SegmentNodeState before, SegmentNodeBuilder builder) throws Exception {
+ while (true) {
+ try {
+ return current.compareAgainstBaseState(before, new
StandbyDiff(builder, store, client, running));
+ } catch (SegmentNotFoundException e) {
+ log.info("Found missing segment {}", e.getSegmentId());
+
copySegmentHierarchyFromPrimary(UUID.fromString(e.getSegmentId()));
+ }
+ }
+ }
+
+ private void copySegmentHierarchyFromPrimary(UUID segmentId) throws
Exception {
+ LinkedList<UUID> batch = new LinkedList<>();
+
+ batch.offer(segmentId);
+
+ while (batch.size() > 0) {
+ UUID current = batch.remove();
+
+ log.info("Loading segment {}", current);
+ Segment segment = copySegmentFromPrimary(current);
+
+ log.info("Marking segment {} as loaded", current);
+ visited.add(current);
+
+ if (!SegmentId.isDataSegmentId(current.getLeastSignificantBits()))
{
+ continue;
+ }
+
+ log.info("Inspecting segment {} for references", current);
+ for (int i = 0; i < segment.getReferencedSegmentIdCount(); i++) {
+ UUID referenced = segment.getReferencedSegmentId(i);
+
+ if (visited.contains(referenced)) {
+ continue;
+ }
+
+ log.info("Found reference from {} to {}", current, referenced);
+ if
(SegmentId.isDataSegmentId(referenced.getLeastSignificantBits())) {
+ batch.add(referenced);
+ } else {
+ batch.addFirst(referenced);
+ }
+ }
+ }
+ }
+
+ private Segment copySegmentFromPrimary(UUID uuid) throws Exception {
+ Segment result = cache.get(uuid);
+
+ if (result != null) {
+ log.info("Segment {} was found in the local cache", uuid);
+ return result;
+ }
+
+ byte[] data = client.getSegment(uuid.toString());
+
+ if (data == null) {
+ throw new IllegalStateException("Unable to read segment " + uuid);
+ }
+
+ long msb = uuid.getMostSignificantBits();
+ long lsb = uuid.getLeastSignificantBits();
+ SegmentId segmentId = store.newSegmentId(msb, lsb);
+ store.writeSegment(segmentId, data, 0, data.length);
+ result = segmentId.getSegment();
+ cache.put(uuid, result);
+ return result;
+ }
+
+}
+
Propchange:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/client/StandbySyncExecution.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetBlobRequestEncoder.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetBlobRequestEncoder.java?rev=1760934&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetBlobRequestEncoder.java
(added)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetBlobRequestEncoder.java
Thu Sep 15 14:03:05 2016
@@ -0,0 +1,37 @@
+/*
+ * 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.standby.codec;
+
+import java.util.List;
+
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToMessageEncoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GetBlobRequestEncoder extends
MessageToMessageEncoder<GetBlobRequest> {
+
+ private final Logger log =
LoggerFactory.getLogger(GetBlobRequestEncoder.class);
+
+ @Override
+ protected void encode(ChannelHandlerContext ctx, GetBlobRequest msg,
List<Object> out) throws Exception {
+ log.debug("Sending request from client {} for blob {}",
msg.getClientId(), msg.getBlobId());
+ out.add(Messages.newGetBlobRequest(msg.getClientId(),
msg.getBlobId()));
+ }
+
+}
Propchange:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetBlobRequestEncoder.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetBlobResponse.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetBlobResponse.java?rev=1760934&r1=1760933&r2=1760934&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetBlobResponse.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetBlobResponse.java
Thu Sep 15 14:03:05 2016
@@ -17,25 +17,30 @@
package org.apache.jackrabbit.oak.segment.standby.codec;
-import org.apache.jackrabbit.oak.api.Blob;
-
public class GetBlobResponse {
private final String clientId;
- private final Blob blob;
+ private final String blobId;
+
+ private final byte[] blobData;
- public GetBlobResponse(String clientId, Blob blob) {
+ public GetBlobResponse(String clientId, String blobId, byte[] blobData) {
this.clientId = clientId;
- this.blob = blob;
+ this.blobId = blobId;
+ this.blobData = blobData;
}
public String getClientId() {
return clientId;
}
- public Blob getBlob() {
- return blob;
+ public String getBlobId() {
+ return blobId;
+ }
+
+ public byte[] getBlobData() {
+ return blobData;
}
}
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetBlobResponseEncoder.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetBlobResponseEncoder.java?rev=1760934&r1=1760933&r2=1760934&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetBlobResponseEncoder.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetBlobResponseEncoder.java
Thu Sep 15 14:03:05 2016
@@ -17,7 +17,6 @@
package org.apache.jackrabbit.oak.segment.standby.codec;
-import java.io.InputStream;
import java.nio.charset.Charset;
import com.google.common.hash.Hasher;
@@ -25,8 +24,6 @@ import com.google.common.hash.Hashing;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
-import org.apache.commons.io.IOUtils;
-import org.apache.jackrabbit.oak.api.Blob;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -36,30 +33,22 @@ public class GetBlobResponseEncoder exte
@Override
protected void encode(ChannelHandlerContext ctx, GetBlobResponse msg,
ByteBuf out) throws Exception {
- log.debug("Sending blob {} to client {}",
msg.getBlob().getContentIdentity(), msg.getClientId());
- encode(msg.getBlob(), out);
+ log.debug("Sending blob {} to client {}", msg.getBlobId(),
msg.getClientId());
+ encode(msg.getBlobId(), msg.getBlobData(), out);
}
- private void encode(Blob b, ByteBuf out) throws Exception {
- byte[] bytes;
-
- try (InputStream s = b.getNewStream()) {
- bytes = IOUtils.toByteArray(s);
- }
+ private void encode(String blobId, byte[] data, ByteBuf out) throws
Exception {
+ byte[] blobIdBytes = blobId.getBytes(Charset.forName("UTF-8"));
Hasher hasher = Hashing.murmur3_32().newHasher();
- long hash = hasher.putBytes(bytes).hash().padToLong();
+ long hash = hasher.putBytes(data).hash().padToLong();
- out.writeInt(bytes.length);
+ out.writeInt(1 + 4 + blobIdBytes.length + 8 + data.length);
out.writeByte(Messages.HEADER_BLOB);
-
- String bid = b.getContentIdentity();
- byte[] id = bid.getBytes(Charset.forName("UTF-8"));
- out.writeInt(id.length);
- out.writeBytes(id);
-
+ out.writeInt(blobIdBytes.length);
+ out.writeBytes(blobIdBytes);
out.writeLong(hash);
- out.writeBytes(bytes);
+ out.writeBytes(data);
}
}
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetHeadRequestEncoder.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetHeadRequestEncoder.java?rev=1760934&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetHeadRequestEncoder.java
(added)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetHeadRequestEncoder.java
Thu Sep 15 14:03:05 2016
@@ -0,0 +1,37 @@
+/*
+ * 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.standby.codec;
+
+import java.util.List;
+
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToMessageEncoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GetHeadRequestEncoder extends
MessageToMessageEncoder<GetHeadRequest> {
+
+ private static final Logger log =
LoggerFactory.getLogger(GetHeadRequestEncoder.class);
+
+ @Override
+ protected void encode(ChannelHandlerContext ctx, GetHeadRequest msg,
List<Object> out) throws Exception {
+ log.debug("Sending request from client {} for current head",
msg.getClientId());
+ out.add(Messages.newGetHeadRequest(msg.getClientId()));
+ }
+
+}
Propchange:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetHeadRequestEncoder.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetHeadResponse.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetHeadResponse.java?rev=1760934&r1=1760933&r2=1760934&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetHeadResponse.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetHeadResponse.java
Thu Sep 15 14:03:05 2016
@@ -17,15 +17,13 @@
package org.apache.jackrabbit.oak.segment.standby.codec;
-import org.apache.jackrabbit.oak.segment.RecordId;
-
public class GetHeadResponse {
private final String clientId;
- private final RecordId headRecordId;
+ private final String headRecordId;
- public GetHeadResponse(String clientId, RecordId headRecordId) {
+ public GetHeadResponse(String clientId, String headRecordId) {
this.clientId = clientId;
this.headRecordId = headRecordId;
}
@@ -34,7 +32,7 @@ public class GetHeadResponse {
return clientId;
}
- public RecordId getHeadRecordId() {
+ public String getHeadRecordId() {
return headRecordId;
}
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetHeadResponseEncoder.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetHeadResponseEncoder.java?rev=1760934&r1=1760933&r2=1760934&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetHeadResponseEncoder.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetHeadResponseEncoder.java
Thu Sep 15 14:03:05 2016
@@ -34,7 +34,7 @@ public class GetHeadResponseEncoder exte
@Override
protected void encode(ChannelHandlerContext ctx, GetHeadResponse msg,
ByteBuf out) throws Exception {
log.debug("Sending head {} to client {}", msg.getHeadRecordId(),
msg.getClientId());
- byte[] body =
msg.getHeadRecordId().toString().getBytes(CharsetUtil.UTF_8);
+ byte[] body = msg.getHeadRecordId().getBytes(CharsetUtil.UTF_8);
out.writeInt(body.length + 1);
out.writeByte(Messages.HEADER_RECORD);
out.writeBytes(body);
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentRequest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentRequest.java?rev=1760934&r1=1760933&r2=1760934&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentRequest.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentRequest.java
Thu Sep 15 14:03:05 2016
@@ -17,15 +17,13 @@
package org.apache.jackrabbit.oak.segment.standby.codec;
-import java.util.UUID;
-
public class GetSegmentRequest {
private final String clientId;
- private final UUID segmentId;
+ private final String segmentId;
- public GetSegmentRequest(String clientId, UUID segmentId) {
+ public GetSegmentRequest(String clientId, String segmentId) {
this.clientId = clientId;
this.segmentId = segmentId;
}
@@ -34,7 +32,7 @@ public class GetSegmentRequest {
return clientId;
}
- public UUID getSegmentId() {
+ public String getSegmentId() {
return segmentId;
}
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentRequestEncoder.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentRequestEncoder.java?rev=1760934&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentRequestEncoder.java
(added)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentRequestEncoder.java
Thu Sep 15 14:03:05 2016
@@ -0,0 +1,37 @@
+/*
+ * 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.standby.codec;
+
+import java.util.List;
+
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToMessageEncoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GetSegmentRequestEncoder extends
MessageToMessageEncoder<GetSegmentRequest> {
+
+ private final Logger log =
LoggerFactory.getLogger(GetSegmentRequestEncoder.class);
+
+ @Override
+ protected void encode(ChannelHandlerContext ctx, GetSegmentRequest msg,
List<Object> out) throws Exception {
+ log.debug("Sending request from client {} for segment {}",
msg.getClientId(), msg.getSegmentId());
+ out.add(Messages.newGetSegmentRequest(msg.getClientId(),
msg.getSegmentId()));
+ }
+
+}
Propchange:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentRequestEncoder.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentResponse.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentResponse.java?rev=1760934&r1=1760933&r2=1760934&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentResponse.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentResponse.java
Thu Sep 15 14:03:05 2016
@@ -17,25 +17,30 @@
package org.apache.jackrabbit.oak.segment.standby.codec;
-import org.apache.jackrabbit.oak.segment.Segment;
-
public class GetSegmentResponse {
private final String clientId;
- private final Segment segment;
+ private final String segmentId;
+
+ private final byte[] segmentData;
- public GetSegmentResponse(String clientId, Segment segment) {
+ public GetSegmentResponse(String clientId, String segmentId, byte[]
segmentData) {
this.clientId = clientId;
- this.segment = segment;
+ this.segmentId = segmentId;
+ this.segmentData = segmentData;
}
public String getClientId() {
return clientId;
}
- public Segment getSegment() {
- return segment;
+ public String getSegmentId() {
+ return segmentId;
+ }
+
+ public byte[] getSegmentData() {
+ return segmentData;
}
}
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentResponseEncoder.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentResponseEncoder.java?rev=1760934&r1=1760933&r2=1760934&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentResponseEncoder.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/GetSegmentResponseEncoder.java
Thu Sep 15 14:03:05 2016
@@ -17,15 +17,13 @@
package org.apache.jackrabbit.oak.segment.standby.codec;
-import java.io.ByteArrayOutputStream;
+import java.util.UUID;
import com.google.common.hash.Hasher;
import com.google.common.hash.Hashing;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
-import org.apache.jackrabbit.oak.segment.Segment;
-import org.apache.jackrabbit.oak.segment.SegmentId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,27 +40,23 @@ public class GetSegmentResponseEncoder e
@Override
protected void encode(ChannelHandlerContext ctx, GetSegmentResponse msg,
ByteBuf out) throws Exception {
- log.debug("Sending segment {} to client {}",
msg.getSegment().getSegmentId(), msg.getClientId());
- encode(msg.getSegment(), out);
+ log.debug("Sending segment {} to client {}", msg.getSegmentId(),
msg.getClientId());
+ encode(msg.getSegmentId(), msg.getSegmentData(), out);
}
- private void encode(Segment s, ByteBuf out) throws Exception {
- SegmentId id = s.getSegmentId();
-
- ByteArrayOutputStream baos = new ByteArrayOutputStream(s.size());
- s.writeTo(baos);
- byte[] segment = baos.toByteArray();
+ private void encode(String segmentId, byte[] data, ByteBuf out) throws
Exception {
+ UUID id = UUID.fromString(segmentId);
Hasher hasher = Hashing.murmur3_32().newHasher();
- long hash = hasher.putBytes(segment).hash().padToLong();
+ long hash = hasher.putBytes(data).hash().padToLong();
- int len = segment.length + EXTRA_HEADERS_WO_SIZE;
+ int len = data.length + EXTRA_HEADERS_WO_SIZE;
out.writeInt(len);
out.writeByte(Messages.HEADER_SEGMENT);
out.writeLong(id.getMostSignificantBits());
out.writeLong(id.getLeastSignificantBits());
out.writeLong(hash);
- out.writeBytes(segment);
+ out.writeBytes(data);
}
}
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/Messages.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/Messages.java?rev=1760934&r1=1760933&r2=1760934&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/Messages.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/Messages.java
Thu Sep 15 14:03:05 2016
@@ -16,19 +16,25 @@
* specific language governing permissions and limitations
* under the License.
*/
+
package org.apache.jackrabbit.oak.segment.standby.codec;
-public class Messages {
+class Messages {
+
+ static final byte HEADER_RECORD = 0x00;
+
+ static final byte HEADER_SEGMENT = 0x01;
+
+ static final byte HEADER_BLOB = 0x02;
- public static final byte HEADER_RECORD = 0x00;
- public static final byte HEADER_SEGMENT = 0x01;
- public static final byte HEADER_BLOB = 0x02;
-
- public static final String GET_HEAD = "h";
- public static final String GET_SEGMENT = "s.";
- public static final String GET_BLOB = "b.";
+ static final String GET_HEAD = "h";
+
+ static final String GET_SEGMENT = "s.";
+
+ static final String GET_BLOB = "b.";
private static final String MAGIC = "Standby-CMD@";
+
private static final String SEPARATOR = ":";
private static String newRequest(String clientId, String body, boolean
delimited) {
@@ -48,31 +54,31 @@ public class Messages {
return builder.toString();
}
- public static String newGetHeadRequest(String clientId, boolean delimited)
{
+ static String newGetHeadRequest(String clientId, boolean delimited) {
return newRequest(clientId, GET_HEAD, delimited);
}
- public static String newGetHeadRequest(String clientId) {
+ static String newGetHeadRequest(String clientId) {
return newGetHeadRequest(clientId, true);
}
- public static String newGetSegmentRequest(String clientId, String
segmentId, boolean delimited) {
+ static String newGetSegmentRequest(String clientId, String segmentId,
boolean delimited) {
return newRequest(clientId, GET_SEGMENT + segmentId, delimited);
}
- public static String newGetSegmentRequest(String clientId, String
segmentId) {
+ static String newGetSegmentRequest(String clientId, String segmentId) {
return newGetSegmentRequest(clientId, segmentId, true);
}
- public static String newGetBlobRequest(String clientId, String blobId,
boolean delimited) {
+ static String newGetBlobRequest(String clientId, String blobId, boolean
delimited) {
return newRequest(clientId, GET_BLOB + blobId, delimited);
}
- public static String newGetBlobRequest(String clientId, String blobId) {
+ static String newGetBlobRequest(String clientId, String blobId) {
return newGetBlobRequest(clientId, blobId, true);
}
- public static String extractMessageFrom(String payload) {
+ static String extractMessageFrom(String payload) {
if (payload.startsWith(MAGIC) && payload.length() > MAGIC.length()) {
int i = payload.indexOf(SEPARATOR);
return payload.substring(i + 1);
@@ -80,7 +86,7 @@ public class Messages {
return null;
}
- public static String extractClientFrom(String payload) {
+ static String extractClientFrom(String payload) {
if (payload.startsWith(MAGIC) && payload.length() > MAGIC.length()) {
payload = payload.substring(MAGIC.length());
int i = payload.indexOf(SEPARATOR);
@@ -88,4 +94,5 @@ public class Messages {
}
return null;
}
+
}
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/RequestDecoder.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/RequestDecoder.java?rev=1760934&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/RequestDecoder.java
(added)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/RequestDecoder.java
Thu Sep 15 14:03:05 2016
@@ -0,0 +1,52 @@
+/*
+ * 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.standby.codec;
+
+import java.util.List;
+
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.MessageToMessageDecoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RequestDecoder extends MessageToMessageDecoder<String> {
+
+ private static final Logger log =
LoggerFactory.getLogger(RequestDecoder.class);
+
+ @Override
+ protected void decode(ChannelHandlerContext ctx, String msg, List<Object>
out) throws Exception {
+ String request = Messages.extractMessageFrom(msg);
+
+ if (request == null) {
+ log.debug("Received invalid message {}, ignoring", msg);
+ ctx.fireChannelRead(msg);
+ } else if (request.startsWith(Messages.GET_BLOB)) {
+ log.debug("Parsed 'get blob' request");
+ out.add(new GetBlobRequest(Messages.extractClientFrom(msg),
request.substring(Messages.GET_BLOB.length())));
+ } else if (request.equalsIgnoreCase(Messages.GET_HEAD)) {
+ log.debug("Parsed 'get head' message");
+ out.add(new GetHeadRequest(Messages.extractClientFrom(msg)));
+ } else if (request.startsWith(Messages.GET_SEGMENT)) {
+ log.debug("Parsed 'get segment' message");
+ out.add(new GetSegmentRequest(Messages.extractClientFrom(msg),
request.substring(Messages.GET_SEGMENT.length())));
+ } else {
+ log.debug("Received unrecognizable message {}, dropping", msg);
+ }
+ }
+
+}
Propchange:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/RequestDecoder.java
------------------------------------------------------------------------------
svn:eol-style = native
Added:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/ResponseDecoder.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/ResponseDecoder.java?rev=1760934&view=auto
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/ResponseDecoder.java
(added)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/ResponseDecoder.java
Thu Sep 15 14:03: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.standby.codec;
+
+import java.util.List;
+import java.util.UUID;
+
+import com.google.common.base.Charsets;
+import com.google.common.hash.Hashing;
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.handler.codec.ByteToMessageDecoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ResponseDecoder extends ByteToMessageDecoder {
+
+ private static final Logger log =
LoggerFactory.getLogger(ResponseDecoder.class);
+
+ @Override
+ protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object>
out) throws Exception {
+ int length = in.readInt();
+
+ switch (in.readByte()) {
+ case Messages.HEADER_RECORD:
+ log.debug("Decoding 'get head' response");
+ decodeGetHeadResponse(length, in, out);
+ break;
+ case Messages.HEADER_SEGMENT:
+ log.debug("Decoding 'get segment' response");
+ decodeGetSegmentResponse(length, in, out);
+ break;
+ case Messages.HEADER_BLOB:
+ log.debug("Decoding 'get blob' response");
+ decodeGetBlobResponse(length, in, out);
+ break;
+ default:
+ log.debug("Invalid type, dropping message");
+ }
+ }
+
+ private void decodeGetHeadResponse(int length, ByteBuf in, List<Object>
out) {
+ byte[] data = new byte[length - 1];
+ in.readBytes(data);
+ String recordId = new String(data, Charsets.UTF_8);
+ out.add(new GetHeadResponse(null, recordId));
+ }
+
+ private void decodeGetSegmentResponse(int length, ByteBuf in, List<Object>
out) {
+ long msb = in.readLong();
+ long lsb = in.readLong();
+
+ String segmentId = new UUID(msb, lsb).toString();
+
+ long hash = in.readLong();
+
+ byte[] data = new byte[length - 25];
+ in.readBytes(data);
+
+ if (hash(data) != hash) {
+ log.debug("Invalid checksum, discarding segment {}", segmentId);
+ return;
+ }
+
+ out.add(new GetSegmentResponse(null, segmentId, data));
+ }
+
+ private void decodeGetBlobResponse(int length, ByteBuf in, List<Object>
out) {
+ int blobIdLength = in.readInt();
+
+ byte[] blobIdBytes = new byte[blobIdLength];
+ in.readBytes(blobIdBytes);
+
+ String blobId = new String(blobIdBytes, Charsets.UTF_8);
+
+ long hash = in.readLong();
+
+ byte[] blobData = new byte[length - 1 - 4 - blobIdBytes.length - 8];
+ in.readBytes(blobData);
+
+ if (hash(blobData) != hash) {
+ log.debug("Invalid checksum, discarding blob {}", blobId);
+ return;
+ }
+
+ out.add(new GetBlobResponse(null, blobId, blobData));
+ }
+
+ private long hash(byte[] data) {
+ return
Hashing.murmur3_32().newHasher().putBytes(data).hash().padToLong();
+ }
+
+}
Propchange:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/codec/ResponseDecoder.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/DefaultStandbyBlobReader.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/DefaultStandbyBlobReader.java?rev=1760934&r1=1760933&r2=1760934&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/DefaultStandbyBlobReader.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/DefaultStandbyBlobReader.java
Thu Sep 15 14:03:05 2016
@@ -17,13 +17,20 @@
package org.apache.jackrabbit.oak.segment.standby.server;
-import org.apache.jackrabbit.oak.api.Blob;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.io.IOUtils;
import org.apache.jackrabbit.oak.plugins.blob.BlobStoreBlob;
import org.apache.jackrabbit.oak.segment.file.FileStore;
import org.apache.jackrabbit.oak.spi.blob.BlobStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
class DefaultStandbyBlobReader implements StandbyBlobReader {
+ private final Logger log =
LoggerFactory.getLogger(DefaultStandbyBlobReader.class);
+
private final FileStore store;
DefaultStandbyBlobReader(FileStore store) {
@@ -31,14 +38,22 @@ class DefaultStandbyBlobReader implement
}
@Override
- public Blob readBlob(String blobId) {
+ public byte[] readBlob(String blobId) {
BlobStore blobStore = store.getBlobStore();
- if (blobStore != null) {
- return new BlobStoreBlob(blobStore, blobId);
+ if (blobStore == null) {
+ return null;
+ }
+
+ byte[] bytes = null;
+
+ try (InputStream s = new BlobStoreBlob(blobStore,
blobId).getNewStream()) {
+ bytes = IOUtils.toByteArray(s);
+ } catch (IOException e) {
+ log.warn("Error while reading blob content", e);
}
- return null;
+ return bytes;
}
}
Modified:
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/DefaultStandbyHeadReader.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/DefaultStandbyHeadReader.java?rev=1760934&r1=1760933&r2=1760934&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/DefaultStandbyHeadReader.java
(original)
+++
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/DefaultStandbyHeadReader.java
Thu Sep 15 14:03:05 2016
@@ -17,7 +17,6 @@
package org.apache.jackrabbit.oak.segment.standby.server;
-import org.apache.jackrabbit.oak.segment.RecordId;
import org.apache.jackrabbit.oak.segment.file.FileStore;
class DefaultStandbyHeadReader implements StandbyHeadReader {
@@ -29,8 +28,8 @@ class DefaultStandbyHeadReader implement
}
@Override
- public RecordId readHeadRecordId() {
- return store.getHead().getRecordId();
+ public String readHeadRecordId() {
+ return store.getHead().getRecordId().toString();
}
}