content: /*
   * 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.bookie;
  
  import io.netty.buffer.ByteBuf;
  import java.io.IOException;
  import java.util.PrimitiveIterator;
  import java.util.concurrent.CompletableFuture;
  import org.apache.bookkeeper.common.util.Watcher;
  import org.apache.bookkeeper.proto.BookkeeperInternalCallbacks.WriteCallback;
  
  /**
   * Interface for the bookie.
   */
  public interface Bookie {
  
      void start();
      void join() throws InterruptedException;
      boolean isRunning();
      int getExitCode();
      int shutdown();
  
      boolean isAvailableForHighPriorityWrites();
      boolean isReadOnly();
  
      // TODO: replace callback with futures
      // TODO: replace ackBeforeSync with flags
      void addEntry(ByteBuf entry, boolean ackBeforeSync, WriteCallback cb, Object ctx, byte[] masterKey)
              throws IOException, BookieException, InterruptedException;
      void recoveryAddEntry(ByteBuf entry, WriteCallback cb, Object ctx, byte[] masterKey)
              throws IOException, BookieException, InterruptedException;
      void forceLedger(long ledgerId, WriteCallback cb, Object ctx);
      void setExplicitLac(ByteBuf entry, WriteCallback writeCallback, Object ctx, byte[] masterKey)
              throws IOException, InterruptedException, BookieException;
      ByteBuf getExplicitLac(long ledgerId) throws IOException, NoLedgerException, BookieException;
  
      // these can probably be moved out and called directly on ledgerdirmanager
      long getTotalDiskSpace() throws IOException;
      long getTotalFreeSpace() throws IOException;
  
      // TODO: Shouldn't this be async?
      ByteBuf readEntry(long ledgerId, long entryId)
              throws IOException, NoLedgerException, BookieException;
      long readLastAddConfirmed(long ledgerId) throws IOException, BookieException;
      PrimitiveIterator.OfLong getListOfEntriesOfLedger(long ledgerId) throws IOException, NoLedgerException;
  
      /**
       * Fences a ledger. From this point on, clients will be unable to
       * write to this ledger. Only recoveryAddEntry will be
       * able to add entries to the ledger.
       * This method is idempotent. Once a ledger is fenced, it can
       * never be unfenced. Fencing a fenced ledger has no effect.
       * @return
       */
      CompletableFuture<Boolean> fenceLedger(long ledgerId, byte[] masterKey)
              throws IOException, BookieException;
  
      // TODO: Replace Watcher with a completableFuture (cancellable)
      boolean waitForLastAddConfirmedUpdate(long ledgerId,
                                            long previousLAC,
                                            Watcher<LastAddConfirmedUpdateNotification> watcher)
              throws IOException;
      void cancelWaitForLastAddConfirmedUpdate(long ledgerId,
                                               Watcher<LastAddConfirmedUpdateNotification> watcher)
              throws IOException;
  
      // TODO: StateManager should be passed as a parameter to Bookie
      StateManager getStateManager();
  
      // TODO: Should be constructed and passed in as a parameter
      LedgerStorage getLedgerStorage();
  
      // TODO: Move this exceptions somewhere else
      /**
       * Exception is thrown when no such a ledger is found in this bookie.
       */
      class NoLedgerException extends IOException {
          private static final long serialVersionUID = 1L;
          private final long ledgerId;
          public NoLedgerException(long ledgerId) {
              super("Ledger " + ledgerId + " not found");
              this.ledgerId = ledgerId;
          }
          public long getLedgerId() {
              return ledgerId;
          }
      }
  
      /**
       * Exception is thrown when no such an entry is found in this bookie.
       */
      class NoEntryException extends IOException {
          private static final long serialVersionUID = 1L;
          private final long ledgerId;
          private final long entryId;
          public NoEntryException(long ledgerId, long entryId) {
              this("Entry " + entryId + " not found in " + ledgerId, ledgerId, entryId);
          }
  
          public NoEntryException(String msg, long ledgerId, long entryId) {
              super(msg);
              this.ledgerId = ledgerId;
              this.entryId = entryId;
          }
  
          public long getLedger() {
              return ledgerId;
          }
          public long getEntry() {
              return entryId;
          }
      }
  
  }