/* * 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 org.ngrinder.agent.controller; import com.google.common.base.Predicate; import com.google.common.collect.Collections2; import org.apache.commons.lang.StringUtils; import org.ngrinder.agent.service.AgentManagerService; import org.ngrinder.agent.service.AgentPackageService; import org.ngrinder.common.controller.BaseController; import org.ngrinder.common.controller.RestAPI; import org.ngrinder.model.AgentInfo; import org.ngrinder.model.User; import org.ngrinder.region.model.RegionInfo; import org.ngrinder.region.service.RegionService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import java.io.File; import java.util.List; import java.util.Map; import static org.ngrinder.common.util.CollectionUtils.buildMap; import static org.ngrinder.common.util.CollectionUtils.newArrayList; import static org.ngrinder.common.util.CollectionUtils.newHashMap; /** * Agent management controller. * * @author JunHo Yoon * @since 3.1 */ @Controller @RequestMapping("/agent") @PreAuthorize("hasAnyRole('A', 'S')") public class AgentManagerController extends BaseController { @SuppressWarnings("SpringJavaAutowiringInspection") @Autowired private AgentManagerService agentManagerService; @Autowired private RegionService regionService; @Autowired private AgentPackageService agentPackageService; /** * Get the agents. * * @param region the region to search. If null, it returns all the attached * agents. * @param model model * @return agent/list */ @RequestMapping({"", "/", "/list"}) public String getAll(@RequestParam(value = "region", required = false) final String region, ModelMap model) { List<AgentInfo> agents = agentManagerService.getAllVisible(); model.addAttribute("agents", Collections2.filter(agents, new Predicate<AgentInfo>() { @Override public boolean apply(AgentInfo agentInfo) { final String eachAgentRegion = agentInfo.getRegion(); //noinspection SimplifiableIfStatement if (StringUtils.equals(region, "all") || StringUtils.isEmpty(region)) { return true; } return eachAgentRegion.startsWith(region + "_owned") || region.equals(eachAgentRegion); } })); model.addAttribute("region", region); model.addAttribute("regions", regionService.getAllVisibleRegionNames()); File agentPackage = null; if (isClustered()) { if (StringUtils.isNotBlank(region)) { final RegionInfo regionInfo = regionService.getOne(region); agentPackage = agentPackageService.createAgentPackage(region, regionInfo.getIp(), regionInfo.getControllerPort(), null); } } else { agentPackage = agentPackageService.createAgentPackage("", "", getConfig().getControllerPort(), null); } if (agentPackage != null) { model.addAttribute("downloadLink", "/agent/download/" + agentPackage.getName()); } return "agent/list"; } /** * Get the agent detail info for the given agent id. * * @param id agent id * @param model model * @return agent/agentDetail */ @RequestMapping("/{id}") public String getOne(@PathVariable Long id, ModelMap model) { model.addAttribute("agent", agentManagerService.getOne(id)); return "agent/detail"; } /** * Clean up the agents in the inactive region */ @PreAuthorize("hasAnyRole('A')") @RequestMapping(value = "/api", params = "action=cleanup", method = RequestMethod.POST) public HttpEntity<String> cleanUpAgentsInInactiveRegion() { agentManagerService.cleanup(); return successJsonHttpEntity(); } /** * Get the current performance of the given agent. * * @param id agent id * @param ip agent ip * @param name agent name * @return json message */ @PreAuthorize("hasAnyRole('A')") @RequestMapping("/api/{id}/state") public HttpEntity<String> getState(@PathVariable Long id, @RequestParam String ip, @RequestParam String name) { agentManagerService.requestShareAgentSystemDataModel(id); return toJsonHttpEntity(agentManagerService.getSystemDataModel(ip, name)); } /** * Get the current all agents state. * * @return json message */ @RestAPI @PreAuthorize("hasAnyRole('A')") @RequestMapping(value = {"/api/states/", "/api/states"}, method = RequestMethod.GET) public HttpEntity<String> getStates() { List<AgentInfo> agents = agentManagerService.getAllVisible(); return toJsonHttpEntity(getAgentStatus(agents)); } /** * Get all agents from database. * * @return json message */ @RestAPI @PreAuthorize("hasAnyRole('A')") @RequestMapping(value = {"/api/", "/api"}, method = RequestMethod.GET) public HttpEntity<String> getAll() { return toJsonHttpEntity(agentManagerService.getAllVisible()); } /** * Get the agent for the given agent id. * * @return json message */ @RestAPI @PreAuthorize("hasAnyRole('A')") @RequestMapping(value = "/api/{id}", method = RequestMethod.GET) public HttpEntity<String> getOne(@PathVariable("id") Long id) { return toJsonHttpEntity(agentManagerService.getOne(id)); } /** * Approve an agent. * * @param id agent id * @return json message */ @RestAPI @PreAuthorize("hasAnyRole('A')") @RequestMapping(value = "/api/{id}", params = "action=approve", method = RequestMethod.PUT) public HttpEntity<String> approve(@PathVariable("id") Long id) { agentManagerService.approve(id, true); return successJsonHttpEntity(); } /** * Disapprove an agent. * * @param id agent id * @return json message */ @RestAPI @PreAuthorize("hasAnyRole('A')") @RequestMapping(value = "/api/{id}", params = "action=disapprove", method = RequestMethod.PUT) public HttpEntity<String> disapprove(@PathVariable("id") Long id) { agentManagerService.approve(id, false); return successJsonHttpEntity(); } /** * Stop the given agent. * * @param id agent id * @return json message */ @RestAPI @PreAuthorize("hasAnyRole('A')") @RequestMapping(value = "/api/{id}", params = "action=stop", method = RequestMethod.PUT) public HttpEntity<String> stop(@PathVariable("id") Long id) { agentManagerService.stopAgent(id); return successJsonHttpEntity(); } /** * Stop the given agent. * * @param ids comma separated agent id list * @return json message */ @RestAPI @PreAuthorize("hasAnyRole('A')") @RequestMapping(value = "/api", params = "action=stop", method = RequestMethod.PUT) public HttpEntity<String> stop(@RequestParam("ids") String ids) { String[] split = StringUtils.split(ids, ","); for (String each : split) { stop(Long.parseLong(each)); } return successJsonHttpEntity(); } /** * Update the given agent. * * @param id agent id * @return json message */ @RestAPI @PreAuthorize("hasAnyRole('A')") @RequestMapping(value = "/api/{id}", params = "action=update", method = RequestMethod.PUT) public HttpEntity<String> update(@PathVariable("id") Long id) { agentManagerService.update(id); return successJsonHttpEntity(); } /** * Send update message to agent side * * @param ids comma separated agent id list * @return json message */ @RestAPI @PreAuthorize("hasAnyRole('A')") @RequestMapping(value = "/api", params = "action=update", method = RequestMethod.PUT) public HttpEntity<String> update(@RequestParam("ids") String ids) { String[] split = StringUtils.split(ids, ","); for (String each : split) { update(Long.parseLong(each)); } return successJsonHttpEntity(); } private List<Map<String, Object>> getAgentStatus(List<AgentInfo> agents) { List<Map<String, Object>> statuses = newArrayList(agents.size()); for (AgentInfo each : agents) { Map<String, Object> result = newHashMap(); result.put("id", each.getId()); result.put("port", each.getPort()); result.put("icon", each.getState().getCategory().getIconName()); result.put("state", each.getState()); statuses.add(result); } return statuses; } /** * Get the number of available agents. * * @param user The login user * @param targetRegion The name of target region * @return availableAgentCount Available agent count */ @RestAPI @RequestMapping(value = {"/api/availableAgentCount"}, method = RequestMethod.GET) @PreAuthorize("permitAll") public HttpEntity<String> getAvailableAgentCount(User user, @RequestParam(value = "targetRegion", required = true) String targetRegion) { int availableAgentCount = agentManagerService.getReadyAgentCount(user, targetRegion); HttpEntity<String> returnHttpEntity = toJsonHttpEntity(buildMap("availableAgentCount", availableAgentCount)); return returnHttpEntity; } }