You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by sh...@apache.org on 2018/08/02 05:51:40 UTC

[kylin] branch master updated: KYLIN-3355 Improve the HTTP return code

This is an automated email from the ASF dual-hosted git repository.

shaofengshi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kylin.git


The following commit(s) were added to refs/heads/master by this push:
     new 9fec0c4  KYLIN-3355 Improve the HTTP return code
9fec0c4 is described below

commit 9fec0c403a4f1e470fc66d7af55060632073553d
Author: shaofengshi <sh...@apache.org>
AuthorDate: Thu Jul 26 11:30:39 2018 +0800

    KYLIN-3355 Improve the HTTP return code
---
 .../java/org/apache/kylin/cube/CubeManager.java    |  20 ----
 .../kylin/rest/controller/BasicController.java     |   8 ++
 .../kylin/rest/controller/CubeController.java      | 123 ++++++++-------------
 .../kylin/rest/controller/ModelController.java     |   2 +-
 .../kylin/rest/controller/ProjectController.java   |   3 +-
 .../rest/exception/TooManyRequestException.java    |  58 ++++++++++
 .../kylin/rest/controller/CubeControllerTest.java  |   3 +-
 7 files changed, 115 insertions(+), 102 deletions(-)

diff --git a/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java b/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java
index a4ed9c3..d6fca79 100755
--- a/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java
+++ b/core-cube/src/main/java/org/apache/kylin/cube/CubeManager.java
@@ -638,7 +638,6 @@ public class CubeManager implements IRealizationProvider {
             CubeInstance cubeCopy = cube.latestCopyForWrite(); // get a latest copy
 
             checkInputRanges(tsRange, segRange);
-            checkBuildingSegment(cubeCopy);
 
             // fix start/end a bit
             if (cubeCopy.getModel().getPartitionDesc().isPartitioned()) {
@@ -673,7 +672,6 @@ public class CubeManager implements IRealizationProvider {
             CubeInstance cubeCopy = cube.latestCopyForWrite(); // get a latest copy
 
             checkInputRanges(tsRange, segRange);
-            checkBuildingSegment(cubeCopy);
 
             if (cubeCopy.getModel().getPartitionDesc().isPartitioned() == false) {
                 // full build
@@ -716,8 +714,6 @@ public class CubeManager implements IRealizationProvider {
         public CubeSegment[] optimizeSegments(CubeInstance cube, Set<Long> cuboidsRecommend) throws IOException {
             CubeInstance cubeCopy = cube.latestCopyForWrite(); // get a latest copy
 
-            checkReadyForOptimize(cubeCopy);
-
             List<CubeSegment> readySegments = cubeCopy.getSegments(SegmentStatusEnum.READY);
             CubeSegment[] optimizeSegments = new CubeSegment[readySegments.size()];
             int i = 0;
@@ -744,7 +740,6 @@ public class CubeManager implements IRealizationProvider {
                 throw new IllegalArgumentException("Cube " + cubeCopy + " has no segments");
 
             checkInputRanges(tsRange, segRange);
-            checkBuildingSegment(cubeCopy);
             checkCubeIsPartitioned(cubeCopy);
 
             if (cubeCopy.getSegments().getFirstSegment().isOffsetCube()) {
@@ -829,21 +824,6 @@ public class CubeManager implements IRealizationProvider {
             }
         }
 
-        private void checkBuildingSegment(CubeInstance cube) {
-            checkBuildingSegment(cube, cube.getConfig().getMaxBuildingSegments());
-        }
-
-        private void checkReadyForOptimize(CubeInstance cube) {
-            checkBuildingSegment(cube, 1);
-        }
-
-        private void checkBuildingSegment(CubeInstance cube, int maxBuildingSeg) {
-            if (cube.getBuildingSegments().size() >= maxBuildingSeg) {
-                throw new IllegalStateException(
-                        "There is already " + cube.getBuildingSegments().size() + " building segment; ");
-            }
-        }
-
         private void checkCubeIsPartitioned(CubeInstance cube) {
             if (cube.getDescriptor().getModel().getPartitionDesc().isPartitioned() == false) {
                 throw new IllegalStateException(
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 539a64c..061dd79 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
@@ -34,6 +34,7 @@ import org.apache.kylin.rest.exception.BadRequestException;
 import org.apache.kylin.rest.exception.ForbiddenException;
 import org.apache.kylin.rest.exception.InternalErrorException;
 import org.apache.kylin.rest.exception.NotFoundException;
+import org.apache.kylin.rest.exception.TooManyRequestException;
 import org.apache.kylin.rest.exception.UnauthorizedException;
 import org.apache.kylin.rest.msg.Message;
 import org.apache.kylin.rest.msg.MsgPicker;
@@ -101,6 +102,13 @@ public class BasicController {
         return new ErrorResponse(req.getRequestURL().toString(), ex);
     }
 
+    @ResponseStatus(HttpStatus.TOO_MANY_REQUESTS)
+    @ExceptionHandler(TooManyRequestException.class)
+    @ResponseBody
+    ErrorResponse handleTooManyRequest(HttpServletRequest req, Exception 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");
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller/CubeController.java b/server-base/src/main/java/org/apache/kylin/rest/controller/CubeController.java
index c6219a4..f610d5c 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller/CubeController.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller/CubeController.java
@@ -58,13 +58,16 @@ import org.apache.kylin.rest.exception.BadRequestException;
 import org.apache.kylin.rest.exception.ForbiddenException;
 import org.apache.kylin.rest.exception.InternalErrorException;
 import org.apache.kylin.rest.exception.NotFoundException;
+import org.apache.kylin.rest.exception.TooManyRequestException;
+import org.apache.kylin.rest.msg.Message;
+import org.apache.kylin.rest.msg.MsgPicker;
 import org.apache.kylin.rest.request.CubeRequest;
 import org.apache.kylin.rest.request.JobBuildRequest;
 import org.apache.kylin.rest.request.JobBuildRequest2;
 import org.apache.kylin.rest.request.JobOptimizeRequest;
+import org.apache.kylin.rest.request.LookupSnapshotBuildRequest;
 import org.apache.kylin.rest.request.SQLRequest;
 import org.apache.kylin.rest.response.CubeInstanceResponse;
-import org.apache.kylin.rest.request.LookupSnapshotBuildRequest;
 import org.apache.kylin.rest.response.CuboidTreeResponse;
 import org.apache.kylin.rest.response.EnvelopeResponse;
 import org.apache.kylin.rest.response.GeneralResponse;
@@ -175,10 +178,8 @@ public class CubeController extends BasicController {
     @RequestMapping(value = "/{cubeName}", method = { RequestMethod.GET }, produces = { "application/json" })
     @ResponseBody
     public CubeInstance getCube(@PathVariable String cubeName) {
+        checkCubeExists(cubeName);
         CubeInstance cube = cubeService.getCubeManager().getCube(cubeName);
-        if (cube == null) {
-            throw new InternalErrorException("Cannot find cube " + cubeName);
-        }
         return cube;
     }
 
@@ -192,10 +193,8 @@ public class CubeController extends BasicController {
     @RequestMapping(value = "/{cubeName}/sql", method = { RequestMethod.GET }, produces = { "application/json" })
     @ResponseBody
     public GeneralResponse getSql(@PathVariable String cubeName) {
+        checkCubeExists(cubeName);
         CubeInstance cube = cubeService.getCubeManager().getCube(cubeName);
-        if (cube == null) {
-            throw new InternalErrorException("Cannot find cube " + cubeName);
-        }
         IJoinedFlatTableDesc flatTableDesc = new CubeJoinedFlatTableDesc(cube.getDescriptor(), true);
         String sql = JoinedFlatTable.generateSelectDataStatement(flatTableDesc);
 
@@ -217,14 +216,13 @@ public class CubeController extends BasicController {
             "application/json" })
     @ResponseBody
     public GeneralResponse getSql(@PathVariable String cubeName, @PathVariable String segmentName) {
+
+        checkCubeExists(cubeName);
         CubeInstance cube = cubeService.getCubeManager().getCube(cubeName);
-        if (cube == null) {
-            throw new InternalErrorException("Cannot find cube " + cubeName);
-        }
 
         CubeSegment segment = cube.getSegment(segmentName, null);
         if (segment == null) {
-            throw new InternalErrorException("Cannot find segment " + segmentName);
+            throw new NotFoundException("Cannot find segment " + segmentName);
         }
 
         IJoinedFlatTableDesc flatTableDesc = new CubeJoinedFlatTableDesc(segment, true);
@@ -247,12 +245,8 @@ public class CubeController extends BasicController {
             "application/json" })
     @ResponseBody
     public void updateNotifyList(@PathVariable String cubeName, @RequestBody List<String> notifyList) {
+        checkCubeExists(cubeName);
         CubeInstance cube = cubeService.getCubeManager().getCube(cubeName);
-
-        if (cube == null) {
-            throw new InternalErrorException("Cannot find cube " + cubeName);
-        }
-
         try {
             cubeService.updateCubeNotifyList(cube, notifyList);
         } catch (Exception e) {
@@ -265,11 +259,8 @@ public class CubeController extends BasicController {
     @RequestMapping(value = "/{cubeName}/cost", method = { RequestMethod.PUT }, produces = { "application/json" })
     @ResponseBody
     public CubeInstance updateCubeCost(@PathVariable String cubeName, @RequestParam(value = "cost") int cost) {
+        checkCubeExists(cubeName);
         CubeInstance cube = cubeService.getCubeManager().getCube(cubeName);
-        if (cube == null) {
-            throw new InternalErrorException("Cannot find cube " + cubeName);
-        }
-
         try {
             return cubeService.updateCubeCost(cube, cost);
         } catch (Exception e) {
@@ -327,15 +318,12 @@ public class CubeController extends BasicController {
             "application/json" })
     @ResponseBody
     public CubeInstance deleteSegment(@PathVariable String cubeName, @PathVariable String segmentName) {
+        checkCubeExists(cubeName);
         CubeInstance cube = cubeService.getCubeManager().getCube(cubeName);
 
-        if (cube == null) {
-            throw new InternalErrorException("Cannot find cube " + cubeName);
-        }
-
         CubeSegment segment = cube.getSegment(segmentName, null);
         if (segment == null) {
-            throw new InternalErrorException("Cannot find segment '" + segmentName + "'");
+            throw new NotFoundException("Cannot find segment '" + segmentName + "'");
         }
 
         try {
@@ -406,9 +394,7 @@ public class CubeController extends BasicController {
             String submitter = SecurityContextHolder.getContext().getAuthentication().getName();
             CubeInstance cube = jobService.getCubeManager().getCube(cubeName);
 
-            if (cube == null) {
-                throw new InternalErrorException("Cannot find cube " + cubeName);
-            }
+            checkBuildingSegment(cube);
             return jobService.submitJob(cube, tsRange, segRange, sourcePartitionOffsetStart, sourcePartitionOffsetEnd,
                     CubeBuildTypeEnum.valueOf(buildType), force, submitter);
         } catch (Throwable e) {
@@ -430,9 +416,7 @@ public class CubeController extends BasicController {
             String submitter = SecurityContextHolder.getContext().getAuthentication().getName();
             CubeInstance cube = jobService.getCubeManager().getCube(cubeName);
 
-            if (cube == null) {
-                throw new InternalErrorException("Cannot find cube " + cubeName);
-            }
+            checkCubeExists(cubeName);
             logger.info("cuboid recommend:" + jobOptimizeRequest.getCuboidsRecommend());
             return jobService.submitOptimizeJob(cube, jobOptimizeRequest.getCuboidsRecommend(), submitter).getFirst();
         } catch (BadRequestException e) {
@@ -459,13 +443,10 @@ public class CubeController extends BasicController {
         try {
             String submitter = SecurityContextHolder.getContext().getAuthentication().getName();
             CubeInstance cube = jobService.getCubeManager().getCube(cubeName);
-            if (cube == null) {
-                throw new InternalErrorException("Cannot find cube " + cubeName);
-            }
 
             CubeSegment segment = cube.getSegmentById(segmentID);
             if (segment == null) {
-                throw new InternalErrorException("Cannot find segment '" + segmentID + "'");
+                throw new NotFoundException("Cannot find segment '" + segmentID + "'");
             }
 
             return jobService.submitRecoverSegmentOptimizeJob(segment, submitter);
@@ -482,12 +463,9 @@ public class CubeController extends BasicController {
     @ResponseBody
     public CubeInstance disableCube(@PathVariable String cubeName) {
         try {
+            checkCubeExists(cubeName);
             CubeInstance cube = cubeService.getCubeManager().getCube(cubeName);
 
-            if (cube == null) {
-                throw new InternalErrorException("Cannot find cube " + cubeName);
-            }
-
             return cubeService.disableCube(cube);
         } catch (Exception e) {
             String message = "Failed to disable cube: " + cubeName;
@@ -500,17 +478,9 @@ public class CubeController extends BasicController {
     @ResponseBody
     public CubeInstance purgeCube(@PathVariable String cubeName) {
         try {
+            checkCubeExists(cubeName);
             CubeInstance cube = cubeService.getCubeManager().getCube(cubeName);
 
-            if (cube == null) {
-                throw new InternalErrorException("Cannot find cube '" + cubeName + "'");
-            }
-
-            //            if (cube.getSegments() != null && cube.getBuildingSegments().size() > 0) {
-            //                int num = cube.getBuildingSegments().size();
-            //                throw new InternalErrorException("Cannot purge cube '" + cubeName + "' as there is " + num + " building " + (num > 1 ? "segment(s)." : "segment. Discard the related job first."));
-            //            }
-
             return cubeService.purgeCube(cube);
         } catch (Exception e) {
             String message = "Failed to purge cube: " + cubeName;
@@ -525,10 +495,8 @@ public class CubeController extends BasicController {
         String newCubeName = cubeRequest.getCubeName();
         String projectName = cubeRequest.getProject();
 
+        checkCubeExists(cubeName);
         CubeInstance cube = cubeService.getCubeManager().getCube(cubeName);
-        if (cube == null) {
-            throw new BadRequestException("Cannot find cube " + cubeName);
-        }
         if (cube.getStatus() == RealizationStatusEnum.DESCBROKEN) {
             throw new BadRequestException("Broken cube can't be cloned");
         }
@@ -538,7 +506,7 @@ public class CubeController extends BasicController {
 
         ProjectInstance project = cubeService.getProjectManager().getProject(projectName);
         if (project == null) {
-            throw new BadRequestException("Project " + projectName + " doesn't exist");
+            throw new NotFoundException("Project " + projectName + " doesn't exist");
         }
         // KYLIN-1925, forbid cloning cross projects
         if (!project.getName().equals(cube.getProject())) {
@@ -568,11 +536,8 @@ public class CubeController extends BasicController {
     @ResponseBody
     public CubeInstance enableCube(@PathVariable String cubeName) {
         try {
+            checkCubeExists(cubeName);
             CubeInstance cube = cubeService.getCubeManager().getCube(cubeName);
-            if (null == cube) {
-                throw new InternalErrorException("Cannot find cube " + cubeName);
-            }
-
             cubeService.checkEnableCubeCondition(cube);
 
             return cubeService.enableCube(cube);
@@ -586,10 +551,8 @@ public class CubeController extends BasicController {
     @RequestMapping(value = "/{cubeName}", method = { RequestMethod.DELETE }, produces = { "application/json" })
     @ResponseBody
     public void deleteCube(@PathVariable String cubeName) {
+        checkCubeExists(cubeName);
         CubeInstance cube = cubeService.getCubeManager().getCube(cubeName);
-        if (null == cube) {
-            throw new NotFoundException("Cube with name " + cubeName + " not found..");
-        }
 
         //drop Cube
         try {
@@ -632,7 +595,7 @@ public class CubeController extends BasicController {
                     : cubeRequest.getProject();
             ProjectInstance project = cubeService.getProjectManager().getProject(projectName);
             if (project == null) {
-                throw new BadRequestException("Project " + projectName + " doesn't exist");
+                throw new NotFoundException("Project " + projectName + " doesn't exist");
             }
             cubeService.createCubeAndDesc(project, desc);
         } catch (Exception e) {
@@ -766,7 +729,7 @@ public class CubeController extends BasicController {
     @RequestMapping(value = "/{cubeName}/holes", method = { RequestMethod.GET }, produces = { "application/json" })
     @ResponseBody
     public List<CubeSegment> getHoles(@PathVariable String cubeName) {
-        checkCubeName(cubeName);
+        checkCubeExists(cubeName);
         return cubeService.getCubeManager().calculateHoles(cubeName);
     }
 
@@ -779,7 +742,7 @@ public class CubeController extends BasicController {
     @RequestMapping(value = "/{cubeName}/holes", method = { RequestMethod.PUT }, produces = { "application/json" })
     @ResponseBody
     public List<JobInstance> fillHoles(@PathVariable String cubeName) {
-        checkCubeName(cubeName);
+        checkCubeExists(cubeName);
         List<JobInstance> jobs = Lists.newArrayList();
         List<CubeSegment> holes = cubeService.getCubeManager().calculateHoles(cubeName);
 
@@ -829,10 +792,8 @@ public class CubeController extends BasicController {
     @ResponseBody
     public void cuboidsExport(@PathVariable String cubeName, @RequestParam(value = "top") Integer top,
             HttpServletResponse response) throws IOException {
+        checkCubeExists(cubeName);
         CubeInstance cube = cubeService.getCubeManager().getCube(cubeName);
-        if (cube == null) {
-            throw new BadRequestException("Cube: [" + cubeName + "] not exist.");
-        }
 
         Map<Long, Long> cuboidList = getRecommendCuboidList(cube);
         List<Set<String>> dimensionSetList = Lists.newLinkedList();
@@ -871,11 +832,8 @@ public class CubeController extends BasicController {
     @RequestMapping(value = "/{cubeName}/cuboids/current", method = RequestMethod.GET)
     @ResponseBody
     public CuboidTreeResponse getCurrentCuboids(@PathVariable String cubeName) {
+        checkCubeExists(cubeName);
         CubeInstance cube = cubeService.getCubeManager().getCube(cubeName);
-        if (cube == null) {
-            logger.error("Get cube: [" + cubeName + "] failed when get current cuboids");
-            throw new BadRequestException("Get cube: [" + cubeName + "] failed when get current cuboids");
-        }
         // The cuboid tree displayed should be consistent with the current one
         CuboidScheduler cuboidScheduler = cube.getCuboidScheduler();
         Map<Long, Long> cuboidStatsMap = cube.getCuboids();
@@ -900,11 +858,8 @@ public class CubeController extends BasicController {
     @RequestMapping(value = "/{cubeName}/cuboids/recommend", method = RequestMethod.GET)
     @ResponseBody
     public CuboidTreeResponse getRecommendCuboids(@PathVariable String cubeName) throws IOException {
+        checkCubeExists(cubeName);
         CubeInstance cube = cubeService.getCubeManager().getCube(cubeName);
-        if (cube == null) {
-            logger.error("Get cube: [" + cubeName + "] failed when get recommend cuboids");
-            throw new BadRequestException("Get cube: [" + cubeName + "] failed when get recommend cuboids");
-        }
         Map<Long, Long> recommendCuboidStatsMap = getRecommendCuboidList(cube);
         if (recommendCuboidStatsMap == null || recommendCuboidStatsMap.isEmpty()) {
             return new CuboidTreeResponse();
@@ -1002,7 +957,7 @@ public class CubeController extends BasicController {
             "application/json" })
     @ResponseBody
     public GeneralResponse initStartOffsets(@PathVariable String cubeName) {
-        checkCubeName(cubeName);
+        checkCubeExists(cubeName);
         CubeInstance cubeInstance = cubeService.getCubeManager().getCube(cubeName);
         if (cubeInstance.getSourceType() != ISourceAware.ID_STREAMING) {
             String msg = "Cube '" + cubeName + "' is not a Streaming Cube.";
@@ -1048,13 +1003,23 @@ public class CubeController extends BasicController {
         request.setMessage(message);
     }
 
-    private void checkCubeName(String cubeName) {
+    private void checkCubeExists(String cubeName) {
         CubeInstance cubeInstance = cubeService.getCubeManager().getCube(cubeName);
-
-        String msg = "";
         if (cubeInstance == null) {
-            msg = "Cube '" + cubeName + "' not found.";
-            throw new IllegalArgumentException(msg);
+            Message msg = MsgPicker.getMsg();
+            throw new NotFoundException(String.format(msg.getCUBE_NOT_FOUND(), cubeName));
+        }
+    }
+
+    private void checkBuildingSegment(CubeInstance cube) {
+        checkBuildingSegment(cube, cube.getConfig().getMaxBuildingSegments());
+    }
+
+
+    private void checkBuildingSegment(CubeInstance cube, int maxBuildingSeg) {
+        if (cube.getBuildingSegments().size() >= maxBuildingSeg) {
+            throw new TooManyRequestException(
+                    "There is already " + cube.getBuildingSegments().size() + " building segment; ");
         }
     }
 
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller/ModelController.java b/server-base/src/main/java/org/apache/kylin/rest/controller/ModelController.java
index 07478db..41c7889 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller/ModelController.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller/ModelController.java
@@ -190,7 +190,7 @@ public class ModelController extends BasicController {
         }
 
         if (modelDesc == null || StringUtils.isEmpty(modelName)) {
-            throw new BadRequestException("Model does not exist.");
+            throw new NotFoundException("Model does not exist.");
         }
 
         if (!project.equals(modelDesc.getProject())) {
diff --git a/server-base/src/main/java/org/apache/kylin/rest/controller/ProjectController.java b/server-base/src/main/java/org/apache/kylin/rest/controller/ProjectController.java
index 4eedb8e1..44eeffe 100644
--- a/server-base/src/main/java/org/apache/kylin/rest/controller/ProjectController.java
+++ b/server-base/src/main/java/org/apache/kylin/rest/controller/ProjectController.java
@@ -28,6 +28,7 @@ import org.apache.kylin.common.util.JsonUtil;
 import org.apache.kylin.metadata.project.ProjectInstance;
 import org.apache.kylin.rest.exception.BadRequestException;
 import org.apache.kylin.rest.exception.InternalErrorException;
+import org.apache.kylin.rest.exception.NotFoundException;
 import org.apache.kylin.rest.request.ProjectRequest;
 import org.apache.kylin.rest.service.AccessService;
 import org.apache.kylin.rest.service.CubeService;
@@ -155,7 +156,7 @@ public class ProjectController extends BasicController {
         try {
             ProjectInstance currentProject = projectService.getProjectManager().getProject(formerProjectName);
             if (currentProject == null) {
-                throw new InternalErrorException("The project named " + formerProjectName + " does not exists");
+                throw new NotFoundException("The project named " + formerProjectName + " does not exists");
             }
 
             if (projectDesc.getName().equals(currentProject.getName())) {
diff --git a/server-base/src/main/java/org/apache/kylin/rest/exception/TooManyRequestException.java b/server-base/src/main/java/org/apache/kylin/rest/exception/TooManyRequestException.java
new file mode 100644
index 0000000..55cf332
--- /dev/null
+++ b/server-base/src/main/java/org/apache/kylin/rest/exception/TooManyRequestException.java
@@ -0,0 +1,58 @@
+/*
+ * 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.exception;
+
+import org.apache.kylin.rest.response.ResponseCode;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.ResponseStatus;
+
+/**
+ *
+ */
+@ResponseStatus(value = HttpStatus.TOO_MANY_REQUESTS)
+public class TooManyRequestException extends RuntimeException {
+
+    private static final long serialVersionUID = -6798154278095441848L;
+
+    private String code;
+
+    /**
+     * legacy support, new APIs should not call this. Instead, new APIs should provide return code
+     */
+    public TooManyRequestException(String msg) {
+        super(msg);
+        this.code = ResponseCode.CODE_UNDEFINED;
+    }
+
+    public TooManyRequestException(String msg, String code) {
+        super(msg);
+        this.code = code;
+    }
+
+    public TooManyRequestException(String msg, String code, Throwable cause) {
+        super(msg, cause);
+        this.code = code;
+    }
+
+
+    public String getCode() {
+        return code;
+    }
+
+}
diff --git a/server/src/test/java/org/apache/kylin/rest/controller/CubeControllerTest.java b/server/src/test/java/org/apache/kylin/rest/controller/CubeControllerTest.java
index b43cb9c..6ebd9e8 100644
--- a/server/src/test/java/org/apache/kylin/rest/controller/CubeControllerTest.java
+++ b/server/src/test/java/org/apache/kylin/rest/controller/CubeControllerTest.java
@@ -28,6 +28,7 @@ import org.apache.kylin.cube.model.CubeDesc;
 import org.apache.kylin.cube.model.DimensionDesc;
 import org.apache.kylin.metadata.model.SegmentRange.TSRange;
 import org.apache.kylin.rest.exception.InternalErrorException;
+import org.apache.kylin.rest.exception.NotFoundException;
 import org.apache.kylin.rest.request.CubeRequest;
 import org.apache.kylin.rest.response.CubeInstanceResponse;
 import org.apache.kylin.rest.response.GeneralResponse;
@@ -140,7 +141,7 @@ public class CubeControllerTest extends ServiceTestBase {
         cubeController.deleteSegment(cubeName, "20131212000000_20140112000000");
     }
 
-    @Test(expected = InternalErrorException.class)
+    @Test(expected = NotFoundException.class)
     public void testDeleteSegmentNotExist() throws IOException {
         String cubeName = "test_kylin_cube_with_slr_ready_3_segments";
         CubeDesc[] cubes = cubeDescController.getCube(cubeName);