Class RegionReadOnlyController

java.lang.Object
org.apache.hadoop.hbase.security.access.AbstractReadOnlyController
org.apache.hadoop.hbase.security.access.RegionReadOnlyController
All Implemented Interfaces:
Coprocessor, RegionCoprocessor, RegionObserver

@LimitedPrivate("Configuration") public class RegionReadOnlyController extends AbstractReadOnlyController implements RegionCoprocessor, RegionObserver
  • Constructor Details

  • Method Details

    • getRegionObserver

      Specified by:
      getRegionObserver in interface RegionCoprocessor
    • preFlushScannerOpen

      Description copied from interface: RegionObserver
      Called before we open store scanner for flush. You can use the options to change max versions and TTL for the scanner being opened.
      Specified by:
      preFlushScannerOpen in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      store - the store where flush is being requested
      options - used to change max versions and TTL for the scanner being opened
      Throws:
      IOException
    • preFlush

      Description copied from interface: RegionObserver
      Called before the memstore is flushed to disk.
      Specified by:
      preFlush in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      tracker - tracker used to track the life cycle of a flush
      Throws:
      IOException
    • preFlush

      Description copied from interface: RegionObserver
      Called before a Store's memstore is flushed to disk.
      Specified by:
      preFlush in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      store - the store where flush is being requested
      scanner - the scanner over existing data used in the memstore
      tracker - tracker used to track the life cycle of a flush
      Returns:
      the scanner to use during flush. Should not be null unless the implementation is writing new store files on its own.
      Throws:
      IOException
    • preMemStoreCompaction

      Description copied from interface: RegionObserver
      Called before in memory compaction started.
      Specified by:
      preMemStoreCompaction in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      store - the store where in memory compaction is being requested
      Throws:
      IOException
    • preMemStoreCompactionCompactScannerOpen

      Description copied from interface: RegionObserver
      Called before we open store scanner for in memory compaction. You can use the options to change max versions and TTL for the scanner being opened. Notice that this method will only be called when you use eager mode. For basic mode we will not drop any cells thus we do not open a store scanner.
      Specified by:
      preMemStoreCompactionCompactScannerOpen in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      store - the store where in memory compaction is being requested
      options - used to change max versions and TTL for the scanner being opened
      Throws:
      IOException
    • preMemStoreCompactionCompact

      Description copied from interface: RegionObserver
      Called before we do in memory compaction. Notice that this method will only be called when you use eager mode. For basic mode we will not drop any cells thus there is no InternalScanner.
      Specified by:
      preMemStoreCompactionCompact in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      store - the store where in memory compaction is being executed
      scanner - the scanner over existing data used in the memstore segments being compact
      Returns:
      the scanner to use during in memory compaction. Must be non-null.
      Throws:
      IOException
    • preCompactSelection

      public void preCompactSelection(ObserverContext<? extends RegionCoprocessorEnvironment> c, Store store, List<? extends StoreFile> candidates, CompactionLifeCycleTracker tracker) throws IOException
      Description copied from interface: RegionObserver
      Called prior to selecting the StoreFiles to compact from the list of available candidates. To alter the files used for compaction, you may mutate the passed in list of candidates. If you remove all the candidates then the compaction will be canceled.

      Supports Coprocessor 'bypass' -- 'bypass' is how this method indicates that it changed the passed in candidates. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Specified by:
      preCompactSelection in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      store - the store where compaction is being requested
      candidates - the store files currently available for compaction
      tracker - tracker used to track the life cycle of a compaction
      Throws:
      IOException
    • preCompactScannerOpen

      Description copied from interface: RegionObserver
      Called before we open store scanner for compaction. You can use the options to change max versions and TTL for the scanner being opened.
      Specified by:
      preCompactScannerOpen in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      store - the store being compacted
      scanType - type of Scan
      options - used to change max versions and TTL for the scanner being opened
      tracker - tracker used to track the life cycle of a compaction
      request - the requested compaction
      Throws:
      IOException
    • preCompact

      Description copied from interface: RegionObserver
      Called prior to writing the StoreFiles selected for compaction into a new StoreFile.

      To override or modify the compaction process, implementing classes can wrap the provided InternalScanner with a custom implementation that is returned from this method. The custom scanner can then inspect Cells from the wrapped scanner, applying its own policy to what gets written.

      If implementations are wrapping the passed in InternalScanner, they can also have their implementation implement Shipper and delegate to the original scanner. This will cause compactions to free up memory as they progress, which is especially important for people using off-heap memory pools.

      Keep in mind that when Shipper.shipped() is called, any cell references you maintain in your implementation may get corrupted. As such you should make sure to deep clone any cells that you need to keep reference to across invocations of shipped.

      Specified by:
      preCompact in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      store - the store being compacted
      scanner - the scanner over existing data used in the store file rewriting
      scanType - type of Scan
      tracker - tracker used to track the life cycle of a compaction
      request - the requested compaction
      Returns:
      the scanner to use during compaction. Should not be null unless the implementation is writing new store files on its own.
      Throws:
      IOException
    • prePut

      public void prePut(ObserverContext<? extends RegionCoprocessorEnvironment> c, Put put, WALEdit edit, Durability durability) throws IOException
      Description copied from interface: RegionObserver
      Called before the client stores a value.

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in 'put' beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      prePut in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      put - The Put object
      edit - The WALEdit object that will be written to the wal
      durability - Persistence guarantee for this Put
      Throws:
      IOException
    • prePut

      public void prePut(ObserverContext<? extends RegionCoprocessorEnvironment> c, Put put, WALEdit edit) throws IOException
      Description copied from interface: RegionObserver
      Called before the client stores a value.

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in 'put' beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      prePut in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      put - The Put object
      edit - The WALEdit object that will be written to the wal
      Throws:
      IOException
    • preDelete

      public void preDelete(ObserverContext<? extends RegionCoprocessorEnvironment> c, Delete delete, WALEdit edit, Durability durability) throws IOException
      Description copied from interface: RegionObserver
      Called before the client deletes a value.

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in 'delete' beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      preDelete in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      delete - The Delete object
      edit - The WALEdit object for the wal
      durability - Persistence guarantee for this Delete
      Throws:
      IOException
    • preDelete

      public void preDelete(ObserverContext<? extends RegionCoprocessorEnvironment> c, Delete delete, WALEdit edit) throws IOException
      Description copied from interface: RegionObserver
      Called before the client deletes a value.

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in 'delete' beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      preDelete in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      delete - The Delete object
      edit - The WALEdit object for the wal
      Throws:
      IOException
    • preBatchMutate

      Description copied from interface: RegionObserver
      This will be called for every batch mutation operation happening at the server. This will be called after acquiring the locks on the mutating rows and after applying the proper timestamp for each Mutation at the server. The batch may contain Put/Delete/Increment/Append. By setting OperationStatus of Mutations (MiniBatchOperationInProgress.setOperationStatus(int, OperationStatus)), RegionObserver can make Region to skip these Mutations.

      Note: Do not retain references to any Cells in Mutations beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      preBatchMutate in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      miniBatchOp - batch of Mutations getting applied to region.
      Throws:
      IOException
    • preCheckAndPut

      public boolean preCheckAndPut(ObserverContext<? extends RegionCoprocessorEnvironment> c, byte[] row, byte[] family, byte[] qualifier, CompareOperator op, ByteArrayComparable comparator, Put put, boolean result) throws IOException
      Description copied from interface: RegionObserver
      Called before checkAndPut.

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in 'put' beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      preCheckAndPut in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      row - row to check
      family - column family
      qualifier - column qualifier
      op - the comparison operation
      comparator - the comparator
      put - data to put if check succeeds
      result - the default value of the result
      Returns:
      the return value to return to client if bypassing default processing
      Throws:
      IOException
    • preCheckAndPut

      public boolean preCheckAndPut(ObserverContext<? extends RegionCoprocessorEnvironment> c, byte[] row, Filter filter, Put put, boolean result) throws IOException
      Description copied from interface: RegionObserver
      Called before checkAndPut.

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in 'put' beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      preCheckAndPut in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      row - row to check
      filter - filter
      put - data to put if check succeeds
      result - the default value of the result
      Returns:
      the return value to return to client if bypassing default processing
      Throws:
      IOException
    • preCheckAndPutAfterRowLock

      public boolean preCheckAndPutAfterRowLock(ObserverContext<? extends RegionCoprocessorEnvironment> c, byte[] row, byte[] family, byte[] qualifier, CompareOperator op, ByteArrayComparable comparator, Put put, boolean result) throws IOException
      Description copied from interface: RegionObserver
      Called before checkAndPut but after acquiring rowlock.

      Note: Caution to be taken for not doing any long time operation in this hook. Row will be locked for longer time. Trying to acquire lock on another row, within this, can lead to potential deadlock.

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in 'put' beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      preCheckAndPutAfterRowLock in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      row - row to check
      family - column family
      qualifier - column qualifier
      op - the comparison operation
      comparator - the comparator
      put - data to put if check succeeds
      result - the default value of the result
      Returns:
      the return value to return to client if bypassing default processing
      Throws:
      IOException
    • preCheckAndPutAfterRowLock

      public boolean preCheckAndPutAfterRowLock(ObserverContext<? extends RegionCoprocessorEnvironment> c, byte[] row, Filter filter, Put put, boolean result) throws IOException
      Description copied from interface: RegionObserver
      Called before checkAndPut but after acquiring rowlock.

      Note: Caution to be taken for not doing any long time operation in this hook. Row will be locked for longer time. Trying to acquire lock on another row, within this, can lead to potential deadlock.

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in 'put' beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      preCheckAndPutAfterRowLock in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      row - row to check
      filter - filter
      put - data to put if check succeeds
      result - the default value of the result
      Returns:
      the return value to return to client if bypassing default processing
      Throws:
      IOException
    • preCheckAndDelete

      public boolean preCheckAndDelete(ObserverContext<? extends RegionCoprocessorEnvironment> c, byte[] row, byte[] family, byte[] qualifier, CompareOperator op, ByteArrayComparable comparator, Delete delete, boolean result) throws IOException
      Description copied from interface: RegionObserver
      Called before checkAndDelete.

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in 'delete' beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      preCheckAndDelete in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      row - row to check
      family - column family
      qualifier - column qualifier
      op - the comparison operation
      comparator - the comparator
      delete - delete to commit if check succeeds
      result - the default value of the result
      Returns:
      the value to return to client if bypassing default processing
      Throws:
      IOException
    • preCheckAndDelete

      public boolean preCheckAndDelete(ObserverContext<? extends RegionCoprocessorEnvironment> c, byte[] row, Filter filter, Delete delete, boolean result) throws IOException
      Description copied from interface: RegionObserver
      Called before checkAndDelete.

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in 'delete' beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      preCheckAndDelete in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      row - row to check
      filter - column family
      delete - delete to commit if check succeeds
      result - the default value of the result
      Returns:
      the value to return to client if bypassing default processing
      Throws:
      IOException
    • preCheckAndDeleteAfterRowLock

      public boolean preCheckAndDeleteAfterRowLock(ObserverContext<? extends RegionCoprocessorEnvironment> c, byte[] row, byte[] family, byte[] qualifier, CompareOperator op, ByteArrayComparable comparator, Delete delete, boolean result) throws IOException
      Description copied from interface: RegionObserver
      Called before checkAndDelete but after acquiring rowock.

      Note: Caution to be taken for not doing any long time operation in this hook. Row will be locked for longer time. Trying to acquire lock on another row, within this, can lead to potential deadlock.

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in 'delete' beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      preCheckAndDeleteAfterRowLock in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      row - row to check
      family - column family
      qualifier - column qualifier
      op - the comparison operation
      comparator - the comparator
      delete - delete to commit if check succeeds
      result - the default value of the result
      Returns:
      the value to return to client if bypassing default processing
      Throws:
      IOException
    • preCheckAndDeleteAfterRowLock

      public boolean preCheckAndDeleteAfterRowLock(ObserverContext<? extends RegionCoprocessorEnvironment> c, byte[] row, Filter filter, Delete delete, boolean result) throws IOException
      Description copied from interface: RegionObserver
      Called before checkAndDelete but after acquiring rowock.

      Note: Caution to be taken for not doing any long time operation in this hook. Row will be locked for longer time. Trying to acquire lock on another row, within this, can lead to potential deadlock.

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in 'delete' beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      preCheckAndDeleteAfterRowLock in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      row - row to check
      filter - filter
      delete - delete to commit if check succeeds
      result - the default value of the result
      Returns:
      the value to return to client if bypassing default processing
      Throws:
      IOException
    • preCheckAndMutate

      Description copied from interface: RegionObserver
      Called before checkAndMutate

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in actions beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      preCheckAndMutate in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      checkAndMutate - the CheckAndMutate object
      result - the default value of the result
      Returns:
      the return value to return to client if bypassing default processing
      Throws:
      IOException - if an error occurred on the coprocessor
    • preCheckAndMutateAfterRowLock

      Description copied from interface: RegionObserver
      Called before checkAndDelete but after acquiring rowlock.

      Note: Caution to be taken for not doing any long time operation in this hook. Row will be locked for longer time. Trying to acquire lock on another row, within this, can lead to potential deadlock.

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in actions beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      preCheckAndMutateAfterRowLock in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      checkAndMutate - the CheckAndMutate object
      result - the default value of the result
      Returns:
      the value to return to client if bypassing default processing
      Throws:
      IOException - if an error occurred on the coprocessor
    • preAppend

      Description copied from interface: RegionObserver
      Called before Append.

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in 'append' beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      preAppend in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      append - Append object
      Returns:
      result to return to the client if bypassing default processing
      Throws:
      IOException
    • preAppend

      Description copied from interface: RegionObserver
      Called before Append.

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in 'append' beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      preAppend in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      append - Append object
      edit - The WALEdit object that will be written to the wal
      Returns:
      result to return to the client if bypassing default processing
      Throws:
      IOException
    • preAppendAfterRowLock

      Description copied from interface: RegionObserver
      Called before Append but after acquiring rowlock.

      Note: Caution to be taken for not doing any long time operation in this hook. Row will be locked for longer time. Trying to acquire lock on another row, within this, can lead to potential deadlock.

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in 'append' beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      preAppendAfterRowLock in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      append - Append object
      Returns:
      result to return to the client if bypassing default processing
      Throws:
      IOException
    • preIncrement

      Description copied from interface: RegionObserver
      Called before Increment.

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in 'increment' beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      preIncrement in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      increment - increment object
      Returns:
      result to return to the client if bypassing default processing
      Throws:
      IOException
    • preIncrement

      Description copied from interface: RegionObserver
      Called before Increment.

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in 'increment' beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      preIncrement in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      increment - increment object
      edit - The WALEdit object that will be written to the wal
      Returns:
      result to return to the client if bypassing default processing
      Throws:
      IOException
    • preIncrementAfterRowLock

      Description copied from interface: RegionObserver
      Called before Increment but after acquiring rowlock.

      Note: Caution to be taken for not doing any long time operation in this hook. Row will be locked for longer time. Trying to acquire lock on another row, within this, can lead to potential deadlock.

      Call CoprocessorEnvironment#bypass to skip default actions. If 'bypass' is set, we skip out on calling any subsequent chained coprocessors.

      Note: Do not retain references to any Cells in 'increment' beyond the life of this invocation. If need a Cell reference for later use, copy the cell and use that.

      Specified by:
      preIncrementAfterRowLock in interface RegionObserver
      Parameters:
      c - the environment provided by the region server
      increment - increment object
      Returns:
      result to return to the client if bypassing default processing
      Throws:
      IOException
    • preReplayWALs

      public void preReplayWALs(ObserverContext<? extends RegionCoprocessorEnvironment> ctx, RegionInfo info, org.apache.hadoop.fs.Path edits) throws IOException
      Description copied from interface: RegionObserver
      Called before replaying WALs for this region. Calling ObserverContext.bypass() has no effect in this hook.
      Specified by:
      preReplayWALs in interface RegionObserver
      Parameters:
      ctx - the environment provided by the region server
      info - the RegionInfo for this region
      edits - the file of recovered edits
      Throws:
      IOException
    • preBulkLoadHFile

      public void preBulkLoadHFile(ObserverContext<? extends RegionCoprocessorEnvironment> ctx, List<Pair<byte[],String>> familyPaths) throws IOException
      Description copied from interface: RegionObserver
      Called before bulkLoadHFile. Users can create a StoreFile instance to access the contents of a HFile.
      Specified by:
      preBulkLoadHFile in interface RegionObserver
      Parameters:
      ctx - the environment provided by the region server
      familyPaths - pairs of { CF, HFile path } submitted for bulk load. Adding or removing from this list will add or remove HFiles to be bulk loaded.
      Throws:
      IOException
    • preCommitStoreFile

      public void preCommitStoreFile(ObserverContext<? extends RegionCoprocessorEnvironment> ctx, byte[] family, List<Pair<org.apache.hadoop.fs.Path,org.apache.hadoop.fs.Path>> pairs) throws IOException
      Description copied from interface: RegionObserver
      Called before moving bulk loaded hfile to region directory.
      Specified by:
      preCommitStoreFile in interface RegionObserver
      Parameters:
      ctx - the environment provided by the region server
      family - column family
      pairs - List of pairs of { HFile location in staging dir, HFile path in region dir } Each pair are for the same hfile.
      Throws:
      IOException
    • preWALAppend

      public void preWALAppend(ObserverContext<? extends RegionCoprocessorEnvironment> ctx, WALKey key, WALEdit edit) throws IOException
      Description copied from interface: RegionObserver
      Called just before the WAL Entry is appended to the WAL. Implementing this hook allows coprocessors to add extended attributes to the WALKey that then get persisted to the WAL, and are available to replication endpoints to use in processing WAL Entries.
      Specified by:
      preWALAppend in interface RegionObserver
      Parameters:
      ctx - the environment provided by the region server
      key - the WALKey associated with a particular append to a WAL
      Throws:
      IOException