Search in sources :

Example 6 with LocatorProcessException

use of jetbrains.buildServer.server.rest.errors.LocatorProcessException in project teamcity-rest by JetBrains.

the class BranchFinder method getBranchSearchOptions.

@NotNull
private BranchSearchOptions getBranchSearchOptions(@NotNull final Locator locator) {
    BranchesPolicy branchesPolicy = BranchesPolicy.ACTIVE_HISTORY_AND_ACTIVE_VCS_BRANCHES;
    final String policyDimension = locator.getSingleDimensionValue(POLICY);
    if (policyDimension != null) {
        try {
            branchesPolicy = BranchesPolicy.valueOf(policyDimension.toUpperCase());
        } catch (IllegalArgumentException e) {
            throw new BadRequestException("Invalid value '" + policyDimension + "' for '" + POLICY + "' dimension. Supported values are: " + Arrays.toString(BranchesPolicy.values()));
        }
    }
    Boolean changesFromDependencies;
    try {
        changesFromDependencies = locator.getSingleDimensionValueAsStrictBoolean(CHANGES_FROM_DEPENDENCIES, null);
    } catch (LocatorProcessException e) {
        throw new LocatorProcessException("Invalid '" + CHANGES_FROM_DEPENDENCIES + "' dimension", e);
    }
    return new BranchSearchOptions(branchesPolicy, changesFromDependencies);
}
Also used : BadRequestException(jetbrains.buildServer.server.rest.errors.BadRequestException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) LocatorProcessException(jetbrains.buildServer.server.rest.errors.LocatorProcessException) NotNull(org.jetbrains.annotations.NotNull)

Example 7 with LocatorProcessException

use of jetbrains.buildServer.server.rest.errors.LocatorProcessException in project teamcity-rest by JetBrains.

the class Locator method parse.

@NotNull
private static HashMap<String, List<String>> parse(@NotNull final String locator, @Nullable final String[] supportedDimensions, @NotNull final Collection<String> hiddenSupportedDimensions, final boolean extendedMode) {
    StringPool stringPool = RestContext.getThreadLocalStringPool();
    HashMap<String, List<String>> result = new HashMap<>();
    String currentDimensionName;
    String currentDimensionValue;
    int parsedIndex = 0;
    while (parsedIndex < locator.length()) {
        // expecting name start at parsedIndex
        int nameEnd = locator.length();
        String nextDelimeter = null;
        int currentIndex = parsedIndex;
        while (currentIndex < locator.length()) {
            if (locator.startsWith(DIMENSIONS_DELIMITER, currentIndex)) {
                nextDelimeter = DIMENSIONS_DELIMITER;
                nameEnd = currentIndex;
                break;
            }
            if (locator.startsWith(DIMENSION_COMPLEX_VALUE_START_DELIMITER, currentIndex)) {
                nextDelimeter = DIMENSION_COMPLEX_VALUE_START_DELIMITER;
                nameEnd = currentIndex;
                break;
            }
            if (locator.startsWith(DIMENSION_NAME_VALUE_DELIMITER, currentIndex)) {
                nextDelimeter = DIMENSION_NAME_VALUE_DELIMITER;
                nameEnd = currentIndex;
                break;
            }
            currentIndex++;
        }
        if (nameEnd == parsedIndex) {
            throw new LocatorProcessException(locator, parsedIndex, "Could not find dimension name, found '" + nextDelimeter + "' instead");
        }
        currentDimensionName = locator.substring(parsedIndex, nameEnd);
        if (!isValidName(currentDimensionName, supportedDimensions, hiddenSupportedDimensions, extendedMode)) {
            throw new LocatorProcessException(locator, parsedIndex, "Invalid dimension name :'" + currentDimensionName + "'. Should contain only alpha-numeric symbols" + (supportedDimensions == null || supportedDimensions.length == 0 ? "" : " or be known one: " + Arrays.toString(supportedDimensions)));
        }
        currentDimensionValue = "";
        parsedIndex = nameEnd;
        if (nextDelimeter != null) {
            if (DIMENSIONS_DELIMITER.equals(nextDelimeter)) {
                parsedIndex = nameEnd + nextDelimeter.length();
            } else {
                if (DIMENSION_NAME_VALUE_DELIMITER.equals(nextDelimeter)) {
                    parsedIndex = nameEnd + nextDelimeter.length();
                }
                if (DIMENSION_COMPLEX_VALUE_START_DELIMITER.equals(nextDelimeter)) {
                    parsedIndex = nameEnd;
                }
                // here begins the value at parsedIndex
                final String valueAndRest = locator.substring(parsedIndex);
                if (valueAndRest.startsWith(DIMENSION_COMPLEX_VALUE_START_DELIMITER)) {
                    // complex value detected
                    final int complexValueEnd = findNextOrEndOfStringConsideringBraces(valueAndRest, null);
                    if (complexValueEnd < 0) {
                        throw new LocatorProcessException(locator, parsedIndex + DIMENSION_COMPLEX_VALUE_START_DELIMITER.length(), "Could not find matching '" + DIMENSION_COMPLEX_VALUE_END_DELIMITER + "'");
                    }
                    currentDimensionValue = valueAndRest.substring(DIMENSION_COMPLEX_VALUE_START_DELIMITER.length(), complexValueEnd - DIMENSION_COMPLEX_VALUE_END_DELIMITER.length());
                    parsedIndex = parsedIndex + complexValueEnd;
                    if (parsedIndex != locator.length()) {
                        if (!locator.startsWith(DIMENSIONS_DELIMITER, parsedIndex)) {
                            throw new LocatorProcessException(locator, parsedIndex, "No dimensions delimiter '" + DIMENSIONS_DELIMITER + "' after complex value");
                        } else {
                            parsedIndex += DIMENSIONS_DELIMITER.length();
                        }
                    }
                } else {
                    int valueEnd = findNextOrEndOfStringConsideringBraces(valueAndRest, DIMENSIONS_DELIMITER);
                    if (valueEnd < 0) {
                        throw new LocatorProcessException(locator, parsedIndex, "Could not find matching '" + DIMENSION_COMPLEX_VALUE_END_DELIMITER + "'");
                    } else if (valueEnd == valueAndRest.length()) {
                        currentDimensionValue = valueAndRest;
                        parsedIndex = locator.length();
                    } else {
                        currentDimensionValue = valueAndRest.substring(0, valueEnd);
                        parsedIndex = parsedIndex + valueEnd + DIMENSIONS_DELIMITER.length();
                    }
                    if (ANY_LITERAL.equals(currentDimensionValue)) {
                        // this was not a complex value, so setting exactly the same string to be able to determine this on retrieving
                        currentDimensionValue = ANY_LITERAL;
                    }
                }
                String unescapedValue = getBase64UnescapedSingleValue(currentDimensionValue, extendedMode);
                if (unescapedValue != null)
                    currentDimensionValue = unescapedValue;
            }
        }
        currentDimensionName = stringPool.reuse(currentDimensionName);
        final List<String> currentList = result.get(currentDimensionName);
        final List<String> newList;
        if (currentList == null) {
            // Dimension with an empy string value is a frequent case in a Fields, so let's reuse a special list for that list.
            newList = currentDimensionValue.equals("") ? LIST_WITH_EMPTY_STRING : Arrays.asList(currentDimensionValue);
        } else {
            newList = new ArrayList<>(currentList);
            newList.add(stringPool.reuse(currentDimensionValue));
        }
        result.put(currentDimensionName, newList);
    }
    return result;
}
Also used : StringPool(jetbrains.buildServer.server.rest.util.StringPool) LocatorProcessException(jetbrains.buildServer.server.rest.errors.LocatorProcessException) NotNull(org.jetbrains.annotations.NotNull)

Example 8 with LocatorProcessException

use of jetbrains.buildServer.server.rest.errors.LocatorProcessException in project teamcity-rest by JetBrains.

the class GenericBuildsFilter method isIncluded.

public boolean isIncluded(@NotNull final SBuild build) {
    if (myAgentName != null && !myAgentName.equals(build.getAgentName())) {
        return false;
    }
    if (myBuildType != null && !myBuildType.getBuildTypeId().equals(build.getBuildTypeId())) {
        return false;
    }
    if (myProject != null && !isUnderProject(myProject, build)) {
        return false;
    }
    if (myStatus != null && !myStatus.equalsIgnoreCase(build.getStatusDescriptor().getStatus().getText())) {
        return false;
    }
    if (myNumber != null && !myNumber.equals(build.getBuildNumber())) {
        return false;
    }
    if (!FilterUtil.isIncludedByBooleanFilter(myPersonal, build.isPersonal())) {
        return false;
    }
    if (!FilterUtil.isIncludedByBooleanFilter(myCanceled, build.getCanceledInfo() != null)) {
        return false;
    }
    if (!FilterUtil.isIncludedByBooleanFilter(myRunning, !build.isFinished())) {
        return false;
    }
    if (!FilterUtil.isIncludedByBooleanFilter(myPinned, build.isPinned())) {
        return false;
    }
    if (myTags != null && myTags.size() > 0 && myTags.get(0).startsWith("format:extended")) {
        @NotNull final List<String> buildTags = build.getTags();
        // unofficial experimental support for "tag:(format:regexp,value:.*)" tag specification
        // todo: locator parsing logic should be moved to build locator parsing
        final Locator tagsLocator;
        try {
            tagsLocator = new Locator(myTags.get(0));
            if (!isTagsMatchLocator(buildTags, tagsLocator)) {
                return false;
            }
            final Set<String> unusedDimensions = tagsLocator.getUnusedDimensions();
            if (unusedDimensions.size() > 0) {
                throw new BadRequestException("Unknown dimensions in locator 'tag': " + unusedDimensions);
            }
        } catch (LocatorProcessException e) {
            throw new BadRequestException("Invalid locator 'tag': " + e.getMessage(), e);
        }
    } else if (myTags != null && myTags.size() > 0 && !build.getTags().containsAll(myTags)) {
        return false;
    }
    if (!myBranchMatcher.matches(build.getBuildPromotion())) {
        return false;
    } else {
        // default to only default branch
        if (!myBranchMatcher.isDefined()) {
            @Nullable final Branch buildBranch = build.getBuildPromotion().getBranch();
            if (buildBranch != null && !buildBranch.isDefaultBranch())
                return false;
        }
    }
    if (myUser != null) {
        final SUser userWhoTriggered = build.getTriggeredBy().getUser();
        if (!build.getTriggeredBy().isTriggeredByUser() || (userWhoTriggered == null) || (myUser.getId() != userWhoTriggered.getId())) {
            return false;
        }
    }
    if (isExcludedBySince(build))
        return false;
    if (myUntil != null) {
        if (myUntil.before(build)) {
            return false;
        }
    }
    if (myAgents != null && !myAgents.contains(build.getAgent())) {
        return false;
    }
    if (myParameterCondition != null) {
        if (!myParameterCondition.matches(Build.getBuildResultingParameters(build.getBuildPromotion(), myServiceLocator))) {
            return false;
        }
    }
    return true;
}
Also used : ServiceLocator(jetbrains.buildServer.ServiceLocator) SUser(jetbrains.buildServer.users.SUser) BadRequestException(jetbrains.buildServer.server.rest.errors.BadRequestException) NotNull(org.jetbrains.annotations.NotNull) LocatorProcessException(jetbrains.buildServer.server.rest.errors.LocatorProcessException) Nullable(org.jetbrains.annotations.Nullable)

Example 9 with LocatorProcessException

use of jetbrains.buildServer.server.rest.errors.LocatorProcessException in project teamcity-rest by JetBrains.

the class FinderImpl method getItemsByLocator.

@NotNull
private PagedSearchResult<ITEM> getItemsByLocator(@Nullable final Locator originalLocator, final boolean multipleItemsQuery) {
    long startTime = System.nanoTime();
    Locator locator;
    if (originalLocator == null) {
        // go on with empty locator
        locator = createLocator(null, Locator.createEmptyLocator());
    } else {
        locator = originalLocator;
        locator.processHelpRequest();
    }
    String contextItemText = locator.getSingleDimensionValue(CONTEXT_ITEM_DIMENSION_NAME);
    if (contextItemText != null) {
        List<ITEM> contextObjects = getContextItems(contextItemText);
        if (contextObjects == null)
            throw new BadRequestException("Context variable '" + contextItemText + "' is used in locator, but is not present in the context");
        if (contextObjects.isEmpty())
            throw new BadRequestException("Context variable '" + contextItemText + "' is used in locator, but the list does not contain any elements");
        // so far do not support additional filtering or other dimensions if context item is used
        locator.checkLocatorFullyProcessed();
        return new PagedSearchResult<>(contextObjects, null, null);
    }
    if (!locator.isEmpty()) {
        final ITEM singleItem;
        try {
            singleItem = myDataBinding.findSingleItem(locator);
        } catch (NotFoundException e) {
            if (multipleItemsQuery && !isReportErrorOnNothingFound(locator)) {
                // returning empty collection for multiple items query
                return new PagedSearchResult<>(Collections.emptyList(), null, null);
            }
            throw e;
        }
        if (singleItem != null) {
            final Set<String> singleItemUsedDimensions = locator.getUsedDimensions();
            // ignore start:0 dimension
            final Long startDimension = locator.getSingleDimensionValueAsLong(PagerData.START);
            if (startDimension == null || startDimension != 0) {
                locator.markUnused(PagerData.START);
            }
            ItemFilter<ITEM> filter;
            try {
                filter = getDataBindingWithLogicOpsSupport(locator, myDataBinding).getFilter();
            } catch (NotFoundException e) {
                throw new NotFoundException("Invalid filter for found single item, try omitting extra dimensions: " + e.getMessage(), e);
            } catch (BadRequestException e) {
                throw new BadRequestException("Invalid filter for found single item, try omitting extra dimensions: " + e.getMessage(), e);
            } catch (Exception e) {
                throw new BadRequestException("Invalid filter for found single item, try omitting extra dimensions: " + e.toString(), e);
            }
            // mark as used as it has no influence on single item
            locator.markUsed(DIMENSION_UNIQUE);
            // checking before invoking filter to report any unused dimensions before possible error reporting in filter
            locator.checkLocatorFullyProcessed();
            if (!filter.isIncluded(singleItem)) {
                final String message = "Found single item by " + StringUtil.pluralize("dimension", singleItemUsedDimensions.size()) + " " + singleItemUsedDimensions + ", but that was filtered out using the entire locator '" + locator + "'";
                if (multipleItemsQuery && !isReportErrorOnNothingFound(locator)) {
                    LOG.debug(message);
                    return new PagedSearchResult<>(Collections.emptyList(), null, null);
                } else {
                    throw new NotFoundException(message);
                }
            }
            return new PagedSearchResult<>(Collections.singletonList(singleItem), null, null);
        }
        // nothing found - no dimensions should be marked as used then
        locator.markAllUnused();
    }
    FinderDataBinding.ItemHolder<ITEM> unfilteredItems;
    PagingItemFilter<ITEM> pagingFilter;
    try {
        FinderDataBinding.LocatorDataBinding<ITEM> locatorDataBinding = getDataBindingWithLogicOpsSupport(locator, myDataBinding);
        unfilteredItems = locatorDataBinding.getPrefilteredItems();
        DuplicateChecker<ITEM> duplicateChecker = myDataBinding.createDuplicateChecker();
        if (duplicateChecker != null) {
            // get the dimension only for supporting finders so that unused dimension is reported otherwise
            boolean deduplicate = locator.getSingleDimensionValueAsStrictBoolean(DIMENSION_UNIQUE, locator.isAnyPresent(DIMENSION_ITEM));
            if (deduplicate) {
                unfilteredItems = new DeduplicatingItemHolder<>(unfilteredItems, duplicateChecker);
            }
        }
        pagingFilter = getPagingFilter(locator, locatorDataBinding.getFilter());
    } catch (LocatorProcessException | BadRequestException | IllegalArgumentException e) {
        if (!locator.isHelpRequested()) {
            throw e;
        }
        throw new BadRequestException(e.getMessage() + "\nLocator details: " + locator.getLocatorDescription(locator.helpOptions().getSingleDimensionValueAsStrictBoolean("hidden", false)), e);
    }
    locator.checkLocatorFullyProcessed();
    return getItems(pagingFilter, unfilteredItems, locator, startTime);
}
Also used : NotFoundException(jetbrains.buildServer.server.rest.errors.NotFoundException) LocatorProcessException(jetbrains.buildServer.server.rest.errors.LocatorProcessException) LocatorProcessException(jetbrains.buildServer.server.rest.errors.LocatorProcessException) BadRequestException(jetbrains.buildServer.server.rest.errors.BadRequestException) OperationException(jetbrains.buildServer.server.rest.errors.OperationException) NotFoundException(jetbrains.buildServer.server.rest.errors.NotFoundException) BadRequestException(jetbrains.buildServer.server.rest.errors.BadRequestException) NotNull(org.jetbrains.annotations.NotNull)

Example 10 with LocatorProcessException

use of jetbrains.buildServer.server.rest.errors.LocatorProcessException in project teamcity-rest by JetBrains.

the class FinderImpl method getFilter.

@NotNull
@Override
public ItemFilter<ITEM> getFilter(@NotNull final String locatorText) {
    final Locator locator = createLocator(locatorText, null);
    final ItemFilter<ITEM> result;
    try {
        result = getFilterWithLogicOpsSupport(locator, myDataBinding.getLocatorDataBinding(locator));
    } catch (LocatorProcessException | BadRequestException e) {
        if (!locator.isHelpRequested()) {
            throw e;
        }
        throw new BadRequestException(e.getMessage() + "\nLocator details: " + locator.getLocatorDescription(locator.helpOptions().getSingleDimensionValueAsStrictBoolean("hidden", false)), e);
    }
    locator.checkLocatorFullyProcessed();
    return result;
}
Also used : BadRequestException(jetbrains.buildServer.server.rest.errors.BadRequestException) LocatorProcessException(jetbrains.buildServer.server.rest.errors.LocatorProcessException) NotNull(org.jetbrains.annotations.NotNull)

Aggregations

LocatorProcessException (jetbrains.buildServer.server.rest.errors.LocatorProcessException)16 NotNull (org.jetbrains.annotations.NotNull)13 BadRequestException (jetbrains.buildServer.server.rest.errors.BadRequestException)12 ServiceLocator (jetbrains.buildServer.ServiceLocator)8 NotFoundException (jetbrains.buildServer.server.rest.errors.NotFoundException)7 Nullable (org.jetbrains.annotations.Nullable)7 PagerData (jetbrains.buildServer.server.rest.model.PagerData)4 SUser (jetbrains.buildServer.users.SUser)4 Logger (com.intellij.openapi.diagnostic.Logger)3 java.util (java.util)3 Collectors (java.util.stream.Collectors)3 GenericBuildsFilter (jetbrains.buildServer.server.rest.data.build.GenericBuildsFilter)3 LocatorDimension (jetbrains.buildServer.server.rest.swagger.annotations.LocatorDimension)3 LocatorResource (jetbrains.buildServer.server.rest.swagger.annotations.LocatorResource)3 LocatorDimensionDataType (jetbrains.buildServer.server.rest.swagger.constants.LocatorDimensionDataType)3 LocatorName (jetbrains.buildServer.server.rest.swagger.constants.LocatorName)3 jetbrains.buildServer.serverSide (jetbrains.buildServer.serverSide)3 Permission (jetbrains.buildServer.serverSide.auth.Permission)3 CollectionsUtil (jetbrains.buildServer.util.CollectionsUtil)3 Converter (jetbrains.buildServer.util.Converter)3