Search in sources :

Example 6 with SVcsModificationOrChangeDescriptor

use of jetbrains.buildServer.server.rest.data.change.SVcsModificationOrChangeDescriptor in project teamcity-rest by JetBrains.

the class ChangeFinderTest method testChangesByBuildIdFromDependenciesHaveDescriptor.

@Test
@TestFor(issues = "TW-60774")
public void testChangesByBuildIdFromDependenciesHaveDescriptor() {
    final BuildTypeImpl buildConf1 = registerBuildType("buildConf1", "project");
    final BuildTypeImpl buildConf2 = registerBuildType("buildConf2", "project");
    createDependencyChain(buildConf2, buildConf1);
    MockVcsSupport vcs = new MockVcsSupport("vcs");
    vcs.setDAGBased(true);
    myFixture.getVcsManager().registerVcsSupport(vcs);
    SVcsRootEx parentRoot1 = myFixture.addVcsRoot(vcs.getName(), "", buildConf1);
    SVcsRootEx parentRoot2 = myFixture.addVcsRoot(vcs.getName(), "", buildConf2);
    VcsRootInstance root1 = buildConf1.getVcsRootInstanceForParent(parentRoot1);
    VcsRootInstance root2 = buildConf2.getVcsRootInstanceForParent(parentRoot2);
    assert root1 != null;
    assert root2 != null;
    setBranchSpec(root1, "+:*");
    setBranchSpec(root2, "+:*");
    SVcsModification m1 = myFixture.addModification(modification().in(root1).version("1").parentVersions("0"));
    SVcsModification m2 = myFixture.addModification(modification().in(root2).version("2").parentVersions("0"));
    SQueuedBuild qb1 = build().in(buildConf1).onModifications(m1).addToQueue();
    SQueuedBuild qb2 = build().in(buildConf2).onModifications(m2).snapshotDepends(qb1.getBuildPromotion()).addToQueue();
    SFinishedBuild build1 = finishBuild(myFixture.flushQueueAndWait(), false);
    SFinishedBuild build2 = finishBuild(myFixture.flushQueueAndWait(), false);
    List<SVcsModificationOrChangeDescriptor> items = getFinder().getItems("build:" + build2.getBuildId() + ",changesFromDependencies:true,vcsRoot:(id:" + root1.getExternalId() + ")").myEntries;
    assertEquals("There is exactly one change coming from dependency.", 1, items.size());
    ChangeDescriptor descriptor = items.get(0).getChangeDescriptor();
    assertNotNull("Change descriptor must be present when looking for changes using build id.", descriptor);
    assertEquals(ChangeDescriptorConstants.SNAPSHOT_DEPENDENCY_VCS_CHANGE, descriptor.getType());
    SVcsModification modification = items.get(0).getSVcsModification();
    assertEquals("1", modification.getDisplayVersion());
}
Also used : MockVcsSupport(jetbrains.buildServer.serverSide.impl.MockVcsSupport) SVcsModificationOrChangeDescriptor(jetbrains.buildServer.server.rest.data.change.SVcsModificationOrChangeDescriptor) BuildTypeImpl(jetbrains.buildServer.serverSide.impl.BuildTypeImpl) SVcsModificationOrChangeDescriptor(jetbrains.buildServer.server.rest.data.change.SVcsModificationOrChangeDescriptor) Test(org.testng.annotations.Test) TestFor(jetbrains.buildServer.util.TestFor)

Example 7 with SVcsModificationOrChangeDescriptor

use of jetbrains.buildServer.server.rest.data.change.SVcsModificationOrChangeDescriptor in project teamcity-rest by JetBrains.

the class ChangeRequest method serveChanges.

// todo: use locator here, like for builds with limitLookup, changes from dependencies flag, etc.
// todo: mark changes from dependencies
/**
 * Lists changes by the specified locator
 * @param locator             Change locator
 * @param projectLocator      Deprecated, use "locator" parameter instead
 * @param buildTypeLocator    Deprecated, use "locator" parameter instead
 * @param buildLocator        Deprecated, use "locator" parameter instead
 * @param vcsRootInstanceLocator      Deprecated, use "locator" parameter instead. Note that corresponding locator dimension is "vcsRootInstance"
 * @param sinceChangeLocator  Deprecated, use "locator" parameter instead
 * @param start               Deprecated, use "locator" parameter instead
 * @param count               Deprecated, use "locator" parameter instead
 * @param uriInfo             Deprecated, use "locator" parameter instead
 * @param request             Deprecated, use "locator" parameter instead
 * @return
 */
@GET
@Produces({ "application/xml", "application/json" })
@ApiOperation(value = "Get all changes.", nickname = "getAllChanges")
public Changes serveChanges(@ApiParam(hidden = true) @QueryParam("project") String projectLocator, @ApiParam(hidden = true) @QueryParam("buildType") String buildTypeLocator, @ApiParam(hidden = true) @QueryParam("build") String buildLocator, @ApiParam(hidden = true) @QueryParam("vcsRoot") String vcsRootInstanceLocator, @ApiParam(hidden = true) @QueryParam("sinceChange") String sinceChangeLocator, @ApiParam(hidden = true) @QueryParam("start") Long start, @ApiParam(hidden = true) @QueryParam("count") Integer count, @ApiParam(format = LocatorName.CHANGE) @QueryParam("locator") String locator, @QueryParam("fields") String fields, @Context UriInfo uriInfo, @Context HttpServletRequest request) {
    Locator actualLocator = locator == null ? Locator.createEmptyLocator() : new Locator(locator);
    if (!actualLocator.isSingleValue()) {
        updateLocatorDimension(actualLocator, "project", projectLocator);
        updateLocatorDimension(actualLocator, "buildType", buildTypeLocator);
        updateLocatorDimension(actualLocator, "build", buildLocator);
        updateLocatorDimension(actualLocator, "vcsRootInstance", vcsRootInstanceLocator);
        updateLocatorDimension(actualLocator, "sinceChange", sinceChangeLocator);
        updateLocatorDimension(actualLocator, "start", start != null ? String.valueOf(start) : null);
        updateLocatorDimension(actualLocator, "count", count != null ? String.valueOf(count) : null);
    }
    final String locatorText = actualLocator.isEmpty() ? null : actualLocator.getStringRepresentation();
    PagedSearchResult<SVcsModificationOrChangeDescriptor> buildModifications = myChangeFinder.getItems(locatorText);
    final UriBuilder requestUriBuilder = uriInfo.getRequestUriBuilder();
    requestUriBuilder.replaceQueryParam("count", null);
    requestUriBuilder.replaceQueryParam("start", null);
    return new Changes(buildModifications.myEntries, new PagerData(requestUriBuilder, request.getContextPath(), buildModifications, locatorText, "locator"), new Fields(fields), myBeanContext);
}
Also used : ServiceLocator(jetbrains.buildServer.ServiceLocator) Locator(jetbrains.buildServer.server.rest.data.Locator) Fields(jetbrains.buildServer.server.rest.model.Fields) SVcsModificationOrChangeDescriptor(jetbrains.buildServer.server.rest.data.change.SVcsModificationOrChangeDescriptor) PagerData(jetbrains.buildServer.server.rest.model.PagerData) UriBuilder(javax.ws.rs.core.UriBuilder) ApiOperation(io.swagger.annotations.ApiOperation)

Example 8 with SVcsModificationOrChangeDescriptor

use of jetbrains.buildServer.server.rest.data.change.SVcsModificationOrChangeDescriptor in project teamcity-rest by JetBrains.

the class ChangeFinder method getFilter.

@NotNull
@Override
public ItemFilter<SVcsModificationOrChangeDescriptor> getFilter(@NotNull final Locator locator) {
    final MultiCheckerFilter<SVcsModification> result = new MultiCheckerFilter<>();
    // myBuildType, myProject and myBranchName are handled on getting initial collection to filter
    final String vcsRootInstanceLocator = locator.getSingleDimensionValue(VCS_ROOT_INSTANCE);
    if (vcsRootInstanceLocator != null) {
        final VcsRootInstance vcsRootInstance = myVcsRootInstanceFinder.getItem(vcsRootInstanceLocator);
        result.add(item -> {
            // todo: check personal change applicability to the root
            return !item.isPersonal() && vcsRootInstance.getId() == item.getVcsRoot().getId();
        });
    }
    final String vcsRootLocator = locator.getSingleDimensionValue(VCS_ROOT);
    if (vcsRootLocator != null) {
        final VcsRoot vcsRoot = myVcsRootFinder.getItem(vcsRootLocator);
        result.add(item -> {
            // todo: check personal change applicability to the root
            return !item.isPersonal() && vcsRoot.getId() == item.getVcsRoot().getParent().getId();
        });
    }
    // todo: deprecate this
    final String sinceChangeLocator = locator.getSingleDimensionValue(SINCE_CHANGE);
    if (sinceChangeLocator != null) {
        final long sinceChangeId = getChangeIdBySinceChangeLocator(sinceChangeLocator);
        result.add(item -> sinceChangeId < item.getId());
    }
    if (locator.isUnused(USERNAME)) {
        final String username = locator.getSingleDimensionValue(USERNAME);
        if (username != null) {
            result.add(item -> {
                // todo: is ignoreCase is right here?
                return username.equalsIgnoreCase(item.getUserName());
            });
        }
    }
    if (locator.getUnusedDimensions().contains(USER)) {
        final String userLocator = locator.getSingleDimensionValue(USER);
        if (userLocator != null) {
            final SUser user = myUserFinder.getItem(userLocator);
            result.add(item -> item.getCommitters().contains(user));
        }
    }
    // TeamCity API: exclude "fake" personal changes created by TeamCity for personal builds without personal changes
    result.add(item -> {
        if (!item.isPersonal())
            return true;
        return item.getChanges().size() > 0;
    });
    final Boolean personal = locator.getSingleDimensionValueAsBoolean(PERSONAL);
    if (personal != null) {
        result.add(item -> FilterUtil.isIncludedByBooleanFilter(personal, item.isPersonal()));
    }
    if (personal != null && personal) {
        // initial collection can contain changes from any buildType/project
        final String buildTypeLocator = locator.getSingleDimensionValue(BUILD_TYPE);
        if (buildTypeLocator != null) {
            final SBuildType buildType = myBuildTypeFinder.getBuildType(null, buildTypeLocator, false);
            result.add(item -> isPersonalChangeMatchesBuildType(item, buildType));
        }
    }
    if (locator.getUnusedDimensions().contains(BUILD)) {
        final String buildLocator = locator.getSingleDimensionValue(BUILD);
        if (buildLocator != null) {
            final Set<Long> buildChanges = getBuildChangeDescriptors(myBuildFinder.getBuildPromotion(null, buildLocator), locator).map(mord -> mord.getRelatedVcsChange().getId()).collect(Collectors.toSet());
            result.add(item -> buildChanges.contains(item.getId()));
        }
    }
    // pre-9.0 dimension compatibility
    if (locator.getUnusedDimensions().contains(PROMOTION)) {
        final Long promotionLocator = locator.getSingleDimensionValueAsLong(PROMOTION);
        if (promotionLocator != null) {
            @SuppressWarnings("ConstantConditions") final Set<Long> buildChanges = getBuildChangeDescriptors(BuildFinder.getBuildPromotion(promotionLocator, myServiceLocator.findSingletonService(BuildPromotionManager.class)), null).map(mord -> mord.getRelatedVcsChange().getId()).collect(Collectors.toSet());
            result.add(item -> buildChanges.contains(item.getId()));
        }
    }
    if (locator.isUnused(BUILD_TYPE)) {
        // todo: support multiple buildTypes here
        final String buildTypeLocator = locator.getSingleDimensionValue(BUILD_TYPE);
        if (buildTypeLocator != null) {
            SBuildType buildType = myBuildTypeFinder.getBuildType(null, buildTypeLocator, false);
            // todo: this does not include "show changes from dependencies", relates to https://youtrack.jetbrains.com/issue/TW-63704
            result.add(item -> item.getRelatedConfigurations().contains(buildType));
        }
    }
    final String projectLocator = locator.getSingleDimensionValue(PROJECT);
    if (projectLocator != null) {
        final SProject project = myProjectFinder.getItem(projectLocator);
        Set<String> btIds = project.getOwnBuildTypes().stream().map(BuildTypeDescriptor::getBuildTypeId).collect(Collectors.toSet());
        result.add(item -> {
            List<String> itemBtIds = ((VcsModificationEx) item).getRelatedConfigurationIds(false);
            for (String itemBtId : itemBtIds) {
                String finalId = RemoteBuildTypeIdUtil.isValidRemoteBuildTypeId(itemBtId) ? RemoteBuildTypeIdUtil.getParentBuildTypeId(itemBtId) : itemBtId;
                if (btIds.contains(finalId)) {
                    return true;
                }
            }
            return false;
        });
    }
    if (locator.isUnused(INTERNAL_VERSION)) {
        final String internalVersion = locator.getSingleDimensionValue(INTERNAL_VERSION);
        if (internalVersion != null) {
            result.add(item -> internalVersion.equals(item.getVersion()));
        }
    }
    if (locator.isUnused(VERSION)) {
        final String displayVersion = locator.getSingleDimensionValue(VERSION);
        ValueCondition condition = ParameterCondition.createValueCondition(displayVersion);
        if (displayVersion != null) {
            result.add(item -> condition.matches(item.getDisplayVersion()));
        }
    }
    final String commentLocatorText = locator.getSingleDimensionValue(COMMENT);
    if (commentLocatorText != null) {
        final String containsText = new Locator(commentLocatorText).getSingleDimensionValue("contains");
        // Preserve legacy behaviour
        if (containsText != null) {
            result.add(item -> item.getDescription().contains(containsText));
        // todo: check unprocessed dimensions
        } else {
            ValueCondition condition = ParameterCondition.createValueCondition(commentLocatorText);
            result.add(item -> condition.matches(item.getDescription()));
        }
    }
    if (locator.getUnusedDimensions().contains(PENDING)) {
        final Boolean pending = locator.getSingleDimensionValueAsBoolean(PENDING);
        if (pending != null) {
            // todo: support multiple buildTypes here
            final String buildTypeLocator = locator.getSingleDimensionValue(BUILD_TYPE);
            final SBuildType buildType = buildTypeLocator == null ? null : myBuildTypeFinder.getBuildType(null, buildTypeLocator, false);
            final Set<SVcsModification> pendingChanges = getPendingChanges(buildType, locator).map(mcd -> mcd.getSVcsModification()).collect(Collectors.toSet());
            result.add(item -> FilterUtil.isIncludedByBooleanFilter(pending, pendingChanges.contains(item)));
        }
    }
    final String fileLocator = locator.getSingleDimensionValue(FILE);
    if (fileLocator != null) {
        // todo: use conditions here
        final String pathLocatorText = new Locator(fileLocator).getSingleDimensionValue("path");
        // todo: check unknown locator dimensions
        if (pathLocatorText != null) {
            final String containsText = new Locator(pathLocatorText).getSingleDimensionValue("contains");
            if (containsText != null) {
                result.add(item -> {
                    for (VcsFileModification vcsFileModification : item.getChanges()) {
                        if (vcsFileModification.getFileName().contains(containsText)) {
                            return true;
                        }
                    }
                    return false;
                });
            // todo: check unknown locator dimensions
            } else {
                ValueCondition condition = ParameterCondition.createValueCondition(pathLocatorText);
                result.add(item -> item.getChanges().stream().map(m -> m.getFileName()).anyMatch(condition::matches));
            }
        }
    }
    if (TeamCityProperties.getBoolean("rest.request.changes.check.enforceChangeViewPermission")) {
        result.add(myPermissionChecker::checkCanView);
    }
    return new UnwrappingFilter<>(result, SVcsModificationOrChangeDescriptor::getSVcsModification);
}
Also used : LocatorProcessException(jetbrains.buildServer.server.rest.errors.LocatorProcessException) WrappingItemHolder(jetbrains.buildServer.server.rest.data.util.WrappingItemHolder) java.util(java.util) SVcsModificationOrChangeDescriptor(jetbrains.buildServer.server.rest.data.change.SVcsModificationOrChangeDescriptor) LocatorName(jetbrains.buildServer.server.rest.swagger.constants.LocatorName) DuplicateChecker(jetbrains.buildServer.server.rest.data.util.DuplicateChecker) LocatorResource(jetbrains.buildServer.server.rest.swagger.annotations.LocatorResource) AuthorityHolder(jetbrains.buildServer.serverSide.auth.AuthorityHolder) UnwrappingFilter(jetbrains.buildServer.server.rest.data.util.UnwrappingFilter) Function(java.util.function.Function) BadRequestException(jetbrains.buildServer.server.rest.errors.BadRequestException) LocatorDimensionDataType(jetbrains.buildServer.server.rest.swagger.constants.LocatorDimensionDataType) BuildTypeDescriptor(jetbrains.buildServer.BuildTypeDescriptor) UserChangesFacade(jetbrains.buildServer.serverSide.userChanges.UserChangesFacade) KeyDuplicateChecker(jetbrains.buildServer.server.rest.data.util.KeyDuplicateChecker) StringUtil(jetbrains.buildServer.util.StringUtil) SecurityContext(jetbrains.buildServer.serverSide.auth.SecurityContext) CollectionsUtil(jetbrains.buildServer.util.CollectionsUtil) PagerData(jetbrains.buildServer.server.rest.model.PagerData) Constants(jetbrains.buildServer.server.rest.request.Constants) ServiceLocator(jetbrains.buildServer.ServiceLocator) jetbrains.buildServer.serverSide(jetbrains.buildServer.serverSide) RemoteBuildTypeIdUtil(jetbrains.buildServer.serverSide.impl.RemoteBuildTypeIdUtil) BFSVisitorAdapter(jetbrains.buildServer.util.graph.BFSVisitorAdapter) Predicate(java.util.function.Predicate) VcsModificationEx(jetbrains.buildServer.vcs.impl.VcsModificationEx) DAGIterator(jetbrains.buildServer.util.graph.DAGIterator) jetbrains.buildServer.vcs(jetbrains.buildServer.vcs) Collectors(java.util.stream.Collectors) RemoteBuildType(jetbrains.buildServer.serverSide.impl.RemoteBuildType) Nullable(org.jetbrains.annotations.Nullable) DAG(jetbrains.buildServer.util.graph.DAG) Stream(java.util.stream.Stream) LocatorDimension(jetbrains.buildServer.server.rest.swagger.annotations.LocatorDimension) NotFoundException(jetbrains.buildServer.server.rest.errors.NotFoundException) AuthUtil(jetbrains.buildServer.serverSide.auth.AuthUtil) NotNull(org.jetbrains.annotations.NotNull) SUser(jetbrains.buildServer.users.SUser) VcsModificationEx(jetbrains.buildServer.vcs.impl.VcsModificationEx) UnwrappingFilter(jetbrains.buildServer.server.rest.data.util.UnwrappingFilter) SUser(jetbrains.buildServer.users.SUser) SVcsModificationOrChangeDescriptor(jetbrains.buildServer.server.rest.data.change.SVcsModificationOrChangeDescriptor) ServiceLocator(jetbrains.buildServer.ServiceLocator) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

SVcsModificationOrChangeDescriptor (jetbrains.buildServer.server.rest.data.change.SVcsModificationOrChangeDescriptor)8 ServiceLocator (jetbrains.buildServer.ServiceLocator)4 PagerData (jetbrains.buildServer.server.rest.model.PagerData)4 Collectors (java.util.stream.Collectors)3 Stream (java.util.stream.Stream)3 BadRequestException (jetbrains.buildServer.server.rest.errors.BadRequestException)3 NotFoundException (jetbrains.buildServer.server.rest.errors.NotFoundException)3 LocatorName (jetbrains.buildServer.server.rest.swagger.constants.LocatorName)3 ApiOperation (io.swagger.annotations.ApiOperation)2 java.util (java.util)2 Function (java.util.function.Function)2 Predicate (java.util.function.Predicate)2 UriBuilder (javax.ws.rs.core.UriBuilder)2 BuildTypeDescriptor (jetbrains.buildServer.BuildTypeDescriptor)2 Locator (jetbrains.buildServer.server.rest.data.Locator)2 DuplicateChecker (jetbrains.buildServer.server.rest.data.util.DuplicateChecker)2 KeyDuplicateChecker (jetbrains.buildServer.server.rest.data.util.KeyDuplicateChecker)2 UnwrappingFilter (jetbrains.buildServer.server.rest.data.util.UnwrappingFilter)2 WrappingItemHolder (jetbrains.buildServer.server.rest.data.util.WrappingItemHolder)2 LocatorProcessException (jetbrains.buildServer.server.rest.errors.LocatorProcessException)2