Package org.sonatype.nexus.proxy.storage.remote

Source Code of org.sonatype.nexus.proxy.storage.remote.AbstractHTTPRemoteRepositoryStorage

/*
* Sonatype Nexus (TM) Open Source Version
* Copyright (c) 2007-2014 Sonatype, Inc.
* All rights reserved. Includes the third-party code listed at http://links.sonatype.com/products/nexus/oss/attributions.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License Version 1.0,
* which accompanies this distribution and is available at http://www.eclipse.org/legal/epl-v10.html.
*
* Sonatype Nexus (TM) Professional Version is available from Sonatype, Inc. "Sonatype" and "Sonatype Nexus" are trademarks
* of Sonatype, Inc. Apache Maven is a trademark of the Apache Software Foundation. M2eclipse is a trademark of the
* Eclipse Foundation. All other trademarks are the property of their respective owners.
*/
package org.sonatype.nexus.proxy.storage.remote;

import java.net.URI;
import java.net.URISyntaxException;

import javax.inject.Provider;

import org.sonatype.nexus.SystemStatus;
import org.sonatype.nexus.mime.MimeSupport;
import org.sonatype.nexus.proxy.RemoteAccessDeniedException;
import org.sonatype.nexus.proxy.RemoteStorageException;
import org.sonatype.nexus.proxy.ResourceStoreRequest;
import org.sonatype.nexus.proxy.item.RepositoryItemUid;
import org.sonatype.nexus.proxy.repository.ProxyRepository;
import org.sonatype.nexus.proxy.utils.RepositoryStringUtils;

/**
* This class is a base abstract class for HTTP remote storage.
*
* @author cstamas
*/
public abstract class AbstractHTTPRemoteRepositoryStorage
    extends AbstractRemoteRepositoryStorage
    implements RemoteRepositoryStorage
{

  protected AbstractHTTPRemoteRepositoryStorage(final Provider<SystemStatus> systemStatusProvider,
                                                final MimeSupport mimeSupport)
  {
    super(systemStatusProvider, mimeSupport);
  }

  @Override
  public boolean isReachable(final ProxyRepository repository,
                             final ResourceStoreRequest request)
      throws RemoteStorageException
  {
    request.pushRequestPath(RepositoryItemUid.PATH_ROOT);
    try {
      return checkRemoteAvailability(0, repository, request, false);
    }
    catch (RemoteAccessDeniedException e) {
      return true;
    }
    finally {
      request.popRequestPath();
    }
  }

  @Override
  public void validateStorageUrl(String url)
      throws RemoteStorageException
  {
    try {
      URI u = new URI(url);

      if (!"http".equals(u.getScheme().toLowerCase()) && !"https".equals(u.getScheme().toLowerCase())) {
        throw new RemoteStorageException("Unsupported protocol, only HTTP/HTTPS protocols are supported: "
            + u.getScheme().toLowerCase());
      }
    }
    catch (URISyntaxException e) {
      throw new RemoteStorageException("Malformed URL", e);
    }
  }

  @Override
  public boolean containsItem(long newerThen, ProxyRepository repository, ResourceStoreRequest request)
      throws RemoteStorageException
  {
    return checkRemoteAvailability(newerThen, repository, request, true);
  }

  /**
   * Returns {@code true} if only and only if we are positive that remote peer (remote URL of passed in
   * ProxyRepository) points to a remote repository that is hosted by Amazon S3 Storage. This method will return
   * false
   * as long as we don't make very 1st HTTP request to remote peer. After that 1st request, we retain the status
   * until
   * ProxyRepository configuration changes. See NEXUS-3338 for more.
   *
   * @param repository that needs to be checked.
   * @return true only if we know that ProxyRepository in question points to Amazon S3 storage.
   * @throws RemoteStorageException in case of some error.
   */
  public boolean isRemotePeerAmazonS3Storage(final ProxyRepository repository)
      throws RemoteStorageException
  {
    RemoteStorageContext ctx = getRemoteStorageContext(repository);

    // it is S3 if we have CTX_KEY_S3_FLAG set, the flag value is not null, and flag value is true
    // if flag is False, we know it is not S3
    // if flag is null, we still did not contact remote, so we were not able to tell yet
    return ctx.hasContextObject(getS3FlagKey())
        && ((DefaultRemoteStorageContext.BooleanFlagHolder) ctx.getContextObject(getS3FlagKey())).isFlag();
  }

  /**
   * Checks is remote a S3 server and puts a Boolean into remote storage context, thus preventing any further checks
   * (we check only once).
   *
   * @param repository            to check for
   * @param httpServerHeaderValue value of "server" http response header
   * @throws RemoteStorageException re-thrown from {@link #getRemoteStorageContext(ProxyRepository)}
   */
  protected void checkForRemotePeerAmazonS3Storage(final ProxyRepository repository,
                                                   final String httpServerHeaderValue)
      throws RemoteStorageException
  {
    RemoteStorageContext ctx = getRemoteStorageContext(repository);

    // we already know the result, do nothing
    if (ctx.hasContextObject(getS3FlagKey())
        && !((DefaultRemoteStorageContext.BooleanFlagHolder) ctx.getContextObject(getS3FlagKey())).isNull()) {
      return;
    }

    // for now, we check the HTTP response header "Server: AmazonS3"

    boolean isAmazonS3 = (httpServerHeaderValue != null)
        && (httpServerHeaderValue.toLowerCase().contains("amazons3"));

    if (ctx.hasContextObject(getS3FlagKey())) {
      ((DefaultRemoteStorageContext.BooleanFlagHolder) ctx.getContextObject(getS3FlagKey())).setFlag(
          isAmazonS3);
    }

    if (isAmazonS3) {
      // very first request for the proxy repository (it goes remote for the 1st time)
      log.info(
          "The proxy repository {} is backed by Amazon S3 service. This means that Nexus can't reliably detect the validity of "
              + "your setup (baseUrl of proxy repository)!", RepositoryStringUtils.getHumanizedNameString(repository));
    }
  }

  /**
   * Initially, this method is here only to share the code for "availability check" and for "contains" check.
   * Unfortunately, the "availability" check cannot be done at RemoteStorage level, since it is completely repository
   * layout unaware and is able to tell only about the existence of remote server and that the URI on it exists. This
   * "availability" check will have to be moved upper into repository, since it is aware of "what it holds".
   * Ultimately, this method will check is the remote server "present" and is responding or not. But nothing more.
   */
  protected abstract boolean checkRemoteAvailability(long newerThen,
                                                     ProxyRepository repository,
                                                     ResourceStoreRequest request,
                                                     boolean isStrict)
      throws RemoteStorageException;

  /**
   * Returns the context key for S3 flag.
   *
   * @return the context key for S3 flag. If {@code null}, we do not handle S3.
   */
  protected abstract String getS3FlagKey();

}
TOP

Related Classes of org.sonatype.nexus.proxy.storage.remote.AbstractHTTPRemoteRepositoryStorage

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.