Repository: kylin Updated Branches: refs/heads/master 1d6a36bf6 -> e62d87826
KYLIN-2317 add HybridController and HybridService Project: http://git-wip-us.apache.org/repos/asf/kylin/repo Commit: http://git-wip-us.apache.org/repos/asf/kylin/commit/e62d8782 Tree: http://git-wip-us.apache.org/repos/asf/kylin/tree/e62d8782 Diff: http://git-wip-us.apache.org/repos/asf/kylin/diff/e62d8782 Branch: refs/heads/master Commit: e62d87826f0b4fc5ab3b4fdbed85d2c2ffe188be Parents: 1d6a36b Author: Billy Liu <billy...@apache.org> Authored: Tue Jan 3 18:28:36 2017 +0800 Committer: Billy Liu <billy...@apache.org> Committed: Tue Jan 3 18:28:55 2017 +0800 ---------------------------------------------------------------------- .../kylin/rest/controller/BasicController.java | 8 + .../kylin/rest/controller/HybridController.java | 84 ++++++++++ .../kylin/rest/request/HybridRequest.java | 62 ++++++++ .../kylin/rest/service/HybridService.java | 155 +++++++++++++++++++ 4 files changed, 309 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/kylin/blob/e62d8782/server-base/src/main/java/org/apache/kylin/rest/controller/BasicController.java ---------------------------------------------------------------------- diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller/BasicController.java b/server-base/src/main/java/org/apache/kylin/rest/controller/BasicController.java index 0e4a70c..f61492d 100644 --- a/server-base/src/main/java/org/apache/kylin/rest/controller/BasicController.java +++ b/server-base/src/main/java/org/apache/kylin/rest/controller/BasicController.java @@ -20,6 +20,7 @@ package org.apache.kylin.rest.controller; import javax.servlet.http.HttpServletRequest; +import org.apache.commons.lang3.StringUtils; import org.apache.kylin.rest.exception.BadRequestException; import org.apache.kylin.rest.exception.ForbiddenException; import org.apache.kylin.rest.exception.NotFoundException; @@ -66,4 +67,11 @@ public class BasicController { logger.error("", ex); return new ErrorResponse(req.getRequestURL().toString(), ex); } + + protected void checkRequiredArg(String fieldName, Object fieldValue) { + if (fieldValue == null || StringUtils.isEmpty(String.valueOf(fieldValue))) { + throw new BadRequestException(fieldName + " is required"); + } + } + } http://git-wip-us.apache.org/repos/asf/kylin/blob/e62d8782/server-base/src/main/java/org/apache/kylin/rest/controller/HybridController.java ---------------------------------------------------------------------- diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller/HybridController.java b/server-base/src/main/java/org/apache/kylin/rest/controller/HybridController.java new file mode 100644 index 0000000..18156b6 --- /dev/null +++ b/server-base/src/main/java/org/apache/kylin/rest/controller/HybridController.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.kylin.rest.controller; + +import java.util.Collection; + +import org.apache.kylin.rest.request.HybridRequest; +import org.apache.kylin.rest.service.HybridService; +import org.apache.kylin.storage.hybrid.HybridInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +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.ResponseBody; + +@Controller +@RequestMapping(value = "/hybrids") +public class HybridController extends BasicController { + + @Autowired + private HybridService hybridService; + + @RequestMapping(value = "", method = RequestMethod.POST) + @ResponseBody + public HybridInstance create(@RequestBody HybridRequest request) { + checkRequiredArg("hybrid", request.getHybrid()); + checkRequiredArg("project", request.getProject()); + checkRequiredArg("model", request.getModel()); + checkRequiredArg("cubes", request.getCubes()); + HybridInstance instance = hybridService.createHybridCube(request.getHybrid(), request.getProject(), request.getModel(), request.getCubes()); + return instance; + } + + @RequestMapping(value = "", method = RequestMethod.PUT) + @ResponseBody + public HybridInstance update(@RequestBody HybridRequest request) { + checkRequiredArg("hybrid", request.getHybrid()); + checkRequiredArg("project", request.getProject()); + checkRequiredArg("model", request.getModel()); + checkRequiredArg("cubes", request.getCubes()); + HybridInstance instance = hybridService.updateHybridCube(request.getHybrid(), request.getProject(), request.getModel(), request.getCubes()); + return instance; + } + + @RequestMapping(value = "", method = RequestMethod.DELETE) + @ResponseBody + public void delete(@RequestBody HybridRequest request) { + checkRequiredArg("hybrid", request.getHybrid()); + checkRequiredArg("project", request.getProject()); + checkRequiredArg("model", request.getModel()); + hybridService.deleteHybridCube(request.getHybrid(), request.getProject(), request.getModel()); + } + + @RequestMapping(value = "", method = RequestMethod.GET) + @ResponseBody + public Collection<HybridInstance> list(@RequestParam(required = false) String project, @RequestParam(required = false) String model) { + return hybridService.listHybrids(project, model); + } + + @RequestMapping(value = "{hybrid}", method = RequestMethod.GET) + @ResponseBody + public HybridInstance get(@PathVariable String hybrid) { + return hybridService.getHybridInstance(hybrid); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/kylin/blob/e62d8782/server-base/src/main/java/org/apache/kylin/rest/request/HybridRequest.java ---------------------------------------------------------------------- diff --git a/server-base/src/main/java/org/apache/kylin/rest/request/HybridRequest.java b/server-base/src/main/java/org/apache/kylin/rest/request/HybridRequest.java new file mode 100644 index 0000000..68fbaa9 --- /dev/null +++ b/server-base/src/main/java/org/apache/kylin/rest/request/HybridRequest.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.kylin.rest.request; + +public class HybridRequest { + + private String hybrid; + + private String project; + + private String model; + + private String[] cubes; + + public String getProject() { + return this.project; + } + + public void setProject(String project) { + this.project = project; + } + + public String getHybrid() { + return this.hybrid; + } + + public void setHybrid(String hybrid) { + this.hybrid = hybrid; + } + + public String getModel() { + return this.model; + } + + public void setModel(String model) { + this.model = model; + } + + public String[] getCubes() { + return this.cubes; + } + + public void setCubes(String[] cubes) { + this.cubes = cubes; + } +} http://git-wip-us.apache.org/repos/asf/kylin/blob/e62d8782/server-base/src/main/java/org/apache/kylin/rest/service/HybridService.java ---------------------------------------------------------------------- diff --git a/server-base/src/main/java/org/apache/kylin/rest/service/HybridService.java b/server-base/src/main/java/org/apache/kylin/rest/service/HybridService.java new file mode 100644 index 0000000..dd1636a --- /dev/null +++ b/server-base/src/main/java/org/apache/kylin/rest/service/HybridService.java @@ -0,0 +1,155 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.kylin.rest.service; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.apache.kylin.cube.model.CubeDesc; +import org.apache.kylin.metadata.model.DataModelDesc; +import org.apache.kylin.metadata.project.ProjectInstance; +import org.apache.kylin.metadata.project.RealizationEntry; +import org.apache.kylin.metadata.realization.RealizationType; +import org.apache.kylin.rest.constant.Constant; +import org.apache.kylin.storage.hybrid.HybridInstance; +import org.apache.kylin.tool.HybridCubeCLI; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.security.access.prepost.PostFilter; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Component; + +@Component("hybridService") +public class HybridService extends BasicService { + + private static final Logger logger = LoggerFactory.getLogger(HybridService.class); + + @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN + " or " + Constant.ACCESS_HAS_ROLE_MODELER) + public HybridInstance createHybridCube(String hybridName, String projectName, String modelName, String[] cubeNames) { + List<String> args = new ArrayList<String>(); + args.add("-name"); + args.add(hybridName); + args.add("-project"); + args.add(projectName); + args.add("-model"); + args.add(modelName); + args.add("-cubes"); + args.add(StringUtils.join(cubeNames, ",")); + args.add("-action"); + args.add("create"); + try { + HybridCubeCLI.main(args.toArray(new String[args.size()])); + } catch (Exception e) { + logger.warn("Create Hybrid Failed", e); + throw e; + } + return getHybridInstance(hybridName); + } + + @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN + " or hasPermission(#cube, 'ADMINISTRATION') or hasPermission(#cube, 'MANAGEMENT')") + public HybridInstance updateHybridCube(String hybridName, String projectName, String modelName, String[] cubeNames) { + List<String> args = new ArrayList<String>(); + args.add("-name"); + args.add(hybridName); + args.add("-project"); + args.add(projectName); + args.add("-model"); + args.add(modelName); + args.add("-cubes"); + args.add(StringUtils.join(cubeNames, ",")); + args.add("-action"); + args.add("update"); + try { + HybridCubeCLI.main(args.toArray(new String[args.size()])); + } catch (Exception e) { + logger.warn("Update Hybrid Failed", e); + throw e; + } + return getHybridInstance(hybridName); + } + + @PreAuthorize(Constant.ACCESS_HAS_ROLE_ADMIN + " or hasPermission(#cube, 'ADMINISTRATION') or hasPermission(#cube, 'MANAGEMENT')") + public void deleteHybridCube(String hybridName, String projectName, String modelName) { + List<String> args = new ArrayList<String>(); + args.add("-name"); + args.add(hybridName); + args.add("-project"); + args.add(projectName); + args.add("-model"); + args.add(modelName); + args.add("-action"); + args.add("delete"); + try { + HybridCubeCLI.main(args.toArray(new String[args.size()])); + } catch (Exception e) { + logger.warn("Delete Hybrid Failed", e); + throw e; + } + } + + public HybridInstance getHybridInstance(String hybridName) { + HybridInstance hybridInstance = getHybridManager().getHybridInstance(hybridName); + return hybridInstance; + } + + @PostFilter(Constant.ACCESS_POST_FILTER_READ) + public List<HybridInstance> listHybrids(final String projectName, final String modelName) { + ProjectInstance project = (null != projectName) ? getProjectManager().getProject(projectName) : null; + List<HybridInstance> hybridsInProject = new ArrayList<HybridInstance>(); + + if (StringUtils.isEmpty(projectName)) { + hybridsInProject = new ArrayList(getHybridManager().listHybridInstances()); + } else if (project == null) { + return new ArrayList<>(); + } else { + List<RealizationEntry> realizationEntries = project.getRealizationEntries(RealizationType.HYBRID); + if (realizationEntries != null) { + for (RealizationEntry entry : realizationEntries) { + HybridInstance instance = getHybridManager().getHybridInstance(entry.getRealization()); + hybridsInProject.add(instance); + } + } + } + + DataModelDesc model = (null != modelName) ? getMetadataManager().getDataModelDesc(modelName) : null; + if (StringUtils.isEmpty(modelName)) { + return hybridsInProject; + } else if (model == null) { + return new ArrayList<>(); + } else { + List<HybridInstance> hybridsInModel = new ArrayList<HybridInstance>(); + for (HybridInstance hybridInstance : hybridsInProject) { + boolean hybridInModel = false; + for (RealizationEntry entry : hybridInstance.getRealizationEntries()) { + CubeDesc cubeDesc = getCubeDescManager().getCubeDesc(entry.getRealization()); + if (cubeDesc != null && model.getName().equalsIgnoreCase(cubeDesc.getModel().getName())) { + hybridInModel = true; + break; + } + } + if (hybridInModel) { + hybridsInModel.add(hybridInstance); + } + } + return hybridsInModel; + } + } + +}