Package org.sonatype.nexus.proxy.maven.routing.internal

Source Code of org.sonatype.nexus.proxy.maven.routing.internal.RemotePrefixFileStrategy

/*
* 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.maven.routing.internal;

import java.io.IOException;
import java.util.Collections;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.sonatype.nexus.proxy.IllegalOperationException;
import org.sonatype.nexus.proxy.ItemNotFoundException;
import org.sonatype.nexus.proxy.ResourceStoreRequest;
import org.sonatype.nexus.proxy.access.Action;
import org.sonatype.nexus.proxy.item.RepositoryItemUid;
import org.sonatype.nexus.proxy.item.StorageFileItem;
import org.sonatype.nexus.proxy.item.StorageItem;
import org.sonatype.nexus.proxy.maven.ChecksumPolicy;
import org.sonatype.nexus.proxy.maven.MavenProxyRepository;
import org.sonatype.nexus.proxy.maven.routing.Config;
import org.sonatype.nexus.proxy.maven.routing.Manager;
import org.sonatype.nexus.proxy.maven.routing.PrefixSource;
import org.sonatype.nexus.proxy.maven.routing.discovery.RemoteStrategy;
import org.sonatype.nexus.proxy.maven.routing.discovery.StrategyFailedException;
import org.sonatype.nexus.proxy.maven.routing.discovery.StrategyResult;
import org.sonatype.nexus.proxy.maven.routing.internal.TextFilePrefixSourceMarshaller.Result;
import org.sonatype.nexus.proxy.storage.remote.httpclient.HttpClientManager;

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

/**
* Remote prefix file strategy.
*
* @author cstamas
*/
@Named(RemotePrefixFileStrategy.ID)
@Singleton
public class RemotePrefixFileStrategy
    extends AbstractHttpRemoteStrategy
    implements RemoteStrategy
{
  private static final PrefixSource UNSUPPORTED_PREFIXSOURCE = new PrefixSource()
  {
    @Override
    public boolean exists() {
      return false;
    }

    @Override
    public boolean supported() {
      return false;
    }

    @Override
    public List<String> readEntries() throws IOException {
      return Collections.emptyList();
    }

    @Override
    public long getLostModifiedTimestamp() {
      return 0;
    }

  };

  protected static final String ID = "prefix-file";

  private final Config config;

  /**
   * Constructor.
   */
  @Inject
  public RemotePrefixFileStrategy(final Config config, final HttpClientManager httpClientManager) {
    super(100, ID, httpClientManager);
    this.config = checkNotNull(config);
  }

  @Override
  public StrategyResult doDiscover(final MavenProxyRepository mavenProxyRepository) throws StrategyFailedException,
      IOException
  {
    StorageFileItem item;
    String path = config.getRemotePrefixFilePath();
    log.debug("Looking for remote prefix on {} at path {}", mavenProxyRepository, path);
    // we keep exclusive lock on UID during discovery to prevent other threads grabbing this file
    // prematurely. We release the lock only when file is present locally, and is validated.
    // in that moment it's not published yet, but the content is correct and it will be
    // the same that will get published.
    final RepositoryItemUid uid = mavenProxyRepository.createUid(path);
    uid.getLock().lock(Action.update);
    try {
      item = retrieveFromRemoteIfExists(mavenProxyRepository, path);
      if (item != null) {
        log.debug("Remote prefix on {} at path {} found!", mavenProxyRepository, path);
        long prefixFileAgeInDays = (System.currentTimeMillis() - item.getModified()) / 86400000L;
        Result unmarshalled = new TextFilePrefixSourceMarshaller(config).read(item);
        if (!unmarshalled.supported()) {
          return new StrategyResult("Remote disabled automatic routing", UNSUPPORTED_PREFIXSOURCE, false);
        }
        if (unmarshalled.entries().isEmpty()) {
          return new StrategyResult("Remote publishes empty prefix file", UNSUPPORTED_PREFIXSOURCE, false);
        }

        final PrefixSource prefixSource = new FilePrefixSource(mavenProxyRepository, path, config);
        if (prefixFileAgeInDays < 1) {
          return new StrategyResult("Remote publishes prefix file (is less than a day old), using it.", prefixSource,
              true);
        }
        else {
          return new StrategyResult(
              "Remote publishes prefix file (is " + prefixFileAgeInDays + " days old), using it.", prefixSource, true);
        }
      }
    }
    finally {
      uid.getLock().unlock();
    }
    throw new StrategyFailedException("Remote does not publish prefix files on path " + path);
  }

  // ==

  protected StorageFileItem retrieveFromRemoteIfExists(final MavenProxyRepository mavenProxyRepository,
      final String path) throws IOException
  {
    final ResourceStoreRequest request = new ResourceStoreRequest(path);
    request.setRequestRemoteOnly(true);
    request.getRequestContext().put(Manager.ROUTING_INITIATED_FILE_OPERATION_FLAG_KEY, Boolean.TRUE);
    // NXCM-5188: Disable checksum policy for prefix file request, it will be processed and checked anyway
    request.getRequestContext().put(ChecksumPolicy.REQUEST_CHECKSUM_POLICY_KEY, ChecksumPolicy.IGNORE);

    // check for remote presence, as fetching with setRequestRemoteOnly has a side effect of
    // DELETING the file from local cache if not present remotely. In this case, prefix
    // file (on default location) obviously originates from scrape, so we should not delete it.
    final boolean presentRemotely = mavenProxyRepository.getRemoteStorage().containsItem(mavenProxyRepository, request);
    if (!presentRemotely) {
      return null;
    }

    mavenProxyRepository.removeFromNotFoundCache(request);
    try {
      @SuppressWarnings("deprecation")
      final StorageItem item = mavenProxyRepository.retrieveItem(true, request);
      if (item instanceof StorageFileItem) {
        return (StorageFileItem) item;
      }
      else {
        return null;
      }
    }
    catch (IllegalOperationException e) {
      // eh?
      return null;
    }
    catch (ItemNotFoundException e) {
      // expected when remote does not publish it
      // not let if rot in NFC as it would block us (if interval is less than NFC keep alive)
      mavenProxyRepository.removeFromNotFoundCache(request);
      return null;
    }
  }
}
TOP

Related Classes of org.sonatype.nexus.proxy.maven.routing.internal.RemotePrefixFileStrategy

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.