private void fixRemoteUrl(ResourceStoreRequest request) {
    if (overwriteRemoteUrl != null) {
      return;
    }

    if (P2Constants.SITE_XML.equals(request.getRequestPath())) {
      return;
    }

    try {
      RepositoryItemUid siteUID = createUid(P2Constants.SITE_XML);
      ResourceStoreRequest siteRequest = new ResourceStoreRequest(siteUID.getPath());
      StorageFileItem siteItem;
      try {
        siteItem = (StorageFileItem) getLocalStorage().retrieveItem(this, siteRequest);
      } catch (ItemNotFoundException e) {
        siteItem =
            (StorageFileItem) getRemoteStorage().retrieveItem(this, siteRequest, getRemoteUrl());
      }

      PlexusConfiguration plexusConfig =
          new XmlPlexusConfiguration(
              Xpp3DomBuilder.build(new InputStreamReader(siteItem.getInputStream())));

      this.overwriteRemoteUrl = plexusConfig.getAttribute("url");
      getLogger()
          .info("Remote update site does overwrite the remote url " + this.overwriteRemoteUrl);
    } catch (Exception e) {
      getLogger().debug(e.getMessage(), e);
      this.overwriteRemoteUrl = "";
    }
  }
Example #2
0
  @Override
  public void storeItem(final ProxyRepository repository, final StorageItem item)
      throws UnsupportedStorageOperationException, RemoteStorageException {
    if (!(item instanceof StorageFileItem)) {
      throw new UnsupportedStorageOperationException(
          "Storing of non-files remotely is not supported!");
    }

    final StorageFileItem fileItem = (StorageFileItem) item;

    final ResourceStoreRequest request = new ResourceStoreRequest(item);

    final URL remoteUrl =
        appendQueryString(getAbsoluteUrlFromBase(repository, request), repository);

    final HttpPut method = new HttpPut(remoteUrl.toExternalForm());

    final InputStreamEntity entity;
    try {
      entity = new InputStreamEntity(fileItem.getInputStream(), fileItem.getLength());
    } catch (IOException e) {
      throw new RemoteStorageException(
          e.getMessage()
              + " [repositoryId=\""
              + repository.getId()
              + "\", requestPath=\""
              + request.getRequestPath()
              + "\", remoteUrl=\""
              + remoteUrl.toString()
              + "\"]",
          e);
    }

    entity.setContentType(fileItem.getMimeType());
    method.setEntity(entity);

    final HttpResponse httpResponse = executeRequestAndRelease(repository, request, method);
    final int statusCode = httpResponse.getStatusLine().getStatusCode();

    if (statusCode != HttpStatus.SC_OK
        && statusCode != HttpStatus.SC_CREATED
        && statusCode != HttpStatus.SC_NO_CONTENT
        && statusCode != HttpStatus.SC_ACCEPTED) {
      throw new RemoteStorageException(
          "Unexpected response code while executing "
              + method.getMethod()
              + " method [repositoryId=\""
              + repository.getId()
              + "\", requestPath=\""
              + request.getRequestPath()
              + "\", remoteUrl=\""
              + remoteUrl.toString()
              + "\"]. Expected: \"any success (2xx)\". Received: "
              + statusCode
              + " : "
              + httpResponse.getStatusLine().getReasonPhrase());
    }
  }
  protected Model getPom(Variant variant, Request request, Response response)
      throws ResourceException {
    Form form = request.getResourceRef().getQueryAsForm();

    // TODO: enable only one section retrieval of POM, ie. only mailing lists, or team members

    String groupId = form.getFirstValue("g");

    String artifactId = form.getFirstValue("a");

    String version = form.getFirstValue("v");

    String repositoryId = form.getFirstValue("r");

    if (groupId == null || artifactId == null || version == null || repositoryId == null) {
      throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST);
    }

    ArtifactStoreRequest gavRequest =
        getResourceStoreRequest(
            request, false, repositoryId, groupId, artifactId, version, null, null, "pom");

    try {
      MavenRepository mavenRepository = getMavenRepository(repositoryId);

      ArtifactStoreHelper helper = mavenRepository.getArtifactStoreHelper();

      InputStream pomContent = null;

      InputStreamReader ir = null;

      Model pom = null;

      try {
        StorageFileItem file = helper.retrieveArtifactPom(gavRequest);

        pomContent = file.getInputStream();

        MavenXpp3Reader reader = new MavenXpp3Reader();

        ir = new InputStreamReader(pomContent);

        pom = reader.read(ir);
      } finally {
        IOUtil.close(pomContent);

        IOUtil.close(ir);
      }

      return pom;

    } catch (Exception e) {
      handleException(request, response, e);
    }

    return null;
  }
  @Test
  public void hiddenTargetHandlingAtRoot() throws Exception {
    // test subject
    final DefaultFSPeer subject = new DefaultFSPeer();

    // repo base
    File repoBase = new File("target/repoId");

    // the file we want to store
    File target = new File(repoBase, "archetype-catalog.xml");
    target.getParentFile().mkdirs();

    final StorageFileItem file = Mockito.mock(StorageFileItem.class);
    Mockito.when(file.getPath()).thenReturn("/archetype-catalog.xml");
    Mockito.when(file.getParentPath()).thenReturn("/");

    // getting hidden target for target
    File hiddenTarget = subject.getHiddenTarget(null, repoBase, target, file);
    assertThat(hiddenTarget, notNullValue());
    assertThat(hiddenTarget, isFile());
    // startsWith, as garbage is appended to it's end
    assertThat(hiddenTarget.getName(), startsWith("archetype-catalog.xml"));
    // contains, as OS path from root is prefixing this, and garbage at the end suffixing it
    assertThat(
        hiddenTarget.getPath(),
        containsString(
            "target/repoId/.nexus/tmp/archetype-catalog.xml".replace("/", File.separator)));

    // writing to hidden target is handled elsewhere, so we simulate content being written out
    final String PAYLOAD = "dummy payload";
    FileUtils.write(hiddenTarget, PAYLOAD);

    // handle the rename
    subject.handleRenameOperation(hiddenTarget, target);

    // hidden should cease to exist
    assertThat(hiddenTarget, not(exists()));
    // target should exists
    assertThat(target, exists());
    // name should be not garbaged anymore
    assertThat(target.getName(), equalTo("archetype-catalog.xml"));
    // path prefixed by OS from root, no garbage at tail
    assertThat(
        target.getPath(),
        endsWith("target/repoId/archetype-catalog.xml".replace("/", File.separator)));
    // content is fine too
    assertThat(FileUtils.readFileToString(target), equalTo(PAYLOAD));
  }
  @Override
  public ContentLocator generateContent(Repository repository, String path, StorageFileItem item)
      throws IllegalOperationException, ItemNotFoundException, LocalStorageException {
    // make length unknown (since it will be known only in the moment of actual content pull)
    item.setLength(-1);

    return new ArchetypeContentLocator(
        repository.getId(),
        ((DefaultIndexerManager) indexerManager).getRepositoryIndexContext(repository),
        macPlugin,
        new ArtifactInfoFilter() {
          public boolean accepts(IndexingContext ctx, ArtifactInfo ai) {
            return indexArtifactFilter.filterArtifactInfo(ai);
          }
        });
  }
Example #6
0
  /**
   * Validate an "XML like file" by searching for passed in patterns (using plain string matching),
   * consuming at most lines as passed in as parameter.
   *
   * @param file file who's content needs to be checked for.
   * @param expectedPattern the expected String pattern to search for.
   * @param linesToCheck amount of lines (as detected by Scanner) to consume during check.
   * @return {@link FileTypeValidity.VALID} if pattern found, {@link FileTypeValidity.INVALID}
   *     otherwise.
   * @throws IOException in case of IO problem while reading file content.
   */
  public static FileTypeValidity validateXmlLikeFile(
      final StorageFileItem file, final String expectedPattern, final int linesToCheck)
      throws IOException {
    int lineCount = 0;
    BufferedInputStream bis = null;
    try {
      bis = new BufferedInputStream(file.getInputStream());
      Scanner scanner = new Scanner(bis);
      while (scanner.hasNextLine() && lineCount < linesToCheck) {
        lineCount++;
        String line = scanner.nextLine();
        if (line.contains(expectedPattern)) {
          return FileTypeValidity.VALID;
        }
      }
    } finally {
      IOUtil.close(bis);
    }

    return FileTypeValidity.INVALID;
  }
    public void doOnCollectionExit(WalkerContext context, StorageCollectionItem coll)
        throws Exception {
      if (getLogger().isDebugEnabled()) {
        getLogger().debug("onCollectionExit() :: " + coll.getRepositoryItemUid().toString());
      }

      shouldProcessCollection = coll.getPath().endsWith("SNAPSHOT");

      if (!shouldProcessCollection) {
        return;
      }

      deletableSnapshotsAndFiles.clear();

      remainingSnapshotsAndFiles.clear();

      removeWholeGAV = false;

      Gav gav = null;

      Collection<StorageItem> items;

      items = repository.list(false, coll);

      HashSet<Long> versionsToRemove = new HashSet<Long>();

      // gathering the facts
      for (StorageItem item : items) {
        if (!item.isVirtual() && !StorageCollectionItem.class.isAssignableFrom(item.getClass())) {
          gav =
              ((MavenRepository) coll.getRepositoryItemUid().getRepository())
                  .getGavCalculator()
                  .pathToGav(item.getPath());

          if (gav != null) {
            // if we find a pom, check for delete on release
            if (!gav.isHash() && !gav.isSignature() && gav.getExtension().equals("pom")) {
              if (request.isRemoveIfReleaseExists()
                  && releaseExistsForSnapshot(gav, item.getItemContext())) {
                getLogger().debug("Found POM and release exists, removing whole gav.");

                removeWholeGAV = true;

                // Will break out and junk whole gav
                break;
              }
            }

            item.getItemContext().put(Gav.class.getName(), gav);

            if (gav.getSnapshotTimeStamp() != null) {
              getLogger().debug("Using GAV snapshot timestamp");

              long itemTimestamp = gav.getSnapshotTimeStamp().longValue();

              getLogger().debug("NOW is " + itemTimestamp);

              // If this timestamp is already marked to be removed, junk it
              if (versionsToRemove.contains(new Long(itemTimestamp))) {
                addStorageFileItemToMap(deletableSnapshotsAndFiles, gav, (StorageFileItem) item);
              } else {
                getLogger()
                    .debug("itemTimestamp=" + itemTimestamp + ", dateTreshold=" + dateThreshold);

                // if dateTreshold is not used (zero days) OR
                // if itemTimestamp is less then dateTreshold (NB: both are positive!)
                // below will the retentionCount overrule if needed this
                if (-1 == dateThreshold || itemTimestamp < dateThreshold) {
                  versionsToRemove.add(new Long(itemTimestamp));
                  addStorageFileItemToMap(deletableSnapshotsAndFiles, gav, (StorageFileItem) item);
                } else {
                  addStorageFileItemToMap(remainingSnapshotsAndFiles, gav, (StorageFileItem) item);
                }
              }
            } else {
              // If no timestamp on gav, then it is a non-unique snapshot
              // and should _not_ be removed
              getLogger()
                  .debug("GAV Snapshot timestamp not available, skipping non-unique snapshot");

              addStorageFileItemToMap(remainingSnapshotsAndFiles, gav, (StorageFileItem) item);
            }
          }
        }
      }

      // and doing the work here
      if (removeWholeGAV) {
        try {
          for (StorageItem item : items) {
            try {
              // preserve possible subdirs
              if (!(item instanceof StorageCollectionItem)) {
                repository.deleteItem(false, new ResourceStoreRequest(item));
              }
            } catch (ItemNotFoundException e) {
              if (getLogger().isDebugEnabled()) {
                getLogger()
                    .debug(
                        "Could not delete whole GAV " + coll.getRepositoryItemUid().toString(), e);
              }
            }
          }
        } catch (Exception e) {
          getLogger()
              .warn("Could not delete whole GAV " + coll.getRepositoryItemUid().toString(), e);
        }
      } else {
        // and now check some things
        if (remainingSnapshotsAndFiles.size() < request.getMinCountOfSnapshotsToKeep()) {
          // do something
          if (remainingSnapshotsAndFiles.size() + deletableSnapshotsAndFiles.size()
              < request.getMinCountOfSnapshotsToKeep()) {
            // delete nothing, since there is less snapshots in total as allowed
            deletableSnapshotsAndFiles.clear();
          } else {
            TreeSet<Version> keys = new TreeSet<Version>(deletableSnapshotsAndFiles.keySet());

            while (!keys.isEmpty()
                && remainingSnapshotsAndFiles.size() < request.getMinCountOfSnapshotsToKeep()) {
              Version keyToMove = keys.last();

              if (remainingSnapshotsAndFiles.containsKey(keyToMove)) {
                remainingSnapshotsAndFiles
                    .get(keyToMove)
                    .addAll(deletableSnapshotsAndFiles.get(keyToMove));
              } else {
                remainingSnapshotsAndFiles.put(
                    keyToMove, deletableSnapshotsAndFiles.get(keyToMove));
              }

              deletableSnapshotsAndFiles.remove(keyToMove);

              keys.remove(keyToMove);
            }
          }
        }

        // NEXUS-814: is this GAV have remaining artifacts?
        boolean gavHasMoreTimestampedSnapshots = remainingSnapshotsAndFiles.size() > 0;

        for (Version key : deletableSnapshotsAndFiles.keySet()) {

          List<StorageFileItem> files = deletableSnapshotsAndFiles.get(key);
          deletedSnapshots++;

          for (StorageFileItem file : files) {
            try {
              // NEXUS-814: mark that we are deleting a TS snapshot, but there are still remaining
              // ones in repository.
              if (gavHasMoreTimestampedSnapshots) {
                file.getItemContext().put(MORE_TS_SNAPSHOTS_EXISTS_FOR_GAV, Boolean.TRUE);
              }

              gav = (Gav) file.getItemContext().get(Gav.class.getName());

              repository.deleteItem(false, new ResourceStoreRequest(file));

              deletedFiles++;
            } catch (ItemNotFoundException e) {
              if (getLogger().isDebugEnabled()) {
                getLogger().debug("Could not delete file:", e);
              }
            } catch (Exception e) {
              getLogger().info("Could not delete file:", e);
            }
          }
        }
      }

      removeDirectoryIfEmpty(coll);

      updateMetadataIfNecessary(context, coll);
    }
  protected Object getContent(
      Variant variant, boolean redirectTo, Request request, Response response)
      throws ResourceException {
    Form form = request.getResourceRef().getQueryAsForm();

    String groupId = form.getFirstValue("g");

    String artifactId = form.getFirstValue("a");

    String version = form.getFirstValue("v");

    String packaging = form.getFirstValue("p");

    String classifier = form.getFirstValue("c");

    String repositoryId = form.getFirstValue("r");

    String extension = form.getFirstValue("e");

    if (groupId == null || artifactId == null || version == null || repositoryId == null) {
      throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST);
    }

    // default the packaging
    if (StringUtils.isBlank(packaging)) {
      packaging = "jar";
    }

    ArtifactStoreRequest gavRequest =
        getResourceStoreRequest(
            request,
            false,
            repositoryId,
            groupId,
            artifactId,
            version,
            packaging,
            classifier,
            extension);

    try {
      MavenRepository mavenRepository = getMavenRepository(repositoryId);

      ArtifactStoreHelper helper = mavenRepository.getArtifactStoreHelper();

      StorageFileItem file = helper.retrieveArtifact(gavRequest);

      if (redirectTo) {
        Reference fileReference =
            createRepositoryReference(
                request,
                file.getRepositoryItemUid().getRepository().getId(),
                file.getRepositoryItemUid().getPath());

        response.setLocationRef(fileReference);

        response.setStatus(Status.REDIRECTION_PERMANENT);

        String redirectMessage =
            "If you are not automatically redirected use this url: " + fileReference.toString();
        return redirectMessage;
      } else {
        Representation result = new StorageFileItemRepresentation(file);

        result.setDownloadable(true);

        result.setDownloadName(file.getName());

        return result;
      }

    } catch (Exception e) {
      handleException(request, response, e);
    }

    return null;
  }
  private void mirrorUpdateSite(boolean force)
      throws StorageException, IllegalOperationException, UnsupportedStorageOperationException {
    UpdateSite site;
    try {
      RepositoryItemUid siteUID = createUid(P2Constants.SITE_XML);
      String oldSha1 = null;

      ResourceStoreRequest request = new ResourceStoreRequest(siteUID.getPath());

      try {
        oldSha1 =
            getLocalStorage()
                .retrieveItem(this, request)
                .getAttributes()
                .get(DigestCalculatingInspector.DIGEST_SHA1_KEY);
      } catch (ItemNotFoundException e) {
        // it's okay
      }

      StorageFileItem siteItem = (StorageFileItem) doRetrieveRemoteItem(request);

      if (!force
          && oldSha1 != null
          && oldSha1.equals(
              siteItem.getAttributes().get(DigestCalculatingInspector.DIGEST_SHA1_KEY))) {
        return;
      }
      site = UpdateSite.read(siteItem.getInputStream());
    } catch (Exception e) {
      throw new StorageException("Could not read site.xml", e);
    }

    List<FeatureRef> features = site.getFeatures();

    getLogger().info("Mirroring " + features.size() + " features from update site " + getName());

    final Set<String> mirrored = new HashSet<String>();

    for (IFeatureRef feature : features) {
      mirrorFeature(site, feature, mirrored);
    }

    ResourceStoreRequest root = new ResourceStoreRequest(RepositoryItemUid.PATH_ROOT);

    DefaultWalkerContext ctx = new DefaultWalkerContext(this, root, filter);
    ctx.getContext().put("mirrored", mirrored);
    ctx.getProcessors()
        .add(
            new AbstractWalkerProcessor() {
              @SuppressWarnings("unchecked")
              @Override
              public void processItem(WalkerContext context, StorageItem item) throws Exception {
                Set<String> mirrored = (Set<String>) context.getContext().get("mirrored");

                if (item.getRepositoryItemUid().getBooleanAttributeValue(IsHiddenAttribute.class)) {
                  return;
                }

                if (item instanceof StorageFileItem
                    && !mirrored.contains(item.getPath().substring(1))) {
                  doDeleteItem(new ResourceStoreRequest(item.getPath()));
                }
              }
            });
    getWalker().walk(ctx);

    getLogger().debug("Generating P2 metadata for Eclipse Update Site " + getName());

    File baseDir = getLocalStorage().getBaseDir(this, root);
    File metadataDir = new File(baseDir, ".p2");

    try {
      FileUtils.deleteDirectory(metadataDir);
    } catch (IOException e) {
      getLogger().warn("Unexpected IOException", e);
    }

    p2.generateSiteMetadata(baseDir, metadataDir, getName());

    try {
      importFile(metadataDir, P2Constants.ARTIFACTS_PATH);
      importFile(metadataDir, P2Constants.CONTENT_PATH);
      FileUtils.deleteDirectory(metadataDir);
    } catch (IOException e) {
      // TODO this can actually happen on Windows
      getLogger().warn("Unexpected IOException", e);
    }
  }