use of jetbrains.buildServer.server.rest.errors.LocatorProcessException in project teamcity-rest by JetBrains.
the class Locator method getBase64UnescapedSingleValue.
@Nullable
private static String getBase64UnescapedSingleValue(@NotNull final String text, final boolean extendedMode) {
if (!TeamCityProperties.getBooleanOrTrue("rest.locator.allowBase64"))
return null;
if (!text.startsWith(BASE64_ESCAPE_FAKE_DIMENSION + DIMENSION_NAME_VALUE_DELIMITER)) {
// optimization until more then one dimension is supported
return null;
}
Map<String, List<String>> parsedDimensions;
try {
parsedDimensions = parse(text, new String[] { BASE64_ESCAPE_FAKE_DIMENSION }, Collections.emptyList(), extendedMode);
} catch (LocatorProcessException e) {
return null;
}
if (parsedDimensions.size() != 1) {
// more then one dimension found
return null;
}
List<String> base64EncodedValues = parsedDimensions.get(BASE64_ESCAPE_FAKE_DIMENSION);
if (base64EncodedValues.isEmpty())
return null;
if (base64EncodedValues.size() != 1)
throw new LocatorProcessException("More then 1 " + BASE64_ESCAPE_FAKE_DIMENSION + " values, only single one is supported");
String base64EncodedValue = base64EncodedValues.get(0);
byte[] decoded;
try {
decoded = Base64.getUrlDecoder().decode(base64EncodedValue.getBytes(StandardCharsets.UTF_8));
} catch (IllegalArgumentException first) {
try {
decoded = Base64.getDecoder().decode(base64EncodedValue.getBytes(StandardCharsets.UTF_8));
} catch (IllegalArgumentException second) {
throw new LocatorProcessException("Invalid Base64url character sequence: '" + base64EncodedValue + "'", first);
}
}
try {
return new String(decoded, StandardCharsets.UTF_8);
} catch (Exception e) {
throw new LocatorProcessException("Error converting decoded '" + base64EncodedValue + "' value bytes to UTF-8 string", e);
}
}
use of jetbrains.buildServer.server.rest.errors.LocatorProcessException in project teamcity-rest by JetBrains.
the class BuildFinder method getBuildPromotion.
/**
* Supported build locators:
* 213 - build with id=213
* 213 when buildType is specified - build in the specified buildType with build number 213
* id:213 - build with id=213
* buildType:bt37 - specify Build Configuration by internal id. If specified, other locator parts should select the build
* number:213 when buildType is specified - build in the specified buildType with build number 213
* status:SUCCESS when buildType is specified - last build with the specified status in the specified buildType
*/
@NotNull
public BuildPromotion getBuildPromotion(@Nullable SBuildType buildType, @Nullable final String buildLocator) {
if (!TeamCityProperties.getBoolean(LEGACY_BUILDS_FILTERING_FORCED)) {
return getBuildPromotionInternal(buildType, buildLocator);
}
if (StringUtil.isEmpty(buildLocator)) {
throw new BadRequestException("Empty single build locator is not supported.");
}
Locator locator = null;
try {
locator = new Locator(buildLocator);
} catch (LocatorProcessException e) {
// unparsable locator - proceed to report a due error later with all the supported locators
}
if (locator == null || useByPromotionFiltering(locator)) {
return getBuildPromotionInternal(buildType, buildLocator);
}
if (locator.isSingleValue()) {
if (buildType == null) {
// no dimensions found and no build type, assume it's build id
@SuppressWarnings("ConstantConditions") SBuild build = // todo: report non-number more user-friendly
myServiceLocator.getSingletonService(BuildsManager.class).findBuildInstanceById(locator.getSingleValueAsLong());
if (build == null) {
throw new NotFoundException("Cannot find build by id '" + locator.getSingleValue() + "'.");
}
return build.getBuildPromotion();
}
// no dimensions found and build type is specified, assume it's build number
@SuppressWarnings("ConstantConditions") SBuild build = myServiceLocator.getSingletonService(BuildsManager.class).findBuildInstanceByBuildNumber(buildType.getBuildTypeId(), buildLocator);
if (build == null) {
throw new NotFoundException("No build can be found by number '" + buildLocator + "' in build configuration " + buildType + ".");
}
return build.getBuildPromotion();
}
String buildTypeLocator = locator.getSingleDimensionValue("buildType");
buildType = myBuildTypeFinder.deriveBuildTypeFromLocator(buildType, buildTypeLocator);
Long id = locator.getSingleDimensionValueAsLong(DIMENSION_ID);
if (id != null) {
SBuild build = myServiceLocator.getSingletonService(BuildsManager.class).findBuildInstanceById(id);
if (build == null) {
throw new NotFoundException("No build can be found by id '" + id + "'.");
}
if (buildType != null && !buildType.getBuildTypeId().equals(build.getBuildTypeId())) {
throw new NotFoundException("No build can be found by id '" + locator.getSingleDimensionValue(DIMENSION_ID) + "' in build type '" + buildType + "'.");
}
if (locator.getDimensionsCount() > 1) {
LOG.info("Build locator '" + buildLocator + "' has '" + DIMENSION_ID + "' dimension and others. Others are ignored.");
}
return build.getBuildPromotion();
}
String number = locator.getSingleDimensionValue("number");
if (number != null && buildType != null) {
SBuild build = myServiceLocator.getSingletonService(BuildsManager.class).findBuildInstanceByBuildNumber(buildType.getBuildTypeId(), number);
if (build == null) {
throw new NotFoundException("No build can be found by number '" + number + "' in build configuration " + buildType + ".");
}
if (locator.getDimensionsCount() > 1) {
LOG.info("Build locator '" + buildLocator + "' has 'number' dimension and others. Others are ignored.");
}
return build.getBuildPromotion();
}
Long promotionId = locator.getSingleDimensionValueAsLong(PROMOTION_ID);
if (promotionId == null) {
// support TeamCity 8.0 dimension
promotionId = locator.getSingleDimensionValueAsLong("promotionId");
}
if (promotionId != null) {
BuildPromotion build = getBuildByPromotionId(promotionId);
if (buildType != null && !buildType.getBuildTypeId().equals(build.getBuildTypeId())) {
throw new NotFoundException("No build can be found by " + PROMOTION_ID + " '" + promotionId + "' in build type '" + buildType + "'.");
}
if (locator.getDimensionsCount() > 1) {
LOG.info("Build locator '" + buildLocator + "' has '" + PROMOTION_ID + "' dimension and others. Others are ignored.");
}
return build;
}
final BuildsFilter buildsFilter = getBuildsFilter(locator, buildType);
buildsFilter.setCount(1);
locator.checkLocatorFullyProcessed();
final List<SBuild> filteredBuilds = getBuilds(buildsFilter);
if (filteredBuilds.size() == 0) {
throw new NotFoundException("No build found by filter: " + buildsFilter.toString() + ".");
}
if (filteredBuilds.size() == 1) {
return filteredBuilds.get(0).getBuildPromotion();
}
throw new BadRequestException("Build locator '" + buildLocator + "' is not supported (" + filteredBuilds.size() + " builds found)");
}
use of jetbrains.buildServer.server.rest.errors.LocatorProcessException in project teamcity-rest by JetBrains.
the class BuildFinder method getBuilds.
@NotNull
public PagedSearchResult<BuildPromotion> getBuilds(@Nullable final SBuildType buildType, @Nullable final String locatorText) {
if (!TeamCityProperties.getBoolean(LEGACY_BUILDS_FILTERING_FORCED)) {
return myBuildPromotionFinder.getBuildPromotions(buildType, locatorText);
}
Locator locator = null;
try {
locator = locatorText != null ? new Locator(locatorText) : Locator.createEmptyLocator();
} catch (LocatorProcessException e) {
// error creating locator - some special dimensions used? process by default
return myBuildPromotionFinder.getBuildPromotions(buildType, locatorText);
}
if (useByPromotionFiltering(locator)) {
return myBuildPromotionFinder.getBuildPromotions(buildType, locatorText);
}
BuildsFilter buildsFilter = getBuildsFilter(locator, buildType);
locator.checkLocatorFullyProcessed();
final Integer c = buildsFilter.getCount();
if (c != null) {
buildsFilter.setCount(c != -1 ? c : null);
} else {
buildsFilter.setCount(jetbrains.buildServer.server.rest.request.Constants.getDefaultPageItemsCount());
}
return new PagedSearchResult<BuildPromotion>(toBuildPromotions(getBuilds(buildsFilter)), buildsFilter.getStart(), buildsFilter.getCount());
}
use of jetbrains.buildServer.server.rest.errors.LocatorProcessException in project teamcity-rest by JetBrains.
the class BuildFinder method getBuildsFilter.
@NotNull
private BuildsFilter getBuildsFilter(@NotNull final Locator buildLocator, @Nullable final SBuildType buildType) {
// todo: report unknown locator dimensions
final SBuildType actualBuildType = myBuildTypeFinder.deriveBuildTypeFromLocator(buildType, buildLocator.getSingleDimensionValue("buildType"));
final String projectFromLocator = buildLocator.getSingleDimensionValue("project");
final SProject project = StringUtil.isEmpty(projectFromLocator) ? null : myProjectFinder.getItem(projectFromLocator);
final String userLocator = buildLocator.getSingleDimensionValue("user");
final String tagsString = buildLocator.getSingleDimensionValue("tags");
final String singleTagString = buildLocator.getSingleDimensionValue("tag");
if (tagsString != null && singleTagString != null) {
throw new BadRequestException("Both 'tags' and 'tag' dimensions specified. Only one can be present.");
}
List<String> tagsList = null;
if (singleTagString != null) {
tagsList = Collections.singletonList(singleTagString);
} else if (tagsString != null) {
tagsList = Arrays.asList(tagsString.split(","));
}
final Long count = buildLocator.getSingleDimensionValueAsLong(PagerData.COUNT);
BranchMatcher branchMatcher;
final String branchLocatorValue = buildLocator.getSingleDimensionValue("branch");
try {
branchMatcher = new BranchMatcher(branchLocatorValue);
} catch (LocatorProcessException e) {
throw new LocatorProcessException("Invalid sub-locator 'branch': " + e.getMessage());
}
Collection<SBuildAgent> agents = null;
final String agentLocator = buildLocator.getSingleDimensionValue("agent");
if (agentLocator != null) {
agents = myAgentFinder.getItems(agentLocator).myEntries;
}
return new GenericBuildsFilter(actualBuildType, project, buildLocator.getSingleDimensionValue("status"), buildLocator.getSingleDimensionValue("number"), userLocator == null ? null : myUserFinder.getItem(userLocator), buildLocator.getSingleDimensionValueAsBoolean("personal", false), buildLocator.getSingleDimensionValueAsBoolean("canceled", false), buildLocator.getSingleDimensionValueAsBoolean("running", false), buildLocator.getSingleDimensionValueAsBoolean("pinned"), tagsList, branchMatcher, // deprecated, use "agent" instead
buildLocator.getSingleDimensionValue("agentName"), agents, ParameterCondition.create(buildLocator.getSingleDimensionValue("property")), getRangeLimit(actualBuildType, buildLocator.getSingleDimensionValue("sinceBuild"), DataProvider.parseDate(buildLocator.getSingleDimensionValue("sinceDate"))), getRangeLimit(actualBuildType, buildLocator.getSingleDimensionValue("untilBuild"), DataProvider.parseDate(buildLocator.getSingleDimensionValue("untilDate"))), buildLocator.getSingleDimensionValueAsLong(PagerData.START), count == null ? null : count.intValue(), buildLocator.getSingleDimensionValueAsLong("lookupLimit"), myServiceLocator);
}
use of jetbrains.buildServer.server.rest.errors.LocatorProcessException in project teamcity-rest by JetBrains.
the class Property method getAllowedValues.
@NotNull
private static List<String> getAllowedValues() {
// allow empty values by default
String valuesLocatorText = TeamCityProperties.getPropertyOrNull("rest.listSecureProperties.valuesLocator", "password:()");
try {
if (!StringUtil.isEmpty(valuesLocatorText)) {
Locator valuesLocator = new Locator(valuesLocatorText, "password", "enabled");
Boolean enabled = valuesLocator.getSingleDimensionValueAsBoolean("enabled", true);
if (enabled != null && !enabled) {
return Collections.emptyList();
}
List<String> values = valuesLocator.getDimensionValue("password");
valuesLocator.checkLocatorFullyProcessed();
return values;
}
} catch (LocatorProcessException e) {
throw new InvalidStateException("Wrong '" + "rest.listSecureProperties.valuesLocator" + "' server internal property value, remove it or use format 'password:(),password:(sample)', error: " + e.getMessage());
}
return Collections.emptyList();
}
Aggregations