/* * Copyright 2000-2018 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.buildServer.server.rest.data; import com.google.common.collect.ComparisonChain; import java.util.*; import jetbrains.buildServer.ServiceLocator; import jetbrains.buildServer.server.rest.data.TypedFinderBuilder.Dimension; import jetbrains.buildServer.server.rest.errors.NotFoundException; import jetbrains.buildServer.serverSide.BuildAgentEx; import jetbrains.buildServer.serverSide.ProjectManager; import jetbrains.buildServer.serverSide.SBuildAgent; import jetbrains.buildServer.serverSide.SProject; import jetbrains.buildServer.serverSide.agentPools.AgentPool; import jetbrains.buildServer.serverSide.agentPools.AgentPoolManager; import jetbrains.buildServer.serverSide.agentTypes.AgentTypeStorage; import jetbrains.buildServer.serverSide.auth.Permission; import jetbrains.buildServer.util.CollectionsUtil; import jetbrains.buildServer.util.filters.Filter; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * @author Yegor.Yarko * Date: 07.11.13 */ public class AgentPoolFinder extends DelegatingFinder { @NotNull private final AgentPoolManager myAgentPoolManager; @NotNull private final ServiceLocator myServiceLocator; @NotNull private final AgentFinder myAgentFinder; public AgentPoolFinder(@NotNull final AgentPoolManager agentPoolManager, @NotNull final AgentFinder agentFinder, @NotNull final ServiceLocator serviceLocator) { myAgentPoolManager = agentPoolManager; myServiceLocator = serviceLocator; myAgentFinder = agentFinder; setDelegate(new AgentPoolFinderBuilder().build()); } @NotNull public static String getLocator(@NotNull final AgentPool agentPool) { return Locator.getStringLocator(ID.name, String.valueOf(agentPool.getAgentPoolId())); } @NotNull public static String getLocator(@NotNull final SProject project) { return Locator.getStringLocator(PROJECT.name, ProjectFinder.getLocator(project)); } public static final Dimension ID = new Dimension<>("id"); public static final Dimension NAME = new Dimension<>("name"); private static final Dimension> AGENT = new Dimension<>("agent"); private static final Dimension> PROJECT = new Dimension<>("project"); private class AgentPoolFinderBuilder extends TypedFinderBuilder { AgentPoolFinderBuilder() { name("AgentPoolFinder"); dimensionLong(Dimension.single()).description("agent pool id").toItems(dimension -> Collections.singletonList(getAgentPoolById(dimension))); dimensionLong(ID).description("agent pool id").toItems(dimension -> Collections.singletonList(getAgentPoolById(dimension))). valueForDefaultFilter(agentPool -> (long)agentPool.getAgentPoolId()); dimensionString(NAME).description("agent pool name").valueForDefaultFilter(agentPool -> agentPool.getName()); dimensionProjects(PROJECT, myServiceLocator).description("projects associated with the agent pool"). valueForDefaultFilter(agentPool -> new HashSet(getPoolProjects(agentPool))); dimensionAgents(AGENT, myServiceLocator).description("agents associated with the agent pool"). valueForDefaultFilter(agentPool -> new HashSet(getPoolAgentsInternal(agentPool))); filter(DimensionCondition.ALWAYS, new ItemFilterFromDimensions() { @Nullable @Override public ItemFilter get(@NotNull final DimensionObjects dimensions) { final PermissionChecker permissionChecker = myServiceLocator.getSingletonService(PermissionChecker.class); final boolean hasPermission = permissionChecker.hasGlobalPermission(Permission.VIEW_AGENT_DETAILS) || permissionChecker.hasPermissionInAnyProject(Permission.VIEW_AGENT_DETAILS_FOR_PROJECT); if (hasPermission) return null; return new ItemFilter() { @Override public boolean shouldStop(@NotNull final AgentPool item) { return false; } @Override public boolean isIncluded(@NotNull final AgentPool item) { return false; } }; } }); multipleConvertToItems(DimensionCondition.ALWAYS, dimensions -> myAgentPoolManager.getAllAgentPools()); locatorProvider(agentPool -> getLocator(agentPool)); containerSetProvider(() -> new TreeSet<>(new Comparator() { @Override public int compare(final AgentPool o1, final AgentPool o2) { return ComparisonChain.start() .compare(o1.getAgentPoolId(), o2.getAgentPoolId()) .compare(o1.getName(), o2.getName()) .result(); } })); } } // // Helper methods // //todo: TeamCity API: what is the due way to do this? http://youtrack.jetbrains.com/issue/TW-33307 /** * Gets all agents (registered and unregistered) of the specified pool excluding cloud agent images. */ @NotNull private List getPoolAgentsInternal(@NotNull final AgentPool agentPool) { final Collection agentTypeIds = myServiceLocator.getSingletonService(AgentTypeStorage.class).getAgentTypeIdsByPool(agentPool.getAgentPoolId()); //todo: support cloud agents here final List allAgents = myAgentFinder.getItems(Locator.getStringLocator(AgentFinder.DEFAULT_FILTERING, "false")).myEntries; return CollectionsUtil.filterCollection(allAgents, new Filter() { public boolean accept(@NotNull final SBuildAgent agent) { return agentTypeIds.contains(agent.getAgentTypeId()); } }); } //todo: TeamCity API: what is the due way to do this? http://youtrack.jetbrains.com/issue/TW-33307 /** * Gets all projects associated with the specified pool. */ @NotNull public List getPoolProjects(@NotNull final AgentPool agentPool) { final Set projectIds = myAgentPoolManager.getPoolProjects(agentPool.getAgentPoolId()); final ProjectManager projectManager = myServiceLocator.getSingletonService(ProjectManager.class); final List result = new ArrayList(projectIds.size()); for (String projectId : projectIds) { final SProject project = projectManager.findProjectById(projectId); if (project != null) { result.add(project); } else { //todo: include not present projects into the list } } return result; } @NotNull public AgentPool getAgentPoolById(final long id) { final AgentPool agentPool = myAgentPoolManager.findAgentPoolById((int)id); if (agentPool == null) { throw new NotFoundException("No agent pool is found by id '" + id + "'."); } return agentPool; } @NotNull public AgentPool getAgentPool(final SBuildAgent agent) { BuildAgentEx agentEx = (BuildAgentEx)agent; return agentEx.getAgentType().getAgentPool(); } public Collection getPoolsForProject(@NotNull final SProject project) { return getItems(getLocator(project)).myEntries; } }