Package com.google.appengine.tools.cloudstorage

Source Code of com.google.appengine.tools.cloudstorage.GcsServiceImpl

/*
* Copyright 2012 Google Inc. All Rights Reserved.
*
* Licensed 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 com.google.appengine.tools.cloudstorage;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.appengine.tools.cloudstorage.RawGcsService.ListItemBatch;
import com.google.appengine.tools.cloudstorage.RawGcsService.RawGcsCreationToken;
import com.google.apphosting.api.ApiProxy.ApiDeadlineExceededException;
import com.google.apphosting.api.ApiProxy.OverQuotaException;
import com.google.apphosting.api.ApiProxy.RPCFailedException;
import com.google.apphosting.api.ApiProxy.UnknownException;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedByInterruptException;
import java.util.Iterator;
import java.util.concurrent.Callable;

/**
* Basic implementation of {@link GcsService}. Mostly delegates to {@link RawGcsService}
*/
final class GcsServiceImpl implements GcsService {

  private final RawGcsService raw;
  private final GcsServiceOptions options;
  private static final int MAX_RESULTS_PER_BATCH = 100;
  static final ExceptionHandler exceptionHandler = new ExceptionHandler.Builder()
      .retryOn(UnknownException.class, RPCFailedException.class, ApiDeadlineExceededException.class,
          IOException.class, SocketTimeoutException.class, OverQuotaException.class)
      .abortOn(InterruptedException.class, FileNotFoundException.class,
          MalformedURLException.class, ClosedByInterruptException.class,
          InterruptedIOException.class)
      .build();

  GcsServiceImpl(RawGcsService raw, GcsServiceOptions options) {
    this.raw = checkNotNull(raw, "Null raw");
    this.options = options;
  }

  @Override
  public String toString() {
    return "GcsServiceImpl [serviceOptions=" + options + "]";
  }

  @Override
  public GcsOutputChannel createOrReplace(
      final GcsFilename filename, final GcsFileOptions fileOptions) throws IOException {
    try {
      RawGcsCreationToken token = RetryHelper.runWithRetries(new Callable<RawGcsCreationToken>() {
        @Override
        public RawGcsCreationToken call() throws IOException {
          long timeout = options.getRetryParams().getRequestTimeoutMillisForCurrentAttempt();
          return raw.beginObjectCreation(filename, fileOptions, timeout);
        }
      }, options.getRetryParams(), exceptionHandler);
      return new GcsOutputChannelImpl(
          raw, token, options.getRetryParams(), options.getDefaultWriteBufferSize(),
          options.getHttpHeaders());
    } catch (RetryInterruptedException ex) {
      throw new ClosedByInterruptException();
    } catch (NonRetriableException e) {
      Throwables.propagateIfInstanceOf(e.getCause(), IOException.class);
      throw e;
    }
  }

  @Override
  public void createOrReplace(final GcsFilename filename, final GcsFileOptions fileOptions,
      final ByteBuffer src) throws IOException {
    if (src.remaining() > raw.getMaxWriteSizeByte()) {
      @SuppressWarnings("resource")
      GcsOutputChannel channel = createOrReplace(filename, fileOptions);
      channel.write(src);
      channel.close();
      return;
    }

    try {
      RetryHelper.runWithRetries(new Callable<Void>() {
          @Override
          public Void call() throws IOException {
            long timeout = options.getRetryParams().getRequestTimeoutMillisForCurrentAttempt();
            raw.putObject(filename, fileOptions, src, timeout);
            return null;
          }
        }, options.getRetryParams(), exceptionHandler);
    } catch (RetryInterruptedException ex) {
      throw new ClosedByInterruptException();
    } catch (NonRetriableException e) {
      Throwables.propagateIfInstanceOf(e.getCause(), IOException.class);
      throw e;
    }
  }

  @Override
  public GcsInputChannel openReadChannel(GcsFilename filename, long startPosition) {
    return new SimpleGcsInputChannelImpl(raw, filename, startPosition, options.getRetryParams(),
        options.getHttpHeaders());
  }

  @Override
  public GcsInputChannel openPrefetchingReadChannel(
      GcsFilename filename, long startPosition, int blockSize) {
    return new PrefetchingGcsInputChannelImpl(raw, filename, blockSize, startPosition,
        options.getRetryParams(), options.getHttpHeaders());
  }

  @Override
  public GcsFileMetadata getMetadata(final GcsFilename filename) throws IOException {
    try {
      return RetryHelper.runWithRetries(new Callable<GcsFileMetadata>() {
        @Override
        public GcsFileMetadata call() throws IOException {
          long timeout = options.getRetryParams().getRequestTimeoutMillisForCurrentAttempt();
          return raw.getObjectMetadata(filename, timeout);
        }
      }, options.getRetryParams(), exceptionHandler);
    } catch (RetryInterruptedException ex) {
      throw new ClosedByInterruptException();
    } catch (NonRetriableException e) {
      Throwables.propagateIfInstanceOf(e.getCause(), IOException.class);
      throw e;
    }
  }

  @Override
  public boolean delete(final GcsFilename filename) throws IOException {
    try {
      return RetryHelper.runWithRetries(new Callable<Boolean>() {
        @Override
        public Boolean call() throws IOException {
          long timeout = options.getRetryParams().getRequestTimeoutMillisForCurrentAttempt();
          return raw.deleteObject(filename, timeout);
        }
      }, options.getRetryParams(), exceptionHandler);
    } catch (RetryInterruptedException ex) {
      throw new ClosedByInterruptException();
    } catch (NonRetriableException e) {
      Throwables.propagateIfInstanceOf(e.getCause(), IOException.class);
      throw e;
    }
  }

  @Override
  public void compose(final Iterable<String> source, final GcsFilename dest)
      throws IOException {
    try {
      RetryHelper.runWithRetries(new Callable<Void>() {
        @Override
        public Void call() throws IOException {
          long timeout = options.getRetryParams().getRequestTimeoutMillisForCurrentAttempt();
          raw.composeObject(source, dest, timeout);
          return null;
        }
      }, options.getRetryParams(), exceptionHandler);
    } catch (RetryInterruptedException ex) {
      throw new ClosedByInterruptException();
    } catch (NonRetriableException e) {
      Throwables.propagateIfInstanceOf(e.getCause(), IOException.class);
      throw e;
    }
  }

  @Override
  public void copy(final GcsFilename source, final GcsFilename dest)
      throws IOException {
    try {
      RetryHelper.runWithRetries(new Callable<Void>() {
        @Override
        public Void call() throws IOException {
          long timeout = options.getRetryParams().getRequestTimeoutMillisForCurrentAttempt();
          raw.copyObject(source, dest, timeout);
          return null;
        }
      }, options.getRetryParams(), exceptionHandler);
    } catch (RetryInterruptedException ex) {
      throw new ClosedByInterruptException();
    } catch (NonRetriableException e) {
      Throwables.propagateIfInstanceOf(e.getCause(), IOException.class);
      throw e;
    }
  }

  @Override
  public ListResult list(final String bucket, ListOptions listOptions) throws IOException {
    if (listOptions == null) {
      listOptions = ListOptions.DEFAULT;
    }
    final String prefix = listOptions.getPrefix();
    final String delimiter = listOptions.isRecursive() ? null : options.getPathDelimiter();
    Callable<Iterator<ListItem>> batcher = new Callable<Iterator<ListItem>>() {
      private String nextMarker = "";

      @Override
      public Iterator<ListItem> call() throws IOException {
        if (nextMarker == null) {
          return null;
        }
        ListItemBatch batch;
        try {
          batch = RetryHelper.runWithRetries(new Callable<ListItemBatch>() {
            @Override
            public ListItemBatch call() throws IOException {
              long timeout = options.getRetryParams().getRequestTimeoutMillisForCurrentAttempt();
              String marker = Strings.emptyToNull(nextMarker);
              return raw.list(bucket, prefix, delimiter, marker, MAX_RESULTS_PER_BATCH, timeout);
            }
          }, options.getRetryParams(), exceptionHandler);
        } catch (RetryInterruptedException ex) {
          throw new ClosedByInterruptException();
        } catch (NonRetriableException e) {
          Throwables.propagateIfInstanceOf(e.getCause(), IOException.class);
          throw e;
        }
        nextMarker = batch.getNextMarker();
        return batch.getItems().iterator();
      }
    };
    return new ListResult(batcher);
  }
}
TOP

Related Classes of com.google.appengine.tools.cloudstorage.GcsServiceImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.