package com.ctrip.framework.apollo.portal.controller; import com.ctrip.framework.apollo.common.dto.ItemDTO; import com.ctrip.framework.apollo.common.exception.BadRequestException; import com.ctrip.framework.apollo.core.enums.Env; import com.ctrip.framework.apollo.core.utils.StringUtils; import com.ctrip.framework.apollo.portal.entity.model.NamespaceSyncModel; import com.ctrip.framework.apollo.portal.entity.model.NamespaceTextModel; import com.ctrip.framework.apollo.portal.entity.vo.ItemDiffs; import com.ctrip.framework.apollo.portal.service.ItemService; import com.ctrip.framework.apollo.portal.spi.UserInfoHolder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.Collections; import java.util.List; import static com.ctrip.framework.apollo.common.utils.RequestPrecondition.checkModel; @RestController public class ItemController { @Autowired private ItemService configService; @Autowired private UserInfoHolder userInfoHolder; @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName)") @RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items", method = RequestMethod.PUT, consumes = { "application/json"}) public void modifyItemsByText(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @PathVariable String namespaceName, @RequestBody NamespaceTextModel model) { checkModel(model != null); model.setAppId(appId); model.setClusterName(clusterName); model.setEnv(env); model.setNamespaceName(namespaceName); configService.updateConfigItemByText(model); } @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName)") @RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/item", method = RequestMethod.POST) public ItemDTO createItem(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @PathVariable String namespaceName, @RequestBody ItemDTO item) { checkModel(isValidItem(item)); //protect item.setLineNum(0); item.setId(0); String userId = userInfoHolder.getUser().getUserId(); item.setDataChangeCreatedBy(userId); item.setDataChangeLastModifiedBy(userId); item.setDataChangeCreatedTime(null); item.setDataChangeLastModifiedTime(null); return configService.createItem(appId, Env.valueOf(env), clusterName, namespaceName, item); } @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName)") @RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/item", method = RequestMethod.PUT) public void updateItem(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @PathVariable String namespaceName, @RequestBody ItemDTO item) { checkModel(isValidItem(item)); String username = userInfoHolder.getUser().getUserId(); item.setDataChangeLastModifiedBy(username); configService.updateItem(appId, Env.valueOf(env), clusterName, namespaceName, item); } @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName)") @RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items/{itemId}", method = RequestMethod.DELETE) public void deleteItem(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @PathVariable String namespaceName, @PathVariable long itemId) { if (itemId <= 0) { throw new BadRequestException("item id invalid"); } configService.deleteItem(Env.valueOf(env), itemId, userInfoHolder.getUser().getUserId()); } @RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/items", method = RequestMethod.GET) public List<ItemDTO> findItems(@PathVariable String appId, @PathVariable String env, @PathVariable String clusterName, @PathVariable String namespaceName, @RequestParam(defaultValue = "lineNum") String orderBy) { List<ItemDTO> items = configService.findItems(appId, Env.valueOf(env), clusterName, namespaceName); if ("lastModifiedTime".equals(orderBy)) { Collections.sort(items, (o1, o2) -> { if (o1.getDataChangeLastModifiedTime().after(o2.getDataChangeLastModifiedTime())) { return -1; } if (o1.getDataChangeLastModifiedTime().before(o2.getDataChangeLastModifiedTime())) { return 1; } return 0; }); } return items; } @RequestMapping(value = "/apps/{appId}/envs/{env}/clusters/{clusterName}/namespaces/{namespaceName}/branches/{branchName}/items", method = RequestMethod.GET) public List<ItemDTO> findBranchItems(@PathVariable("appId") String appId, @PathVariable String env, @PathVariable("clusterName") String clusterName, @PathVariable("namespaceName") String namespaceName, @PathVariable("branchName") String branchName) { return findItems(appId, env, branchName, namespaceName, "lastModifiedTime"); } @RequestMapping(value = "/namespaces/{namespaceName}/diff", method = RequestMethod.POST, consumes = { "application/json"}) public List<ItemDiffs> diff(@RequestBody NamespaceSyncModel model) { checkModel(model != null && !model.isInvalid()); return configService.compare(model.getSyncToNamespaces(), model.getSyncItems()); } @PreAuthorize(value = "@permissionValidator.hasModifyNamespacePermission(#appId, #namespaceName)") @RequestMapping(value = "/apps/{appId}/namespaces/{namespaceName}/items", method = RequestMethod.PUT, consumes = { "application/json"}) public ResponseEntity<Void> update(@PathVariable String appId, @PathVariable String namespaceName, @RequestBody NamespaceSyncModel model) { checkModel(model != null && !model.isInvalid()); configService.syncItems(model.getSyncToNamespaces(), model.getSyncItems()); return ResponseEntity.status(HttpStatus.OK).build(); } private boolean isValidItem(ItemDTO item) { return item != null && !StringUtils.isContainEmpty(item.getKey()); } }