You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@griffin.apache.org by gu...@apache.org on 2018/01/16 09:00:28 UTC

[3/3] incubator-griffin git commit: fix job management sysnc bug and delete job triggerkey not exist bug

fix job management sysnc bug and delete job triggerkey not exist bug

Author: ahutsunshine <ah...@gmail.com>
Author: He Wang <wa...@qq.com>

Closes #190 from ahutsunshine/master.


Project: http://git-wip-us.apache.org/repos/asf/incubator-griffin/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-griffin/commit/44eea866
Tree: http://git-wip-us.apache.org/repos/asf/incubator-griffin/tree/44eea866
Diff: http://git-wip-us.apache.org/repos/asf/incubator-griffin/diff/44eea866

Branch: refs/heads/master
Commit: 44eea866d34fdd6729b67bf9dfaa87d655d22d58
Parents: 06f969f
Author: ahutsunshine <ah...@gmail.com>
Authored: Tue Jan 16 17:00:18 2018 +0800
Committer: Lionel Liu <bh...@163.com>
Committed: Tue Jan 16 17:00:18 2018 +0800

----------------------------------------------------------------------
 griffin-doc/service/api-guide.md                | 1084 +++++++++
 griffin-doc/service/postman/griffin.json        | 2259 ++++++++++--------
 .../apache/griffin/core/job/JobController.java  |    2 +-
 .../apache/griffin/core/job/JobInstance.java    |    3 +-
 .../org/apache/griffin/core/job/JobService.java |    2 +-
 .../apache/griffin/core/job/JobServiceImpl.java |   86 +-
 .../griffin/core/job/entity/JobDataSegment.java |    5 +
 .../griffin/core/job/entity/JobSchedule.java    |    6 +-
 .../griffin/core/login/LoginController.java     |    3 +-
 .../measure/ExternalMeasureOperationImpl.java   |   14 +-
 .../measure/GriffinMeasureOperationImpl.java    |   12 +-
 .../core/measure/MeasureServiceImpl.java        |   14 +-
 .../core/measure/entity/DataConnector.java      |   21 +-
 .../core/measure/entity/GriffinMeasure.java     |    8 +
 .../griffin/core/metric/MetricController.java   |    5 +-
 .../griffin/core/metric/MetricService.java      |    5 +-
 .../griffin/core/metric/MetricServiceImpl.java  |   20 +-
 .../griffin/core/metric/MetricStoreImpl.java    |    2 +-
 .../src/main/resources/application.properties   |   16 +-
 .../griffin/core/job/JobControllerTest.java     |  308 +--
 .../core/job/repo/JobInstanceRepoTest.java      |   87 +
 .../core/measure/MeasureControllerTest.java     |  398 ++-
 .../core/measure/MeasureOrgControllerTest.java  |    1 -
 .../core/measure/MeasureOrgServiceImplTest.java |    4 +-
 .../core/measure/MeasureServiceImplTest.java    |    6 +-
 .../griffin/core/measure/MeasureTestHelper.java |   89 -
 .../core/measure/repo/MeasureRepoTest.java      |    2 +-
 .../apache/griffin/core/util/EntityHelper.java  |   89 +
 28 files changed, 3057 insertions(+), 1494 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-griffin/blob/44eea866/griffin-doc/service/api-guide.md
----------------------------------------------------------------------
diff --git a/griffin-doc/service/api-guide.md b/griffin-doc/service/api-guide.md
new file mode 100644
index 0000000..9668145
--- /dev/null
+++ b/griffin-doc/service/api-guide.md
@@ -0,0 +1,1084 @@
+<!--
+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.
+-->
+
+# Apache Griffin API Guide
+
+This page lists the major RESTful APIs provided by Griffin.
+
+Apache Griffin default `BASE_PATH` is `http://<your ip>:8080`. 
+
+- [Griffin Basic](#1)
+
+- [Measures](#2)
+
+- [Jobs](#3)
+
+- [Metrics](#4)
+
+- [Hive MetaStore](#5)
+
+- [Auth](#6)
+
+
+<h2 id = "1"></h2>
+## Griffin Basic
+
+### Get griffin version
+`GET /api/v1/version`
+
+#### Response Body Sample
+`0.1.0`
+
+<h2 id = "2"></h2>
+## Measures
+### Add measure
+`POST /api/v1/measures`
+
+#### Request Header
+| key          | value            |
+| ------------ | ---------------- |
+| Content-Type | application/json |
+
+#### Request Body
+
+| name    | description    | type    |
+| ------- | -------------- | ------- |
+| measure | measure entity | Measure |
+
+There are two different measures that are griffin measure and external measure.
+If you want to create an external measure,you can use following example json in request body.
+```
+{
+    "type": "external",
+    "name": "external_name",
+    "description": " test measure",
+    "organization": "orgName",
+    "owner": "test",
+    "metricName": "metricName"
+}
+```
+Here gives a griffin measure example in request body and response body. 
+#### Request Body example 
+```
+{
+    "name":"measure_name",
+	"type":"griffin",
+    "description":"create a measure",
+    "evaluate.rule":{
+        "rules":[
+            {
+                "rule":"source.desc=target.desc",
+                "dsl.type":"griffin-dsl",
+                "dq.type":"accuracy",
+                "details":{}
+            }
+        ]
+    },
+    "data.sources":[
+        {
+            "name":"source",
+            "connectors":[
+                {
+					"name":"connector_name_source",
+                    "type":"HIVE",
+                    "version":"1.2",
+					"data.unit":"1h",
+                    "config":{
+                        "database":"default",
+                        "table.name":"demo_src",
+                        "where":"dt=#YYYYMMdd# AND hour=#HH#"
+                    },
+                    "predicates":[
+                        {
+                            "type":"file.exist",
+                            "config":{
+                                "root.path":"hdfs:///griffin/demo_src",
+                                "path":"/dt=#YYYYMMdd#/hour=#HH#/_DONE"
+                            }
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "name":"target",
+            "connectors":[
+                {
+					"name":"connector_name_target",
+                    "type":"HIVE",
+                    "version":"1.2",
+					"data.unit":"1h",
+                    "config":{
+                        "database":"default",
+                        "table.name":"demo_src",
+                        "where":"dt=#YYYYMMdd# AND hour=#HH#"
+                    },
+                    "predicates":[
+                        {
+                            "type":"file.exist",
+                            "config":{
+                                "root.path":"hdfs:///griffin/demo_src",
+                                "path":"/dt=#YYYYMMdd#/hour=#HH#/_DONE"
+                            }
+                        }
+                    ]
+                }
+            ]
+        }
+    ]
+}
+```
+#### Response Body Sample
+```
+{
+  "code": 201,
+  "description": "Create Measure Succeed"
+}
+```
+It may return failed messages.Such as,
+```
+{
+  "code": 410,
+  "description": "Create Measure Failed, duplicate records"
+}
+
+```
+The reason for failure may be that connector names already exist or connector names are empty.
+
+
+### Get measures
+`GET /api/v1/measures`
+#### Response Body Sample
+```
+[
+    {
+        "id": 1,
+        "name": "measurename",
+        "description": "This is measure test.",
+        "owner": "test",
+        "deleted": false,
+        "process.type": "batch",
+        "evaluateRule": {
+            "id": 1,
+            "rules": [
+                {
+                    "id": 1,
+                    "rule": "source.id=target.id AND source.age=target.age",
+                    "dsl.type": "griffin-dsl",
+                    "dq.type": "accuracy"
+                }
+            ]
+        },
+        "data.sources": [
+            {
+                "id": 1,
+                "name": "source",
+                "connectors": [
+                    {
+                        "id": 1,
+                        "type": "HIVE",
+                        "version": "1.2",
+                        "config": {
+                            "database": "default",
+                            "table.name": "demo_src"
+                        }
+                    }
+                ]
+            },
+            {
+                "id": 2,
+                "name": "target",
+                "connectors": [
+                    {
+                        "id": 2,
+                        "type": "HIVE",
+                        "version": "1.2",
+                        "config": {
+                            "database": "default",
+                            "table.name": "demo_tgt"
+                        }
+                    }
+                ]
+            }
+        ]
+    }
+]
+```
+
+
+### Update measure
+`PUT /api/v1/measures`
+#### Request Header
+| key          | value            |
+| ------------ | ---------------- |
+| Content-Type | application/json |
+
+#### Request Body
+| name    | description    | type    |
+| ------- | -------------- | ------- |
+| measure | measure entity | Measure |
+There are two different measures that are griffin measure and external measure.
+If you want to update an external measure,you can use following example json in request body.
+```
+{
+	"id":1,
+    "type": "external",
+    "name": "external_name",
+    "description": " update test measure",
+    "organization": "orgName",
+    "owner": "test",
+    "metricName": "metricName"
+}
+```
+Here gives a griffin measure example in request body and response body. 
+#### Request Body example 
+```
+{
+        "id": 1,
+        "name": "measure_official_update",
+        "description": "create a measure",
+        "owner": "test",
+        "deleted": false,
+        "type": "griffin",
+        "process.type": "batch",
+        "data.sources": [
+            {
+                "id": 1,
+                "name": "source",
+                "connectors": [
+                    {
+                        "id": 1,
+                        "name": "connector_name_source",
+                        "type": "HIVE",
+                        "version": "1.2",
+                        "predicates": [],
+                        "data.unit": "1h",
+                        "config": {
+                            "database": "default",
+                            "table.name": "demo_src",
+                            "where": "dt=#YYYYMMdd# AND hour=#HH#"
+                        }
+                    }
+                ]
+            },
+            {
+                "id": 2,
+                "name": "target",
+                "connectors": [
+                    {
+                        "id": 2,
+                        "name": "connector_name_target",
+                        "type": "HIVE",
+                        "version": "1.2",
+                        "predicates": [],
+                        "data.unit": "1h",
+                        "config": {
+                            "database": "default",
+                            "table.name": "demo_src",
+                            "where": "dt=#YYYYMMdd# AND hour=#HH#"
+                        }
+                    }
+                ]
+            }
+        ],
+        "evaluate.rule": {
+            "id": 1,
+            "rules": [
+                {
+                    "id": 1,
+                    "rule": "source.desc=target.desc",
+                    "dsl.type": "griffin-dsl",
+                    "dq.type": "accuracy",
+                    "details": {}
+                }
+            ]
+        }
+    }
+```
+#### Response Body Sample
+```
+{
+  "code": 204,
+  "description": "Update Measure Succeed"
+}
+```
+It may return failed messages.Such as,
+```
+{
+  "code": 400,
+  "description": "Resource Not Found"
+}
+
+```
+
+The reason for failure may be that measure id doesn't exist.
+
+### Delete measure
+`DELETE /api/v1/measures/{id}`
+When deleting a measure,api will also delete related jobs.
+#### Path Variable
+- id -`required` `Long` measure id
+
+#### Request Sample
+
+`/api/v1/measures/1`
+
+#### Response Body Sample
+```
+{
+  "code": 202,
+  "description": "Delete Measures By Id Succeed"
+}
+```
+
+It may return failed messages.Such as,
+
+```
+{
+  "code": 400,
+  "description": "Resource Not Found"
+}
+
+```
+
+The reason for failure may be that measure id doesn't exist.
+
+
+### Get measure by id
+`GET /api/v1/measures/{id}`
+#### Path Variable
+- id -`required` `Long` measure id
+
+#### Request Sample
+
+`/api/v1/measures/1`
+
+#### Response Body Sample
+```
+{
+    "id": 1,
+    "name": "measureName",
+    "description": "This is a test measure",
+    "organization": "orgName",
+    "evaluateRule": {
+        "id": 1,
+        "rules": [
+            {
+                "id": 1,
+                "rule": "source.id = target.id and source.age = target.age and source.desc = target.desc",
+                "dsl.type": "griffin-dsl",
+                "dq.type": "accuracy"
+            }
+        ]
+    },
+    "owner": "test",
+    "deleted": false,
+    "process.type": "batch",
+    "data.sources": [
+        {
+            "id": 39,
+            "name": "source",
+            "connectors": [
+                {
+                    "id": 1,
+                    "type": "HIVE",
+                    "version": "1.2",
+                    "config": {
+                        "database": "default",
+                        "table.name": "demo_src"
+                    }
+                }
+            ]
+        },
+        {
+            "id": 2,
+            "name": "target",
+            "connectors": [
+                {
+                    "id": 2,
+                    "type": "HIVE",
+                    "version": "1.2",
+                    "config": {
+                        "database": "default",
+                        "table.name": "demo_tgt"
+                    }
+                }
+            ]
+        }
+    ]
+}
+```
+It may return no content.That's because your measure id doesn't exist.
+
+<h2 id = "3"></h2>
+## Jobs
+### Add job
+`POST /api/v1/jobs`
+#### Request Header
+| key          | value            |
+| ------------ | ---------------- |
+| Content-Type | application/json |
+
+#### Request Body
+| name        | description                              | type        |
+| ----------- | ---------------------------------------- | ----------- |
+| jobSchedule | custom class composed of job key parameters | JobSchedule |
+
+#### Request Body Sample
+```
+{
+    "measure.id": 1,
+	"job.name":"job_name",
+    "cron.expression": "0 0/4 * * * ?",
+    "cron.time.zone": "GMT+8:00",
+    "predicate.config": {
+		"checkdonefile.schedule":{
+			"interval": "5m",
+			"repeat": 12
+		}
+    },
+    "data.segments": [
+        {
+            "data.connector.name": "connector_name_source_test",
+			"as.baseline":true, 
+            "segment.range": {
+                "begin": "-1h",
+                "length": "1h"
+            }
+        },
+        {
+            "data.connector.name": "connector_name_target_test",
+            "segment.range": {
+                "begin": "-1h",
+                "length": "1h"
+            }
+        }
+    ]
+}
+```
+#### Response Body Sample
+```
+{
+  "code": 205,
+  "description": "Create Job Succeed"
+}
+```
+It may return failed messages.Such as,
+
+```
+{
+  "code": 405,
+  "description": "Create Job Failed"
+}
+```
+
+There are several reasons to create job failure.
+
+- Measure id does not exist.
+- Job name already exits.
+- Param as.baselines aren't set or are all false.
+- Connector name doesn't exist in your measure.
+- The trigger key already exists.
+
+### Get jobs
+`GET /api/v1/jobs`
+
+#### Response Body Sample
+```
+[
+    {
+        "jobId": 1,
+        "jobName": "job_name",
+        "measureId": 1,
+        "triggerState": "NORMAL",
+        "nextFireTime": 1515400080000,
+        "previousFireTime": 1515399840000,
+        "cronExpression": "0 0/4 * * * ?"
+    }
+]
+
+```
+
+### Delete job by id
+#### `DELETE /api/v1/jobs/{id}`
+#### Path Variable
+- id -`required` `Long` job id
+
+#### Response Body Sample
+```
+{
+  "code": 206,
+  "description": "Delete Job Succeed"
+}
+
+```
+It may return failed messages.Such as,
+```
+{
+    "code": 406,
+    "description": "Delete Job Failed"
+}
+```
+The reason for failure may be that job id does not exist.
+
+### Delete job by name
+#### `DELETE /api/v1/jobs`
+| name    | description | type   | example value |
+| ------- | ----------- | ------ | ------------- |
+| jobName | job name    | String | job_name      |
+
+#### Response Body Sample
+```
+{
+  "code": 206,
+  "description": "Delete Job Succeed"
+}
+
+```
+It may return failed messages.Such as,
+```
+{
+    "code": 406,
+    "description": "Delete Job Failed"
+}
+```
+The reason for failure may that job name does not exist.
+
+
+### Get job instances
+`GET /api/v1/jobs/instances`
+
+| name  | description                         | type | example value |
+| ----- | ----------------------------------- | ---- | ------------- |
+| jobId | job id                              | Long | 1             |
+| page  | page you want starting from index 0 | int  | 0             |
+| size  | instance number per page            | int  | 10            |
+
+#### Response Body Sample
+```
+[
+    {
+        "id": 1,
+        "sessionId": null,
+        "state": "success",
+        "appId": null,
+        "appUri": null,
+        "predicateGroup": "PG",
+        "predicateName": "job_name_predicate_1515399840077",
+        "deleted": true,
+        "timestamp": 1515399840092,
+        "expireTimestamp": 1516004640092
+    },
+    {
+        "id": 2,
+        "sessionId": null,
+        "state": "not_found",
+        "appId": null,
+        "appUri": null,
+        "predicateGroup": "PG",
+        "predicateName": "job_name_predicate_1515399840066",
+        "deleted": true,
+        "timestamp": 1515399840067,
+        "expireTimestamp": 1516004640067
+    }
+]
+```
+
+### Get job healthy statistics
+`GET /api/v1/jobs/health`
+
+#### Response Body Sample
+```
+{
+  "healthyJobCount": 1,
+  "jobCount": 2
+}
+```
+
+<h2 id = "4"></h2>
+## Metrics
+### Get metrics
+`GET /api/v1/metrics`
+#### Response Example
+```
+[
+    {
+        "name": "external_name",
+        "description": " test measure",
+        "organization": "orgName",
+        "owner": "test",
+        "metricValues": [
+            {
+                "name": "metricName",
+                "tmst": 1509599811123,
+                "value": {
+                    "__tmst": 1509599811123,
+                    "miss": 11,
+                    "total": 125000,
+                    "matched": 124989
+                }
+            }
+        ]
+    }
+]
+```
+
+### Add metric values
+`POST /api/v1/metrics/values`
+#### Request Header
+| key          | value            |
+| ------------ | ---------------- |
+| Content-Type | application/json |
+#### Request Body
+| name          | description             | type        |
+| ------------- | ----------------------- | ----------- |
+| Metric Values | A list of metric values | MetricValue |
+#### Request Body Sample
+```
+[
+	{
+		"name" : "metricName",
+		"tmst" : 1509599811123,
+		"value" : {
+			"__tmst" : 1509599811123,
+			"miss" : 11,
+			"total" : 125000,
+			"matched" : 124989
+		}
+   }
+]
+```
+#### Response Body Sample
+```
+{
+    "code": 210,
+    "description": "Add Metric Values Success"
+}
+```
+
+It may return failed message
+
+```
+{
+	"code": 412,
+    "description": "Add Metric Values Failed"
+}
+```
+The returned HTTP status code identifies the reason for failure.
+### Get metric values by name 
+`GET /api/v1/metrics/values`
+
+#### Request Parameter
+| name       | description                              | type   | example value |
+| ---------- | ---------------------------------------- | ------ | ------------- |
+| metricName | name of the metric values                | String | metricName    |
+| size       | max amount of return values              | int    | 5             |
+| offset     | the amount of records to skip by timestamp in descending order | int    | 0             |
+
+Parameter offset is optional, it has default value as 0.
+#### Response Body Sample
+```
+[
+    {
+        "name": "metricName",
+        "tmst": 1509599811123,
+        "value": {
+            "__tmst": 1509599811123,
+            "miss": 11,
+            "total": 125000,
+            "matched": 124989
+        }
+    }
+]
+```
+
+### Delete metric values by name
+`DELETE /api/v1/metrics/values`
+#### Request Parameters 
+| name       | description               | type   | example value |
+| ---------- | ------------------------- | ------ | ------------- |
+| metricName | name of the metric values | String | metricName    |
+#### Response Body Sample
+```
+{
+    "code": 211,
+    "description": "Delete Metric Values Success"
+}
+```
+It may return failed messages
+```
+{
+    "code": 413,
+    "description": "Delete Metric Values Failed"
+}
+```
+The returned HTTP status code identifies the reason for failure.
+
+<h2 id = "5"></h2>
+### Hive MetaStore
+### Get table metadata
+`GET /api/v1/metadata/hive/table`
+#### Request Parameters
+| name  | description        | type   | example value |
+| ----- | ------------------ | ------ | ------------- |
+| db    | hive database name | String | default       |
+| table | hive table name    | String | demo_src      |
+
+#### Response Example Sample
+```
+{
+    "tableName": "demo_src",
+    "dbName": "default",
+    "owner": "root",
+    "createTime": 1505986176,
+    "lastAccessTime": 0,
+    "retention": 0,
+    "sd": {
+        "cols": [
+            {
+                "name": "id",
+                "type": "bigint",
+                "comment": null,
+                "setName": true,
+                "setType": true,
+                "setComment": false
+            },
+            {
+                "name": "age",
+                "type": "int",
+                "comment": null,
+                "setName": true,
+                "setType": true,
+                "setComment": false
+            },
+            {
+                "name": "desc",
+                "type": "string",
+                "comment": null,
+                "setName": true,
+                "setType": true,
+                "setComment": false
+            }
+        ],
+        "location": "hdfs://sandbox:9000/griffin/data/batch/demo_src"
+    },
+    "partitionKeys": [
+        {
+            "name": "dt",
+            "type": "string",
+            "comment": null,
+            "setName": true,
+            "setType": true,
+            "setComment": false
+        },
+        {
+            "name": "hour",
+            "type": "string",
+            "comment": null,
+            "setName": true,
+            "setType": true,
+            "setComment": false
+        }
+    ]
+}
+```
+### Get table names
+`GET /api/v1/metadata/hive/tables/names`
+#### Request Parameter
+| name | description        | typ    | example value |
+| ---- | ------------------ | ------ | ------------- |
+| db   | hive database name | String | default       |
+
+#### Response Example Sample
+```
+[
+  "demo_src",
+  "demo_tgt"
+]
+```
+
+### Get all database tables metadata
+`GET /api/v1/metadata/hive/dbs/tables`
+#### Response Example Sample
+```
+{
+   "default": [
+    {
+      "tableName": "demo_src",
+      "dbName": "default",
+      "owner": "root",
+      "createTime": 1505986176,
+      "lastAccessTime": 0,
+      "sd": {
+        "cols": [
+          {
+            "name": "id",
+            "type": "bigint",
+            "comment": null,
+            "setComment": false,
+            "setType": true,
+            "setName": true
+          },
+          {
+            "name": "age",
+            "type": "int",
+            "comment": null,
+            "setComment": false,
+            "setType": true,
+            "setName": true
+          },
+          {
+            "name": "desc",
+            "type": "string",
+            "comment": null,
+            "setComment": false,
+            "setType": true,
+            "setName": true
+          }
+        ],
+        "location": "hdfs://sandbox:9000/griffin/data/batch/demo_src"
+      },
+      "partitionKeys": [
+        {
+          "name": "dt",
+          "type": "string",
+          "comment": null,
+          "setComment": false,
+          "setType": true,
+          "setName": true
+        },
+        {
+          "name": "hour",
+          "type": "string",
+          "comment": null,
+          "setComment": false,
+          "setType": true,
+          "setName": true
+        }
+      ]
+    },
+    {
+      "tableName": "demo_tgt",
+      "dbName": "default",
+      "owner": "root",
+      "createTime": 1505986176,
+      "lastAccessTime": 0,
+      "sd": {
+        "cols": [
+          {
+            "name": "id",
+            "type": "bigint",
+            "comment": null,
+            "setComment": false,
+            "setType": true,
+            "setName": true
+          },
+          {
+            "name": "age",
+            "type": "int",
+            "comment": null,
+            "setComment": false,
+            "setType": true,
+            "setName": true
+          },
+          {
+            "name": "desc",
+            "type": "string",
+            "comment": null,
+            "setComment": false,
+            "setType": true,
+            "setName": true
+          }
+        ],
+        "location": "hdfs://sandbox:9000/griffin/data/batch/demo_tgt"
+      },
+      "partitionKeys": [
+        {
+          "name": "dt",
+          "type": "string",
+          "comment": null,
+          "setComment": false,
+          "setType": true,
+          "setName": true
+        },
+        {
+          "name": "hour",
+          "type": "string",
+          "comment": null,
+          "setComment": false,
+          "setType": true,
+          "setName": true
+        }
+      ]
+    }
+  ]
+}
+
+```
+
+### Get database names
+`GET /api/v1/metadata/hive/dbs`
+#### Response Example Sample
+```
+[
+	"default"
+]
+```
+
+### Get tables metadata
+`GET /api/v1/metadata/hive/tables`
+#### Request Parameter
+| name | description        | typ    | example value |
+| ---- | ------------------ | ------ | ------------- |
+| db   | hive database name | String | default       |
+#### Response Body Sample
+```
+[
+  {
+    "tableName": "demo_src",
+    "dbName": "default",
+    "owner": "root",
+    "createTime": 1508216660,
+    "lastAccessTime": 0,
+    "retention": 0,
+    "sd": {
+      "cols": [
+        {
+          "name": "id",
+          "type": "bigint",
+          "comment": null,
+          "setName": true,
+          "setType": true,
+          "setComment": false
+        },
+        {
+          "name": "age",
+          "type": "int",
+          "comment": null,
+          "setName": true,
+          "setType": true,
+          "setComment": false
+        },
+        {
+          "name": "desc",
+          "type": "string",
+          "comment": null,
+          "setName": true,
+          "setType": true,
+          "setComment": false
+        }
+      ],
+      "location": "hdfs://sandbox:9000/griffin/data/batch/demo_src"
+    },
+    "partitionKeys": [
+      {
+        "name": "dt",
+        "type": "string",
+        "comment": null,
+        "setName": true,
+        "setType": true,
+        "setComment": false
+      },
+      {
+        "name": "hour",
+        "type": "string",
+        "comment": null,
+        "setName": true,
+        "setType": true,
+        "setComment": false
+      }
+    ]
+  },
+  {
+    "tableName": "demo_tgt",
+    "dbName": "default",
+    "owner": "root",
+    "createTime": 1508216660,
+    "lastAccessTime": 0,
+    "retention": 0,
+    "sd": {
+      "cols": [
+        {
+          "name": "id",
+          "type": "bigint",
+          "comment": null,
+          "setName": true,
+          "setType": true,
+          "setComment": false
+        },
+        {
+          "name": "age",
+          "type": "int",
+          "comment": null,
+          "setName": true,
+          "setType": true,
+          "setComment": false
+        },
+        {
+          "name": "desc",
+          "type": "string",
+          "comment": null,
+          "setName": true,
+          "setType": true,
+          "setComment": false
+        }
+      ],
+      "location": "hdfs://sandbox:9000/griffin/data/batch/demo_tgt"
+ },
+    "partitionKeys": [
+      {
+        "name": "dt",
+        "type": "string",
+        "comment": null,
+        "setName": true,
+        "setType": true,
+        "setComment": false
+      },
+      {
+        "name": "hour",
+        "type": "string",
+        "comment": null,
+        "setName": true,
+        "setType": true,
+        "setComment": false
+      }
+    ]
+  }
+]
+```
+
+
+<h2 id = "6"></h2>
+## Auth
+### User authentication
+`POST /api/v1/login/authenticate`
+
+#### Request Parameter
+| name | description                           | type | example value                           |
+| ---- | ------------------------------------- | ---- | --------------------------------------- |
+| map  | a map contains user name and password | Map  | `{"username":"user","password":"test"}` |
+
+#### Response Body Sample
+```
+{
+  "fullName": "Default",
+  "ntAccount": "user",
+  "status": 0
+}
+```