/** * * 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.bookkeeper.proto; import java.io.IOException; import java.nio.ByteBuffer; import java.util.concurrent.TimeUnit; import org.apache.bookkeeper.bookie.BookieException; import org.apache.bookkeeper.proto.BookkeeperProtocol.WriteLacRequest; import org.apache.bookkeeper.proto.BookkeeperProtocol.WriteLacResponse; import org.apache.bookkeeper.proto.BookkeeperProtocol.Request; import org.apache.bookkeeper.proto.BookkeeperProtocol.Response; import org.apache.bookkeeper.proto.BookkeeperProtocol.StatusCode; import org.apache.bookkeeper.util.MathUtils; import org.jboss.netty.channel.Channel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; class WriteLacProcessorV3 extends PacketProcessorBaseV3 { private final static Logger logger = LoggerFactory.getLogger(WriteLacProcessorV3.class); public WriteLacProcessorV3(Request request, Channel channel, BookieRequestProcessor requestProcessor) { super(request, channel, requestProcessor); } // Returns null if there is no exception thrown private WriteLacResponse getWriteLacResponse() { final long startTimeNanos = MathUtils.nowInNano(); WriteLacRequest writeLacRequest = request.getWriteLacRequest(); long lac = writeLacRequest.getLac(); long ledgerId = writeLacRequest.getLedgerId(); final WriteLacResponse.Builder writeLacResponse = WriteLacResponse.newBuilder().setLedgerId(ledgerId); if (!isVersionCompatible()) { writeLacResponse.setStatus(StatusCode.EBADVERSION); return writeLacResponse.build(); } if (requestProcessor.bookie.isReadOnly()) { logger.warn("BookieServer is running as readonly mode, so rejecting the request from the client!"); writeLacResponse.setStatus(StatusCode.EREADONLY); return writeLacResponse.build(); } StatusCode status = null; ByteBuffer lacToAdd = writeLacRequest.getBody().asReadOnlyByteBuffer(); byte[] masterKey = writeLacRequest.getMasterKey().toByteArray(); try { requestProcessor.bookie.setExplicitLac(lacToAdd, channel, masterKey); status = StatusCode.EOK; } catch (IOException e) { logger.error("Error saving lac for ledger:{}", new Object[] { lac, ledgerId, e }); status = StatusCode.EIO; } catch (BookieException e) { logger.error("Unauthorized access to ledger:{} while adding lac:{}", ledgerId, lac); status = StatusCode.EUA; } catch (Throwable t) { logger.error("Unexpected exception while writing {}@{} : ", new Object[] { lac, t }); // some bad request which cause unexpected exception status = StatusCode.EBADREQ; } // If everything is okay, we return null so that the calling function // dosn't return a response back to the caller. if (status.equals(StatusCode.EOK)) { requestProcessor.writeLacStats.registerSuccessfulEvent(MathUtils.elapsedNanos(startTimeNanos), TimeUnit.NANOSECONDS); } else { requestProcessor.writeLacStats.registerFailedEvent(MathUtils.elapsedNanos(startTimeNanos), TimeUnit.NANOSECONDS); } writeLacResponse.setStatus(status); return writeLacResponse.build(); } @Override public void safeRun() { WriteLacResponse writeLacResponse = getWriteLacResponse(); if (null != writeLacResponse) { Response.Builder response = Response.newBuilder() .setHeader(getHeader()) .setStatus(writeLacResponse.getStatus()) .setWriteLacResponse(writeLacResponse); Response resp = response.build(); sendResponse(writeLacResponse.getStatus(), resp, requestProcessor.writeLacStats); } } }