You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kylin.apache.org by zh...@apache.org on 2015/10/22 12:06:54 UTC

[2/5] incubator-kylin git commit: KYLIN-1041, Streaming UI

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/js/model/cubeListModel.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/model/cubeListModel.js b/webapp/app/js/model/cubeListModel.js
index 7145092..5a2d1b2 100755
--- a/webapp/app/js/model/cubeListModel.js
+++ b/webapp/app/js/model/cubeListModel.js
@@ -17,8 +17,8 @@
 */
 
 KylinApp.service('CubeList',function(CubeService,$q,AccessService){
-    var cubes=[];
     var _this = this;
+    this.cubes=[];
 
     this.list = function(queryParam){
 

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/js/model/streamingListModel.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/model/streamingListModel.js b/webapp/app/js/model/streamingListModel.js
new file mode 100644
index 0000000..113ffe6
--- /dev/null
+++ b/webapp/app/js/model/streamingListModel.js
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+KylinApp.service('StreamingList', function (CubeService, $q, AccessService, StreamingService) {
+  var _this = this;
+  this.streamingConfigs = [];
+  this.kafkaConfigs = [];
+
+
+  this.list = function () {
+    var defer = $q.defer();
+
+    var streamingPromises = [];
+    var kafkaPromises = [];
+
+
+    kafkaPromises.push(StreamingService.getKfkConfig({}, function (kfkConfigs) {
+      _this.kafkaConfigs = kfkConfigs;
+    },function(){
+      defer.reject("Failed to load models");
+    }).$promise);
+
+    streamingPromises.push(StreamingService.getConfig({}, function (streamings) {
+      _this.streamingConfigs = streamings;
+    },function(){
+      defer.reject("Failed to load models");
+    }).$promise);
+
+    $q.all(streamingPromises,kafkaPromises).then(function(result,rs){
+      defer.resolve("success");
+    },function(){
+      defer.resolve("failed");
+    })
+    return defer.promise;
+
+  };
+
+  this.checkCubeExist = function(cubeName){
+    var result = {streaming:null,exist:false};
+    for(var i=0;i<_this.streamingConfigs.length;i++){
+      if(_this.streamingConfigs[i].cubeName == cubeName){
+        result ={
+          streaming:_this.streamingConfigs[i],
+          exist:true
+        }
+        break;
+      }
+    }
+    return result;
+  }
+
+  this.getKafkaConfig = function(kfkName){
+      for(var i=0;i<_this.kafkaConfigs.length;i++) {
+        if(_this.kafkaConfigs[i].name == kfkName){
+          return _this.kafkaConfigs[i];
+        }
+      }
+    }
+
+  this.removeAll = function () {
+    _this.streamingConfigs = [];
+    _this.kafkaConfigs = [];
+  };
+
+});

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/js/model/streamingModel.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/model/streamingModel.js b/webapp/app/js/model/streamingModel.js
new file mode 100644
index 0000000..fa2d20c
--- /dev/null
+++ b/webapp/app/js/model/streamingModel.js
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+KylinApp.service('StreamingModel', function () {
+
+  //
+  this.createStreamingConfig = function () {
+    var streamingConfig = {
+      "name": "",
+      "iiName": "",
+      "cubeName": ""
+    };
+
+    return streamingConfig;
+  };
+
+  this.createKafkaConfig = function () {
+    var kafkaConfig = {
+      "name": "",
+      "topic": "",
+      "timeout": "60000",
+      "maxReadCount": "1000",
+      "bufferSize": "65536",
+      "parserName": "org.apache.kylin.streaming.TimedJsonStreamParser",
+      "margin": "300000",
+      "clusters":[],
+      "parserProperties":""
+      }
+
+    return kafkaConfig;
+  }
+
+  this.createKafkaCluster = function () {
+      var kafkaCluster = {
+          "brokers":[]
+      }
+
+      return kafkaCluster;
+  }
+
+  this.createBrokerConfig = function () {
+        var brokerConfig = {
+            "id":'',
+            "host":'',
+            "port":''
+        }
+
+      return brokerConfig;
+  }
+
+})

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/js/services/streaming.js
----------------------------------------------------------------------
diff --git a/webapp/app/js/services/streaming.js b/webapp/app/js/services/streaming.js
new file mode 100644
index 0000000..9da4394
--- /dev/null
+++ b/webapp/app/js/services/streaming.js
@@ -0,0 +1,28 @@
+/*
+ * 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.
+*/
+
+KylinApp.factory('StreamingService', ['$resource', function ($resource, config) {
+    return $resource(Config.service.url + 'streaming/:streamingId/:propName/:propValue/:action', {}, {
+        list: {method: 'GET', params: {}, isArray: true},
+        'getConfig': {method: 'GET',params: {action:'getConfig'},isArray:true},
+        'getKfkConfig': {method: 'GET',params: {action:'getKfkConfig'},isArray:true},
+        drop: {method: 'DELETE', params: {}, isArray: false},
+        save: {method: 'POST', params: {}, isArray: false},
+        update: {method: 'PUT', params: {}, isArray: false}
+    });
+}]);

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/cubeDesigner/filter.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubeDesigner/filter.html b/webapp/app/partials/cubeDesigner/filter.html
deleted file mode 100644
index 118c4aa..0000000
--- a/webapp/app/partials/cubeDesigner/filter.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!--
-* 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.
--->
-
-<div ng-controller="CubeFilterCtrl">
-<div class="row">
-    <div class="col-xs-8">
-        <!--Cube Designer-->
-        <div class="form-group" ng-if="state.mode=='edit'"
-             style="font-family:'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro'">
-            <label for="filter_condition"
-                   style="color: #930f80;"><b>WHERE</b></label>
-            <textarea id="filter_condition" type="text"
-                    style="height:150px"
-                    class="form-control box-default"
-                    placeholder="Please input WHERE clause without typing 'WHERE'"
-                    ng-model="metaModel.model.filter_condition">
-            </textarea>
-        </div>
-        <!--Cube Detail-->
-        <div class="form-group row" ng-if="state.mode=='view'"
-             style="font-family:'Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro'">
-            <div ng-if="metaModel.model.filter_condition" class="col-md-11 col-md-offset-1">
-                <p style="color: #930f80;"><b>WHERE</b></p>
-                <span>{{metaModel.model.filter_condition}}</span>
-            </div>
-            <div ng-if="!metaModel.model.filter_condition" no-result text="No Filter."></div>
-        </div>
-    </div>
-
-    <!--Tips-->
-    <div class="col-xs-4">
-        <div class="box box-solid">
-            <div class="box-header">
-                <h4 class="box-title">Tips</h4>
-            </div>
-            <div class="box-body">
-                <div class="row">
-                    <div class="col-xs-12">
-                        <ol class="text-info">
-                            <li>Where clause to filter data from source</li>
-                            <li>Do not include date column which will be used for incremental refresh</li>
-                            <li>Do not include "Where"</li>
-                            <li>Please verify SQL when finish cube design from SQL view of cube</li>
-                        </ol>
-                    </div>
-                </div>
-            </div>
-        </div>
-    </div>
-</div>
-</div>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/cubeDesigner/info.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubeDesigner/info.html b/webapp/app/partials/cubeDesigner/info.html
index f680487..3389c4a 100644
--- a/webapp/app/partials/cubeDesigner/info.html
+++ b/webapp/app/partials/cubeDesigner/info.html
@@ -20,7 +20,7 @@
     <div class="col-xs-8">
         <ng-form name="forms.cube_info_form" novalidate>
             <!--Project-->
-            <div class="form-group required">
+            <div class="form-group" ng-class="{'required':state.mode=='edit'}">
                 <div class="row">
                   <label class="col-xs-12 col-sm-3 control-label no-padding-right">
                     <b>Model Name</b>
@@ -40,7 +40,7 @@
             </div>
 
             <!--Cube Name-->
-            <div class="form-group required">
+            <div class="form-group" ng-class="{'required':state.mode=='edit'}">
                 <div class="row">
                     <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default">
                         <b>Cube Name</b>

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/cubeDesigner/kafkaAdvancedConfig.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubeDesigner/kafkaAdvancedConfig.html b/webapp/app/partials/cubeDesigner/kafkaAdvancedConfig.html
new file mode 100644
index 0000000..c0b2b39
--- /dev/null
+++ b/webapp/app/partials/cubeDesigner/kafkaAdvancedConfig.html
@@ -0,0 +1,165 @@
+<!--
+* 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.
+-->
+
+<div ng-controller="kafkaConfigCtrl">
+  <ng-form name="forms.kafka_ad_config_form" novalidate>
+    <accordion>
+
+      <accordion-group is-open="state.isStreamingAdOpen" ng-init="state.isStreamingAdOpen=true">
+        <accordion-heading>
+          Advanced Setting
+          <i class="pull-right glyphicon"
+             ng-class="{'glyphicon-chevron-down': state.isStreamingAdOpen, 'glyphicon-chevron-right': !state.isStreamingAdOpen}"></i>
+        </accordion-heading>
+
+        <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+          <div class="row">
+            <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+              <b>Timeout</b>
+            </label>
+
+            <div class="col-xs-12 col-sm-6"
+                 ng-class="{'has-error':forms.kafka_ad_config_form.timeout.$invalid && (forms.kafka_ad_config_form.timeout.$dirty||forms.kafka_ad_config_form.timeout.$sbumitted)}">
+              <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.timeout" type="text"
+                     placeholder="Input kafkaConfig timeout"
+                     class="form-control"/>
+              <small class="help-block"
+                     ng-show="forms.kafka_ad_config_form.timeout.$error.required && (forms.kafka_ad_config_form.timeout.$dirty||forms.kafka_ad_config_form.$sbumitted)">
+                Kafka timeout is required.
+              </small>
+              <span ng-if="state.mode=='view'">{{kafkaMeta.timeout}}</span>
+            </div>
+          </div>
+        </div>
+
+        <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+          <div class="row">
+            <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+              <b>Max Read Count</b>
+            </label>
+
+            <div class="col-xs-12 col-sm-6"
+                 ng-class="{'has-error':forms.kafka_ad_config_form.maxReadCount.$invalid && (forms.kafka_ad_config_form.maxReadCount.$dirty||forms.kafka_ad_config_form.maxReadCount.$sbumitted)}">
+              <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.maxReadCount" type="text"
+                     placeholder="Input kafkaConfig maxReadCount"
+                     class="form-control"/>
+              <small class="help-block"
+                     ng-show="forms.kafka_ad_config_form.maxReadCount.$error.required && (forms.kafka_ad_config_form.maxReadCount.$dirty||forms.kafka_ad_config_form.$sbumitted)">
+                Kafka maxReadCount is required.
+              </small>
+              <span ng-if="state.mode=='view'">{{kafkaMeta.maxReadCount}}</span>
+            </div>
+          </div>
+        </div>
+
+        <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+          <div class="row">
+            <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+              <b>Buffer Size</b>
+            </label>
+
+            <div class="col-xs-12 col-sm-6"
+                 ng-class="{'has-error':forms.kafka_ad_config_form.bufferSize.$invalid && (forms.kafka_ad_config_form.bufferSize.$dirty||forms.kafka_ad_config_form.bufferSize.$sbumitted)}">
+              <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.bufferSize" type="text"
+                     placeholder="Input kafkaConfig bufferSize"
+                     class="form-control"/>
+              <small class="help-block"
+                     ng-show="forms.kafka_ad_config_form.bufferSize.$error.required && (forms.kafka_ad_config_form.bufferSize.$dirty||forms.kafka_ad_config_form.$sbumitted)">
+                Kafka bufferSize is required.
+              </small>
+              <span ng-if="state.mode=='view'">{{kafkaMeta.bufferSize}}</span>
+            </div>
+          </div>
+        </div>
+
+        <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+          <div class="row">
+            <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+              <b>Margin</b>
+            </label>
+
+            <div class="col-xs-12 col-sm-6"
+                 ng-class="{'has-error':forms.kafka_ad_config_form.margin.$invalid && (forms.kafka_ad_config_form.margin.$dirty||forms.kafka_ad_config_form.margin.$sbumitted)}">
+              <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.margin" type="text"
+                     placeholder="Input kafkaConfig margin"
+                     class="form-control"/>
+              <small class="help-block"
+                     ng-show="forms.kafka_ad_config_form.margin.$error.required && (forms.kafka_ad_config_form.margin.$dirty||forms.kafka_ad_config_form.$sbumitted)">
+                Kafka margin is required.
+              </small>
+              <span ng-if="state.mode=='view'">{{kafkaMeta.margin}}</span>
+            </div>
+          </div>
+        </div>
+      </accordion-group>
+    </accordion>
+
+    <hr/>
+    <accordion>
+
+      <accordion-group is-open="state.isParserHeaderOpen">
+        <accordion-heading>
+          Parser Setting
+          <i class="pull-right glyphicon"
+             ng-class="{'glyphicon-chevron-down': state.isParserHeaderOpen, 'glyphicon-chevron-right': !state.isParserHeaderOpen}"></i>
+        </accordion-heading>
+
+        <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+          <div class="row">
+            <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+              <b>Parser Name</b>
+            </label>
+
+            <div class="col-xs-12 col-sm-6"
+                 ng-class="{'has-error':forms.kafka_ad_config_form.parserName.$invalid && (forms.kafka_ad_config_form.parserName.$dirty||forms.kafka_ad_config_form.parserName.$sbumitted)}">
+              <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.parserName" type="text"
+                     placeholder="Input kafkaConfig parserName"
+                     class="form-control"/>
+              <small class="help-block"
+                     ng-show="forms.kafka_ad_config_form.parserName.$error.required && (forms.kafka_ad_config_form.parserName.$dirty||forms.kafka_ad_config_form.$sbumitted)">
+                Kafka parserName is required.
+              </small>
+              <span ng-if="state.mode=='view'">{{kafkaMeta.parserName}}</span>
+            </div>
+          </div>
+        </div>
+
+        <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+          <div class="row">
+            <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+              <b>Parser Properties</b>
+            </label>
+
+            <div class="col-xs-12 col-sm-6"
+                 ng-class="{'has-error':forms.kafka_ad_config_form.parserProperties.$invalid && (forms.kafka_ad_config_form.parserProperties.$dirty||forms.kafka_ad_config_form.parserProperties.$sbumitted)}">
+              <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.parserProperties" type="text"
+                     placeholder="configA=1;configB=2"
+                     class="form-control"/>
+              <small class="help-block"
+                     ng-show="forms.kafka_ad_config_form.parserProperties.$error.required && (forms.kafka_ad_config_form.parserProperties.$dirty||forms.kafka_ad_config_form.$sbumitted)">
+                Parser Properties is required.
+              </small>
+              <span ng-if="state.mode=='view'">{{kafkaMeta.parserProperties}}</span>
+            </div>
+          </div>
+        </div>
+      </accordion-group>
+    </accordion>
+
+  </ng-form>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/cubeDesigner/kafkaBasicConfig.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubeDesigner/kafkaBasicConfig.html b/webapp/app/partials/cubeDesigner/kafkaBasicConfig.html
new file mode 100644
index 0000000..d9ca5b1
--- /dev/null
+++ b/webapp/app/partials/cubeDesigner/kafkaBasicConfig.html
@@ -0,0 +1,114 @@
+<!--
+* 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.
+-->
+
+<div ng-controller="kafkaConfigCtrl">
+  <ng-form name="forms.kafka_config_form" novalidate>
+    <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+      <div class="row">
+        <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+          <b>Topic</b>
+        </label>
+        <div class="col-xs-12 col-sm-6"   ng-class="{'has-error':forms.kafka_config_form.topic.$invalid && (forms.kafka_config_form.topic.$dirty||forms.kafka_config_form.topic.$sbumitted)}">
+          <input  ng-if="state.mode=='edit'"  name="name" required ng-model="kafkaMeta.topic" type="text"
+                  placeholder="Input kafkaConfig topic"
+                  class="form-control"/>
+          <small class="help-block" ng-show="forms.kafka_config_form.topic.$error.required && (forms.kafka_config_form.topic.$dirty||forms.kafka_config_form.$sbumitted)">Kafka topic is required.</small>
+          <span ng-if="state.mode=='view'">{{kafkaMeta.topic}}</span>
+        </div>
+      </div>
+    </div>
+
+
+
+
+    <div ng-repeat="cluster in kafkaMeta.clusters | filter: state.measureFilter track by $index" class="box">
+      <div class="box-header">
+        <h3 class="box-title">Cluster-{{$index+1}}</h3>
+        <button type="button" ng-click="removeCluster(cluster)" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
+      </div>
+      <div class="box-body no-padding">
+        <table class="table table-condensed" ng-if="cluster.brokers.length||cluster.newBroker">
+          <thead>
+          <tr>
+            <th>ID</th>
+            <th>Host</th>
+            <th>Port</th>
+            <th ng-if="state.mode=='edit'">Actions</th>
+          </tr>
+          </thead>
+          <tbody>
+          <tr ng-repeat="broker in cluster.brokers| filter: state.measureFilter track by $index">
+            <td>{{broker.id}}</td>
+            <td>{{broker.host}}</td>
+            <td>{{broker.port}}</td>
+            <td ng-if="state.mode=='edit'">
+              <!--Edit Button -->
+              <button class="btn btn-xs btn-info" ng-click="addBroker(cluster,broker)">
+                <i class="fa fa-pencil"></i>
+              </button>
+
+              <button class="btn btn-xs btn-danger" ng-click="removeElement(cluster,broker)"><i class="fa fa-trash-o"></i>
+              </button>
+            </td>
+          </tr>
+          <tr ng-if="cluster.newBroker">
+            <td>
+              <div class="input-group">
+                <input class="form-control" type="text" ng-model="cluster.newBroker.id" name="broker_id" placeholder="Input broker ID"/>
+              </div>
+            </td>
+            <td>
+              <div class="input-group">
+                <input class="form-control" type="text" ng-model="cluster.newBroker.host" name="broker_host" placeholder="Input broker host">
+              </div>
+            </td>
+            <td>
+              <div class="input-group">
+                <input class="form-control" type="text" ng-model="cluster.newBroker.port" name="broker_port" placeholder="Input broker port">
+              </div>
+            </td>
+            <td>
+              <button class="btn btn-xs btn-danger" ng-click="removeNewBroker(cluster)"><i class="fa fa-trash-o"></i>
+              </button>
+            </td>
+          </tr>
+          </tbody>
+        </table>
+      </div>
+      <div class="box-footer">
+        <div>
+          <button class="btn btn-sm btn-success" ng-click="addBroker(cluster)" ng-show="state.mode=='edit'&&!cluster.newBroker">
+            <i class="fa fa-plus"></i> Broker
+          </button>
+          <button class="btn btn-sm btn-info" ng-click="saveNewBroker(cluster)" ng-show="state.mode=='edit'&&cluster.newBroker">
+            <i class="fa fa-saved"></i> Save
+          </button>
+          <button class="btn btn-link" ng-click="clearNewBroker(cluster)"  ng-show="state.mode=='edit'&&cluster.newBroker">Cancel</button>
+        </div>
+      </div>
+    </div>
+    <!--Add Measures Button-->
+    <div class="form-group">
+      <button class="btn btn-sm btn-info" ng-click="addCluster()" ng-show="state.mode=='edit'">
+        <i class="fa fa-plus"></i> Cluster
+      </button>
+    </div>
+
+
+  </ng-form>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/cubeDesigner/measures.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubeDesigner/measures.html b/webapp/app/partials/cubeDesigner/measures.html
index e4962dc..ece2b7d 100755
--- a/webapp/app/partials/cubeDesigner/measures.html
+++ b/webapp/app/partials/cubeDesigner/measures.html
@@ -17,186 +17,188 @@
 -->
 
 <!-- Measures Summary -->
-<ng-form name="forms.cube_measure_form">
-    <div class="dataTables_wrapper form-inline no-footer" ng-if="cubeMetaFrame.measures.length > 0">
-            <table class="table table-striped table-hover">
-                <thead>
-                    <tr>
-                        <th>ID</th>
-                        <th>Name</th>
-                        <th>Expression</th>
-                        <th>Param Type</th>
-                        <th>Param Value</th>
-                        <th>Return Type</th>
-                        <th ng-if="state.mode=='edit'">Actions</th>
-                    </tr>
-                </thead>
-                <tbody>
-                    <tr ng-repeat="measure in cubeMetaFrame.measures | filter: state.measureFilter track by $index">
-                        <td>
-                            <!--ID -->
-                            <b>{{measure.id = ($index + 1)}}</b>
-                        </td>
-                        <td>
-                            <!--Name -->
-                            <span tooltip="measure name..">{{measure.name}}</span>
-                        </td>
-                        <td>
-                            <!--Expression -->
-                            <span>{{measure.function.expression}}</span>
-                        </td>
-                        <td>
-                            <!--Param Type -->
-                            <span>{{measure.function.parameter.type}}</span>
-                        </td>
-                        <td>
-                            <!--Param Value -->
-                            <span>{{measure.function.parameter.value}}</span>
-                        </td>
-                        <td>
-                            <!--Return Type -->
-                            <span>{{measure.function.returntype}}</span>
-                        </td>
-                        <td ng-if="state.mode=='edit'">
-                            <!--Edit Button -->
-                            <button class="btn btn-xs btn-info" ng-click="addNewMeasure(measure)">
-                                <i class="fa fa-pencil"></i>
-                            </button>
-                            <!--Remove Button -->
-                            <button class="btn btn-xs  btn-danger" ng-click="removeElement(cubeMetaFrame.measures, measure)">
-                                <i class="fa fa-trash-o"></i>
-                            </button>
-                        </td>
-                    </tr>
-                </tbody>
-            </table>
-    </div>
-</ng-form>
+<div ng-controller="CubeMeasuresCtrl">
+  <ng-form name="forms.cube_measure_form">
+      <div class="dataTables_wrapper form-inline no-footer" ng-if="cubeMetaFrame.measures.length > 0">
+              <table class="table table-striped table-hover">
+                  <thead>
+                      <tr>
+                          <th>ID</th>
+                          <th>Name</th>
+                          <th>Expression</th>
+                          <th>Param Type</th>
+                          <th>Param Value</th>
+                          <th>Return Type</th>
+                          <th ng-if="state.mode=='edit'">Actions</th>
+                      </tr>
+                  </thead>
+                  <tbody>
+                      <tr ng-repeat="measure in cubeMetaFrame.measures | filter: state.measureFilter track by $index">
+                          <td>
+                              <!--ID -->
+                              <b>{{measure.id = ($index + 1)}}</b>
+                          </td>
+                          <td>
+                              <!--Name -->
+                              <span tooltip="measure name..">{{measure.name}}</span>
+                          </td>
+                          <td>
+                              <!--Expression -->
+                              <span>{{measure.function.expression}}</span>
+                          </td>
+                          <td>
+                              <!--Param Type -->
+                              <span>{{measure.function.parameter.type}}</span>
+                          </td>
+                          <td>
+                              <!--Param Value -->
+                              <span>{{measure.function.parameter.value}}</span>
+                          </td>
+                          <td>
+                              <!--Return Type -->
+                              <span>{{measure.function.returntype}}</span>
+                          </td>
+                          <td ng-if="state.mode=='edit'">
+                              <!--Edit Button -->
+                              <button class="btn btn-xs btn-info" ng-click="addNewMeasure(measure)">
+                                  <i class="fa fa-pencil"></i>
+                              </button>
+                              <!--Remove Button -->
+                              <button class="btn btn-xs  btn-danger" ng-click="removeElement(cubeMetaFrame.measures, measure)">
+                                  <i class="fa fa-trash-o"></i>
+                              </button>
+                          </td>
+                      </tr>
+                  </tbody>
+              </table>
+      </div>
+  </ng-form>
 
-<!--Add Measures Button-->
-<div class="form-group">
-    <button class="btn btn-sm btn-info" ng-click="addNewMeasure()" ng-show="state.mode=='edit' && !newMeasure">
-        <i class="fa fa-plus"></i> Measure
-    </button>
-</div>
+  <!--Add Measures Button-->
+  <div class="form-group">
+      <button class="btn btn-sm btn-info" ng-click="addNewMeasure()" ng-show="state.mode=='edit' && !newMeasure">
+          <i class="fa fa-plus"></i> Measure
+      </button>
+  </div>
 
-<!--Edit Measure-->
-<ng-form name="edit_mes_form">
-<div class="box box-solid" ng-if="newMeasure">
-    <div class="box-header">
-        <h4 class="box-title text-info">Edit Measure</h4>
-    </div>
-    <div class="box-body">
-        <div class="row">
-            <div class="col-xs-8">
-                    <!--Name-->
-                    <div class="form-group">
-                        <div class="row">
-                            <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Name</b></label>
-                            <div class="col-xs-12 col-sm-6">
-                                <input type="text" placeholder="Name.." class="form-control"
-                                    tooltip="measure name.." tooltip-trigger="focus"
-                                    ng-model="newMeasure.name" required />
-                            </div>
-                        </div>
-                    </div>
-                    <!--Expression-->
-                    <div class="form-group">
-                        <div class="row">
-                            <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Expression</b></label>
-                            <div class="col-xs-12 col-sm-6">
-                                <select class="form-control"
-                                    ng-init="newMeasure.function.expression = (!!newMeasure.function.expression)?newMeasure.function.expression:cubeConfig.dftSelections.measureExpression" chosen ng-model="newMeasure.function.expression" required
-                                    ng-change="measureReturnTypeUpdate();"
-                                    ng-options="me as me for me in cubeConfig.measureExpressions">
-                                    <option value=""></option>
-                                </select>
-                            </div>
-                        </div>
-                    </div>
-                    <!--Param Type-->
-                    <div class="form-group">
-                        <div class="row">
-                            <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Param Type</b></label>
-                            <div class="col-xs-12 col-sm-6">
-                                <select class="form-control" ng-if="newMeasure.function.expression != 'COUNT'"
-                                    ng-init="newMeasure.function.parameter.type=(!!newMeasure.function.parameter.type)?newMeasure.function.parameter.type: 'column' "
-                                    chosen ng-model="newMeasure.function.parameter.type" required
-                                    ng-change="measureReturnTypeUpdate();"
-                                    ng-options="mpt as mpt for mpt in cubeConfig.measureParamType">
-                                    <option value=""></option>
-                                </select>
-                                <span class="font-color-default"
-                                       ng-if="newMeasure.function.expression == 'COUNT'"
-                                       ng-init="newMeasure.function.parameter.type= 'constant' "><b>&nbsp;&nbsp;constant</b>
-                                </span>
-                            </div>
-                        </div>
-                    </div>
-                    <!--Param Value-->
-                    <div class="form-group">
-                        <div class="row">
-                            <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Param Value</b></label>
-                            <div class="col-xs-12 col-sm-6">
-                                <span class="font-color-default"
-                                    ng-if="newMeasure.function.parameter.type == 'constant'"
-                                    ng-init="newMeasure.function.parameter.value = 1"><b>&nbsp;&nbsp;1</b></span>
-                                <select class="form-control" chosen
-                                    ng-if="newMeasure.function.parameter.type == 'column'"
-                                    ng-model="newMeasure.function.parameter.value"
-                                    ng-change="measureReturnTypeUpdate();"
-                                    ng-options="columns.name as columns.name for columns in getMetricColumnsByTable(metaModel.model.fact_table)" >
-                                    <option value="">-- Select a Fact Table Column --</option>
-                                </select>
-                            </div>
-                        </div>
-                    </div>
-                    <!--Return Type-->
-                    <div class="form-group">
-                        <div class="row">
-                            <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Return Type</b></label>
-                            <div class="col-xs-12 col-sm-6">
-                                <select class="form-control"
-                                    ng-if="newMeasure.function.expression == 'COUNT_DISTINCT'"
-                                    ng-init="newMeasure.function.returntype = (!!newMeasure.function.returntype)?newMeasure.function.returntype:cubeConfig.dftSelections.distinctDataType.value"
-                                    chosen ng-model="newMeasure.function.returntype" required
-                                    ng-options="ddt.value as ddt.name for ddt in cubeConfig.distinctDataTypes">
-                                    <option value=""></option>
-                                </select>
-                                <span class="font-color-default"
-                                      ng-if="newMeasure.function.expression != 'COUNT_DISTINCT'"
-                                     ><b>&nbsp;&nbsp;{{newMeasure.function.returntype | uppercase}}</b>
-                                </span>
-                            </div>
-                        </div>
-                    </div>
-            </div>
+  <!--Edit Measure-->
+  <ng-form name="edit_mes_form">
+  <div class="box box-solid" ng-if="newMeasure">
+      <div class="box-header">
+          <h4 class="box-title text-info">Edit Measure</h4>
+      </div>
+      <div class="box-body">
+          <div class="row">
+              <div class="col-xs-8">
+                      <!--Name-->
+                      <div class="form-group">
+                          <div class="row">
+                              <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Name</b></label>
+                              <div class="col-xs-12 col-sm-6">
+                                  <input type="text" placeholder="Name.." class="form-control"
+                                      tooltip="measure name.." tooltip-trigger="focus"
+                                      ng-model="newMeasure.name" required />
+                              </div>
+                          </div>
+                      </div>
+                      <!--Expression-->
+                      <div class="form-group">
+                          <div class="row">
+                              <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Expression</b></label>
+                              <div class="col-xs-12 col-sm-6">
+                                  <select class="form-control"
+                                      ng-init="newMeasure.function.expression = (!!newMeasure.function.expression)?newMeasure.function.expression:cubeConfig.dftSelections.measureExpression" chosen ng-model="newMeasure.function.expression" required
+                                      ng-change="measureReturnTypeUpdate();"
+                                      ng-options="me as me for me in cubeConfig.measureExpressions">
+                                      <option value=""></option>
+                                  </select>
+                              </div>
+                          </div>
+                      </div>
+                      <!--Param Type-->
+                      <div class="form-group">
+                          <div class="row">
+                              <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Param Type</b></label>
+                              <div class="col-xs-12 col-sm-6">
+                                  <select class="form-control" ng-if="newMeasure.function.expression != 'COUNT'"
+                                      ng-init="newMeasure.function.parameter.type=(!!newMeasure.function.parameter.type)?newMeasure.function.parameter.type: 'column' "
+                                      chosen ng-model="newMeasure.function.parameter.type" required
+                                      ng-change="measureReturnTypeUpdate();"
+                                      ng-options="mpt as mpt for mpt in cubeConfig.measureParamType">
+                                      <option value=""></option>
+                                  </select>
+                                  <span class="font-color-default"
+                                         ng-if="newMeasure.function.expression == 'COUNT'"
+                                         ng-init="newMeasure.function.parameter.type= 'constant' "><b>&nbsp;&nbsp;constant</b>
+                                  </span>
+                              </div>
+                          </div>
+                      </div>
+                      <!--Param Value-->
+                      <div class="form-group">
+                          <div class="row">
+                              <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Param Value</b></label>
+                              <div class="col-xs-12 col-sm-6">
+                                  <span class="font-color-default"
+                                      ng-if="newMeasure.function.parameter.type == 'constant'"
+                                      ng-init="newMeasure.function.parameter.value = 1"><b>&nbsp;&nbsp;1</b></span>
+                                  <select class="form-control" chosen
+                                      ng-if="newMeasure.function.parameter.type == 'column'"
+                                      ng-model="newMeasure.function.parameter.value"
+                                      ng-change="measureReturnTypeUpdate();"
+                                      ng-options="columns.name as columns.name for columns in getMetricColumnsByTable(metaModel.model.fact_table)" >
+                                      <option value="">-- Select a Fact Table Column --</option>
+                                  </select>
+                              </div>
+                          </div>
+                      </div>
+                      <!--Return Type-->
+                      <div class="form-group">
+                          <div class="row">
+                              <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default"><b>Return Type</b></label>
+                              <div class="col-xs-12 col-sm-6">
+                                  <select class="form-control"
+                                      ng-if="newMeasure.function.expression == 'COUNT_DISTINCT'"
+                                      ng-init="newMeasure.function.returntype = (!!newMeasure.function.returntype)?newMeasure.function.returntype:cubeConfig.dftSelections.distinctDataType.value"
+                                      chosen ng-model="newMeasure.function.returntype" required
+                                      ng-options="ddt.value as ddt.name for ddt in cubeConfig.distinctDataTypes">
+                                      <option value=""></option>
+                                  </select>
+                                  <span class="font-color-default"
+                                        ng-if="newMeasure.function.expression != 'COUNT_DISTINCT'"
+                                       ><b>&nbsp;&nbsp;{{newMeasure.function.returntype | uppercase}}</b>
+                                  </span>
+                              </div>
+                          </div>
+                      </div>
+              </div>
 
-            <!--Tips-->
-            <div class="col-xs-4">
-                <div class="box box-solid">
-                    <div class="box-header">
-                        <h4 class="box-title">Tips</h4>
-                    </div>
-                    <div class="box-body">
-                        <div class="row">
-                            <div class="col-xs-12">
-                                <ol class="text-info">
-                                    <li>All cubes have to contain one measure for Count(1), suggest use "_Count_" as name (Has been generated automatically)</li>
-                                    <li>Only accept single column in param value with "Column" type</li>
-                                    <li>Distinct Count is approximate, please indicate Error Rate, higher accuracy degree accompanied with larger storage size and longer build time</li>
-                                </ol>
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-    </div>
-    <div class="box-footer">
-        <button class="btn btn-sm btn-info" ng-disabled="edit_mes_form.$invalid"
-                ng-click="saveNewMeasure()" ng-show="state.mode=='edit'">OK</button>
-        <button class="btn btn-link" ng-click="clearNewMeasure()">Cancel</button>
-    </div>
+              <!--Tips-->
+              <div class="col-xs-4">
+                  <div class="box box-solid">
+                      <div class="box-header">
+                          <h4 class="box-title">Tips</h4>
+                      </div>
+                      <div class="box-body">
+                          <div class="row">
+                              <div class="col-xs-12">
+                                  <ol class="text-info">
+                                      <li>All cubes have to contain one measure for Count(1), suggest use "_Count_" as name (Has been generated automatically)</li>
+                                      <li>Only accept single column in param value with "Column" type</li>
+                                      <li>Distinct Count is approximate, please indicate Error Rate, higher accuracy degree accompanied with larger storage size and longer build time</li>
+                                  </ol>
+                              </div>
+                          </div>
+                      </div>
+                  </div>
+              </div>
+          </div>
+      </div>
+      <div class="box-footer">
+          <button class="btn btn-sm btn-info" ng-disabled="edit_mes_form.$invalid"
+                  ng-click="saveNewMeasure()" ng-show="state.mode=='edit'">OK</button>
+          <button class="btn btn-link" ng-click="clearNewMeasure()">Cancel</button>
+      </div>
+  </div>
+  </ng-form>
 </div>
-</ng-form>

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/cubeDesigner/streamingConfig.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubeDesigner/streamingConfig.html b/webapp/app/partials/cubeDesigner/streamingConfig.html
new file mode 100644
index 0000000..f8ab61d
--- /dev/null
+++ b/webapp/app/partials/cubeDesigner/streamingConfig.html
@@ -0,0 +1,282 @@
+<!--
+* 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.
+-->
+
+<div ng-controller="streamingConfigCtrl">
+  <ng-form name="forms.cube_streaming_form" novalidate>
+    <div class="form-group">
+      <div class="row">
+        <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default">
+          <b>Is this cube for streaming use?</b>
+        </label>
+        <div class="col-xs-12 col-sm-6" ng-if="state.mode=='edit'" >
+          <toggle-switch ng-model="cubeState.isStreaming" on-label="YES" off-label="NO"> <toggle-switch>
+        </div>
+        <div class="col-xs-12 col-sm-6" ng-if="state.mode=='view'" >
+            <span>{{(!!cubeState.isStreaming)?'YES':'NO'}}</span>
+        </div>
+      </div>
+    </div>
+{{}}
+
+    <div ng-if="cubeState.isStreaming">
+      <accordion>
+        <accordion-group is-open="state.isKfkSettingOpen" ng-init="state.isKfkSettingOpen=true">
+          <accordion-heading>
+            Kafka Setting
+            <i class="pull-right glyphicon"
+               ng-class="{'glyphicon-chevron-down': state.isKfkSettingOpen, 'glyphicon-chevron-right': !state.isKfkSettingOpen}"></i>
+          </accordion-heading>
+
+          <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+        <div class="row">
+          <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+            <b>Topic</b>
+          </label>
+          <div class="col-xs-12 col-sm-6"   ng-class="{'has-error':forms.cube_streaming_form.topic.$invalid && (forms.cube_streaming_form.topic.$dirty||forms.cube_streaming_form.topic.$sbumitted)}">
+            <input  ng-if="state.mode=='edit'"  name="topic" required ng-model="kafkaMeta.topic" type="text"
+                    placeholder="Input kafkaConfig topic"
+                    class="form-control"/>
+            <small class="help-block" ng-show="forms.cube_streaming_form.topic.$error.required && (forms.cube_streaming_form.topic.$dirty||forms.cube_streaming_form.$sbumitted)">Kafka topic is required.</small>
+            <span ng-if="state.mode=='view'">{{kafkaMeta.topic}}</span>
+          </div>
+        </div>
+      </div>
+
+      <div ng-repeat="cluster in kafkaMeta.clusters | filter: state.measureFilter track by $index" class="box">
+        <div class="box-header">
+          <h3 class="box-title">Cluster-{{$index+1}}</h3>
+          <button ng-if="state.mode=='edit'" type="button" ng-click="removeCluster(cluster)" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
+        </div>
+        <div class="box-body no-padding">
+          <table class="table table-condensed" ng-if="cluster.brokers.length||cluster.newBroker">
+            <thead>
+            <tr>
+              <th>ID</th>
+              <th>Host</th>
+              <th>Port</th>
+              <th ng-if="state.mode=='edit'">Actions</th>
+            </tr>
+            </thead>
+            <tbody>
+            <tr ng-repeat="broker in cluster.brokers| filter: state.measureFilter track by $index">
+              <td>{{broker.id}}</td>
+              <td>{{broker.host}}</td>
+              <td>{{broker.port}}</td>
+              <td ng-if="state.mode=='edit'">
+                <!--Edit Button -->
+                <button class="btn btn-xs btn-info" ng-click="addBroker(cluster,broker)">
+                  <i class="fa fa-pencil"></i>
+                </button>
+
+                <button class="btn btn-xs btn-danger" ng-click="removeElement(cluster,broker)"><i class="fa fa-trash-o"></i>
+                </button>
+              </td>
+            </tr>
+            <tr ng-if="cluster.newBroker">
+              <td>
+                <div class="input-group">
+                  <input class="form-control" type="text" ng-model="cluster.newBroker.id" name="broker_id" placeholder="Input broker ID"/>
+                </div>
+              </td>
+              <td>
+                <div class="input-group">
+                  <input class="form-control" type="text" ng-model="cluster.newBroker.host" name="broker_host" placeholder="Input broker host">
+                </div>
+              </td>
+              <td>
+                <div class="input-group">
+                  <input class="form-control" type="text" ng-model="cluster.newBroker.port" name="broker_port" placeholder="Input broker port">
+                </div>
+              </td>
+              <td>
+                <button class="btn btn-xs btn-danger" ng-click="removeNewBroker(cluster)"><i class="fa fa-trash-o"></i>
+                </button>
+              </td>
+            </tr>
+            </tbody>
+          </table>
+        </div>
+        <div class="box-footer">
+          <div>
+            <button class="btn btn-sm btn-success" ng-click="addBroker(cluster)" ng-show="state.mode=='edit'&&!cluster.newBroker">
+              <i class="fa fa-plus"></i> Broker
+            </button>
+            <button class="btn btn-sm btn-info" ng-click="saveNewBroker(cluster)" ng-show="state.mode=='edit'&&cluster.newBroker">
+              <i class="fa fa-saved"></i> Save
+            </button>
+            <button class="btn btn-link" ng-click="clearNewBroker(cluster)"  ng-show="state.mode=='edit'&&cluster.newBroker">Cancel</button>
+          </div>
+        </div>
+      </div>
+      <!--Add Measures Button-->
+      <div class="form-group">
+        <button class="btn btn-sm btn-info" ng-click="addCluster()" ng-show="state.mode=='edit'">
+          <i class="fa fa-plus"></i> Cluster
+        </button>
+      </div>
+
+          </accordion-group>
+        </accordion>
+
+      <hr/>
+      <!--Advanced setting-->
+      <accordion>
+        <accordion-group is-open="state.isStreamingAdOpen" ng-init="state.isStreamingAdOpen=true">
+          <accordion-heading>
+            Advanced Setting
+            <i class="pull-right glyphicon"
+               ng-class="{'glyphicon-chevron-down': state.isStreamingAdOpen, 'glyphicon-chevron-right': !state.isStreamingAdOpen}"></i>
+          </accordion-heading>
+
+          <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+            <div class="row">
+              <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+                <b>Timeout</b>
+              </label>
+
+              <div class="col-xs-12 col-sm-6"
+                   ng-class="{'has-error':forms.cube_streaming_form.timeout.$invalid && (forms.cube_streaming_form.timeout.$dirty||forms.cube_streaming_form.timeout.$sbumitted)}">
+                <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.timeout" type="text"
+                       placeholder="Input kafkaConfig timeout"
+                       class="form-control"/>
+                <small class="help-block"
+                       ng-show="forms.cube_streaming_form.timeout.$error.required && (forms.cube_streaming_form.timeout.$dirty||forms.cube_streaming_form.$sbumitted)">
+                  Kafka timeout is required.
+                </small>
+                <span ng-if="state.mode=='view'">{{kafkaMeta.timeout}}</span>
+              </div>
+            </div>
+          </div>
+
+          <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+            <div class="row">
+              <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+                <b>Max Read Count</b>
+              </label>
+
+              <div class="col-xs-12 col-sm-6"
+                   ng-class="{'has-error':forms.cube_streaming_form.maxReadCount.$invalid && (forms.cube_streaming_form.maxReadCount.$dirty||forms.cube_streaming_form.maxReadCount.$sbumitted)}">
+                <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.maxReadCount" type="text"
+                       placeholder="Input kafkaConfig maxReadCount"
+                       class="form-control"/>
+                <small class="help-block"
+                       ng-show="forms.cube_streaming_form.maxReadCount.$error.required && (forms.cube_streaming_form.maxReadCount.$dirty||forms.cube_streaming_form.$sbumitted)">
+                  Kafka maxReadCount is required.
+                </small>
+                <span ng-if="state.mode=='view'">{{kafkaMeta.maxReadCount}}</span>
+              </div>
+            </div>
+          </div>
+
+          <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+            <div class="row">
+              <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+                <b>Buffer Size</b>
+              </label>
+
+              <div class="col-xs-12 col-sm-6"
+                   ng-class="{'has-error':forms.cube_streaming_form.bufferSize.$invalid && (forms.cube_streaming_form.bufferSize.$dirty||forms.cube_streaming_form.bufferSize.$sbumitted)}">
+                <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.bufferSize" type="text"
+                       placeholder="Input kafkaConfig bufferSize"
+                       class="form-control"/>
+                <small class="help-block"
+                       ng-show="forms.cube_streaming_form.bufferSize.$error.required && (forms.cube_streaming_form.bufferSize.$dirty||forms.cube_streaming_form.$sbumitted)">
+                  Kafka bufferSize is required.
+                </small>
+                <span ng-if="state.mode=='view'">{{kafkaMeta.bufferSize}}</span>
+              </div>
+            </div>
+          </div>
+
+          <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+            <div class="row">
+              <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+                <b>Margin</b>
+              </label>
+
+              <div class="col-xs-12 col-sm-6"
+                   ng-class="{'has-error':forms.cube_streaming_form.margin.$invalid && (forms.cube_streaming_form.margin.$dirty||forms.cube_streaming_form.margin.$sbumitted)}">
+                <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.margin" type="text"
+                       placeholder="Input kafkaConfig margin"
+                       class="form-control"/>
+                <small class="help-block"
+                       ng-show="forms.cube_streaming_form.margin.$error.required && (forms.cube_streaming_form.margin.$dirty||forms.cube_streaming_form.$sbumitted)">
+                  Kafka margin is required.
+                </small>
+                <span ng-if="state.mode=='view'">{{kafkaMeta.margin}}</span>
+              </div>
+            </div>
+          </div>
+        </accordion-group>
+      </accordion>
+
+      <hr/>
+      <accordion>
+
+        <accordion-group is-open="state.isParserHeaderOpen">
+          <accordion-heading>
+            Parser Setting
+            <i class="pull-right glyphicon"
+               ng-class="{'glyphicon-chevron-down': state.isParserHeaderOpen, 'glyphicon-chevron-right': !state.isParserHeaderOpen}"></i>
+          </accordion-heading>
+
+          <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+            <div class="row">
+              <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+                <b>Parser Name</b>
+              </label>
+
+              <div class="col-xs-12 col-sm-6"
+                   ng-class="{'has-error':forms.cube_streaming_form.parserName.$invalid && (forms.cube_streaming_form.parserName.$dirty||forms.cube_streaming_form.parserName.$sbumitted)}">
+                <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.parserName" type="text"
+                       placeholder="Input kafkaConfig parserName"
+                       class="form-control"/>
+                <small class="help-block"
+                       ng-show="forms.cube_streaming_form.parserName.$error.required && (forms.cube_streaming_form.parserName.$dirty||forms.cube_streaming_form.$sbumitted)">
+                  Kafka parserName is required.
+                </small>
+                <span ng-if="state.mode=='view'">{{kafkaMeta.parserName}}</span>
+              </div>
+            </div>
+          </div>
+
+          <div class="form-group" ng-class="{'required':state.mode=='edit'}">
+            <div class="row">
+              <label class="col-xs-12 col-sm-3 control-label no-padding-right">
+                <b>Parser Properties</b>
+              </label>
+
+              <div class="col-xs-12 col-sm-6"
+                   ng-class="{'has-error':forms.cube_streaming_form.parserProperties.$invalid && (forms.cube_streaming_form.parserProperties.$dirty||forms.cube_streaming_form.parserProperties.$sbumitted)}">
+                <input ng-if="state.mode=='edit'" name="name" required ng-model="kafkaMeta.parserProperties" type="text"
+                       placeholder="configA=1;configB=2"
+                       class="form-control"/>
+                <small class="help-block"
+                       ng-show="forms.cube_streaming_form.parserProperties.$error.required && (forms.cube_streaming_form.parserProperties.$dirty||forms.cube_streaming_form.$sbumitted)">
+                  Parser Properties is required.
+                </small>
+                <span ng-if="state.mode=='view'">{{kafkaMeta.parserProperties}}</span>
+              </div>
+            </div>
+          </div>
+        </accordion-group>
+      </accordion>
+
+    </div>
+  </ng-form>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/cubes/cube_detail.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubes/cube_detail.html b/webapp/app/partials/cubes/cube_detail.html
index 48a22d7..49e2578 100755
--- a/webapp/app/partials/cubes/cube_detail.html
+++ b/webapp/app/partials/cubes/cube_detail.html
@@ -46,19 +46,17 @@
             ng-if="userService.hasRole('ROLE_ADMIN')">
             <a href="" ng-click="cube.visiblePage='hbase';getHbaseInfo(cube)">HBase</a>
         </li>
-
     </ul>
 
     <div class="cube-detail" ng-if="!cube.visiblePage || cube.visiblePage=='metadata'">
         <div ng-include="'partials/cubes/cube_schema.html'" ng-controller="CubeSchemaCtrl"
-             ng-init="state={mode:'view', cubeName:cube.name}"></div>
+             ng-init="state={mode:'view', cubeName:cube.name};cubeState={isStreaming:(!!cube.streaming)?true:false}"></div>
     </div>
 
     <div ng-show="cube.visiblePage=='sql'" class="cube-detail">
         <div ng-if="cube.sql">
             <pre style="background-color: white;border: 0px">{{cube.sql}}</pre>
         </div>
-
         <div ng-if="!cube.sql">
             <span calss="text-info">No SQL GENERATED.</span>
         </div>
@@ -101,7 +99,7 @@
         </div>
     </div>
 
-    <div class="cube-detail" ng-show="cube.visiblePage=='hbase'">
+  <div class="cube-detail" ng-show="cube.visiblePage=='hbase'">
         <div style="margin: 15px;">
             <div ng-repeat="table in cube.hbase">
                 <h5><b>HTable:</b> {{table.tableName}}</h5>
@@ -115,10 +113,12 @@
             <div ng-if="cube.hbase">
                 <div class="hr hr8 hr-double hr-dotted"></div>
                 <h5><b>Total Size:</b> <span class="red">{{cube.totalSize | bytes:2}}</span></h5>
+                <h5><b>Total Number:</b> <span class="red">{{cube.hbase.length}}</span></h5>
             </div>
             <div ng-if="cube.hbase.length == 0">
                 <h5>No HBase Info.</h5>
             </div>
         </div>
     </div>
-</div>
+  </div>
+

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/cubes/cubes.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/cubes/cubes.html b/webapp/app/partials/cubes/cubes.html
index 3c8c2e7..fdf3277 100644
--- a/webapp/app/partials/cubes/cubes.html
+++ b/webapp/app/partials/cubes/cubes.html
@@ -45,6 +45,7 @@
             </th>
             <th>Actions</th>
             <th ng-if="userService.hasRole('ROLE_ADMIN')">Admins</th>
+            <th></th>
         </tr>
         </thead>
         <!--Body-->
@@ -83,6 +84,7 @@
                             <a ng-click="dropCube(cube)" tooltip="Drop the cube, related jobs and data permanently.">Drop</a></li>
                         <li ng-if="cube.status=='DISABLED' && (userService.hasRole('ROLE_ADMIN') || hasPermission(cube, permissions.ADMINISTRATION.mask, permissions.MANAGEMENT.mask))">
                             <a ng-click="cubeEdit(cube);">Edit</a></li>
+                      <li ng-if="cube.streaming && cube.status=='DISABLED' && (userService.hasRole('ROLE_ADMIN') || hasPermission(cube, permissions.ADMINISTRATION.mask, permissions.MANAGEMENT.mask))">
                         <li><a ng-click="startJobSubmit(cube);">Build</a></li>
                         <li><a ng-click="startRefresh(cube)">Refresh</a></li>
                         <li><a ng-click="startMerge(cube)">Merge</a></li>
@@ -106,6 +108,11 @@
                     </ul>
                 </div>
             </td>
+            <td ng-if="cube.streaming">
+              <label class="badge label-info" style="cursor:pointer;">STREAMING</label>
+            </td>
+          <td ng-if="!cube.streaming">
+          </td>
         </tr>
         <tr ng-show="cube.showDetail">
             <td colspan="9" style="padding: 10px 30px 10px 30px;">

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/modelDesigner/conditions_settings.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/modelDesigner/conditions_settings.html b/webapp/app/partials/modelDesigner/conditions_settings.html
index 7a0d463..6e836ee 100644
--- a/webapp/app/partials/modelDesigner/conditions_settings.html
+++ b/webapp/app/partials/modelDesigner/conditions_settings.html
@@ -132,7 +132,11 @@
                     <div class="col-xs-12">
                         <ol class="text-info">
                             <li>Partition date column not required,leave as default if cube always need full build</li>
-                            <li>Partition date column will select 'date' or 'string' type column from fact table</li>
+                            <li>Partition date column will select 'date' type column from fact table</li>
+                            <li>Where clause to filter data from source</li>
+                            <li>Do not include date column which will be used for incremental refresh</li>
+                            <li>Do not include "Where"</li>
+                            <li>Please verify SQL when finish cube design from SQL view of cube</li>
                         </ol>
                     </div>
                 </div>

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/modelDesigner/data_model.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/modelDesigner/data_model.html b/webapp/app/partials/modelDesigner/data_model.html
index e100287..e1cae39 100644
--- a/webapp/app/partials/modelDesigner/data_model.html
+++ b/webapp/app/partials/modelDesigner/data_model.html
@@ -20,7 +20,7 @@
     <ng-form name="forms.data_model_form">
 
     <!-- Fact Table Name -->
-    <div class="form-group required">
+    <div class="form-group" ng-class="{'required':state.mode=='edit'}">
         <div class="row">
             <label class="col-xs-12 col-sm-2 control-label concube.detailtrol-label no-padding-right font-color-default">
                 <b>Fact Table</b>

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/modelDesigner/model_info.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/modelDesigner/model_info.html b/webapp/app/partials/modelDesigner/model_info.html
index aed4325..a290bfb 100644
--- a/webapp/app/partials/modelDesigner/model_info.html
+++ b/webapp/app/partials/modelDesigner/model_info.html
@@ -22,7 +22,7 @@
         <ng-form name="forms.model_info_form" novalidate>
 
             <!--Model Name-->
-            <div class="form-group required">
+            <div class="form-group" ng-class="{'required':state.mode=='edit'}">
                 <div class="row">
                     <label class="col-xs-12 col-sm-3 control-label no-padding-right font-color-default">
                         <b>Model Name</b>

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/models/models_tree.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/models/models_tree.html b/webapp/app/partials/models/models_tree.html
index 722d65f..9d86c50 100644
--- a/webapp/app/partials/models/models_tree.html
+++ b/webapp/app/partials/models/models_tree.html
@@ -44,10 +44,6 @@
             <a href="models/add"  ng-if="userService.hasRole('ROLE_MODELER')"><i class="fa fa-star"></i> New Model</a>
           </li>
 
-          <li ng-if="userService.hasRole('ROLE_ADMIN')">
-            <a href="streaming/add"  ng-if="userService.hasRole('ROLE_MODELER')"><i class="fa fa-area-chart"></i>New Streaming</a>
-          </li>
-
         </ul>
       </div>
 

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/streaming/streaming_edit.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/streaming/streaming_edit.html b/webapp/app/partials/streaming/streaming_edit.html
new file mode 100644
index 0000000..d4b4926
--- /dev/null
+++ b/webapp/app/partials/streaming/streaming_edit.html
@@ -0,0 +1,34 @@
+<!--
+* 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.
+-->
+
+<div class="row">
+    <div class="col-xs-3">
+      <div ng-include src="'partials/models/models_tree.html'" ng-controller="ModelsCtrl"></div>
+      <!--<div ng-include src="'partials/tables/source_table_tree.html'" ng-controller="SourceMetaCtrl"></div>-->
+    </div>
+    <div class="col-xs-9">
+        <form role="form" name="cube_form" novalidate>
+            <!-- This margin in order to align with table tree in left part -->
+            <div style="margin-top: 20px;" ng-controller="CubeEditCtrl">
+                <div ng-include="'partials/streaming/streaming_schema.html'" ng-controller="StreamingSchemaCtrl">
+                </div>
+            </div>
+        </form>
+    </div>
+</div>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/streaming/streaming_schema.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/streaming/streaming_schema.html b/webapp/app/partials/streaming/streaming_schema.html
new file mode 100644
index 0000000..a45904c
--- /dev/null
+++ b/webapp/app/partials/streaming/streaming_schema.html
@@ -0,0 +1,63 @@
+<!--
+* 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.
+-->
+
+<!--hide when view model and no model selected-->
+<div class="box box-primary model-design box-2px" ng-init="model">
+    <div class="box-header widget-header-blue widget-header-flat">
+        <h4 class="box-title text-info">Streaming Designer</h4>
+    </div>
+    <div class="box-body">
+        <div>
+            <ul class="wizard-steps">
+                <li ng-repeat="step in wizardSteps"
+                    class="{{step==curStep?'active':''}} {{step.isComplete?'complete':''}}">
+                    <span style="cursor:pointer;" ng-click="checkForm()?goToStep($index):''" class="step">{{step.step = ($index + 1)}}</span>
+                    <span class="title">{{step.title}}</span>
+                </li>
+            </ul>
+        </div>
+        <hr/>
+        <div class="step-content pos-rel" id="step-container">
+            <div ng-include src="curStep.src"></div>
+        </div>
+        <hr/>
+        <div class="wizard-actions">
+            <div class="row">
+                <div class="col-xs-8" style="display:block;">
+                    <div>
+                    </div>
+                </div>
+                <div class="col-xs-4 pull-right">
+                    <button class="btn btn-prev" ng-click="preView()" ng-show="curStep.title!='Streaming Config'">
+                        <i class="ace-icon fa fa-arrow-left"></i>
+                        Prev
+                    </button>
+                    <button id="nextButton" class="btn btn-success btn-next" ng-disabled="forms[curStep.form].$invalid" ng-click="checkForm()?nextView():''"
+                            ng-show="curStep.title!='Advanced Settings'">
+                        Next
+                        <i class="ace-icon fa fa-arrow-right icon-on-right"></i>
+                    </button>
+                    <button class="btn btn-primary"  ng-click="checkForm()?saveStreaming():''"
+                            ng-if="curStep.title=='Advanced Settings' && state.mode=='edit'">
+                        Save
+                    </button>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/tables/source_table_tree.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/tables/source_table_tree.html b/webapp/app/partials/tables/source_table_tree.html
index ff95d10..767eb43 100755
--- a/webapp/app/partials/tables/source_table_tree.html
+++ b/webapp/app/partials/tables/source_table_tree.html
@@ -45,3 +45,5 @@
         <div no-result ng-if="tableModel.selectedSrcDb.length == 0"></div>
     </div>
 </div>
+
+<div ng-include="'partials/tables/table_load.html'"></div>

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/tables/table_detail.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/tables/table_detail.html b/webapp/app/partials/tables/table_detail.html
index e692269..b232375 100644
--- a/webapp/app/partials/tables/table_detail.html
+++ b/webapp/app/partials/tables/table_detail.html
@@ -199,117 +199,4 @@
     </div>
   </div>
 
-
-  <script type="text/ng-template" id="addHiveTable.html">
-    <div class="modal-header">
-      <h4>Load Hive Table Metadata</h4>
-    </div>
-    <div class="modal-body">
-      <span><strong>Project: </strong>{{ $parent.projectName!=null?$parent.projectName:'NULL'}}</span>
-      <label for="tables"> Table Names:(Seperate with comma)</label>
-            <textarea ng-model="$parent.tableNames" class="form-control" id="tables"
-                      placeholder="table1,table2  By default,system will choose 'Default' as database,you can specify database like this 'database.table'"></textarea>
-    </div>
-    <div class="modal-footer">
-      <button class="btn btn-primary" ng-click="add()">Sync</button>
-      <button class="btn btn-primary" ng-click="cancel()">Cancel</button>
-    </div>
-  </script>
-
-  <script type="text/ng-template" id="addStreamingSource.html">
-    <div class="modal-header">
-      <h2>Create Streaming Table Schema</h2>
-    </div>
-
-    <div class="modal-body streaming-source" style="height: 480px;">
-      <div class="col-xs-5">
-        <p class="text-info">
-          Need to input streaming source record here, will detect the source schema and create a table schema for
-          streaming.
-        </p>
-
-        <div style="padding:15px;" class="has-error">
-          <small class="help-block" ng-show="streaming.sourceSchema==''&&form.setStreamingSchema.$sbumitted">Please
-            input Streaming source record to generate schema.
-          </small>
-        </div>
-        <div style="margin-bottom: 20px;">
-          <span class="label label-info">JSON</span>
-        </div>
-        <div ng-model="streaming.sourceSchema" ui-ace="{
-    useWrapMode : true,
-    mode:'json',
-    onLoad: streamingOnLoad
-  }">
-
-        </div>
-      </div>
-      <div class="col-xs-1" style="margin-top:300px;text-align:center;">
-        <button type="button" class="btn btn-primary" ng-click="streamingOnChange()"><i
-          class="fa fa-angle-double-right fa-5" style="font-size:2em;"></i></button>
-      </div>
-      <div class="col-xs-6" ng-show="table.sourceValid">
-        <ol class="text-info" style="margin-bottom: 30px;">
-          <li>Choose one 'timestamp' type column for streaming table.</li>
-          <li>Uncheck the 'timestamp' type column which will not be used.</li>
-        </ol>
-        <form class="form-horizontal" name="form.setStreamingSchema" novalidate>
-          <div class="form-group required">
-            <label class="col-xs-4 control-label" style="text-align: left;">Table Name</label>
-
-            <div class="col-xs-8"
-                 ng-class="{'has-error':form.setStreamingSchema.streamingObject.$invalid && (form.setStreamingSchema.streamingObject.$dirty||form.setStreamingSchema.$sbumitted)}">
-              <input type="text" name="streamingObject" required="" ng-model="table.name" class="form-control"/>
-              <small class="help-block"
-                     ng-show="form.setStreamingSchema.streamingObject.$error.required&&(form.setStreamingSchema.streamingObject.$dirty||form.setStreamingSchema.$sbumitted)">
-                Table name is required.
-              </small>
-            </div>
-          </div>
-        </form>
-        <table class="table table-hover table-bordered">
-          <tr>
-            <th>Check As Column</th>
-            <th>Column</th>
-            <th>Column Type</th>
-            <th>Comment</th>
-          </tr>
-          <tr ng-repeat="column in columnList">
-            <td><label style="width:100%;cursor: pointer;" for="{{column.name}}"><input style="width:1em;height:1em;"
-                                                                                        type="checkbox"
-                                                                                        id="{{column.name}}"
-                                                                                        ng-model="column.checked"
-                                                                                        ng-true-value="Y"
-                                                                                        ng-false-value="N"/></label>
-            </td>
-            <td>{{column.name}}</td>
-            <td>
-              <select chosen ng-model="column.type"
-                      ng-options="type as type for type in tableConfig.dataTypes"
-                      data-placeholder="select a column type"
-                      style="width: 200px !important;"
-                      class="chosen-select">
-              </select>
-            </td>
-            <td>
-              <label ng-if="column.type=='timestamp'&&column.fromSource=='Y'" class="badge badge-info">TIMESTAMP</label>
-              <label ng-if="column.fromSource=='N'" class="badge badge-info">AUTO APPEND</label>
-            </td>
-          </tr>
-        </table>
-
-        <div class="has-error" ng-if="rule.timestampColumnConflict">
-          <small class="help-block">
-            You should choose one, and only one 'timestamp' type column generated from source schema.
-          </small>
-        </div>
-      </div>
-    </div>
-    <div class="modal-footer">
-      <button class="btn btn-primary" ng-click="syncStreamingSchema()" ng-disabled="form.setStreamingSchema.$invalid">
-        Submit
-      </button>
-      <button class="btn btn-primary" ng-click="cancel()">Cancel</button>
-    </div>
-  </script>
 </div>

http://git-wip-us.apache.org/repos/asf/incubator-kylin/blob/53b383d9/webapp/app/partials/tables/table_load.html
----------------------------------------------------------------------
diff --git a/webapp/app/partials/tables/table_load.html b/webapp/app/partials/tables/table_load.html
new file mode 100644
index 0000000..99c993d
--- /dev/null
+++ b/webapp/app/partials/tables/table_load.html
@@ -0,0 +1,130 @@
+<!--
+* 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.
+-->
+
+  <script type="text/ng-template" id="addHiveTable.html">
+    <div class="modal-header">
+      <h4>Load Hive Table Metadata</h4>
+    </div>
+    <div class="modal-body">
+      <span><strong>Project: </strong>{{ $parent.projectName!=null?$parent.projectName:'NULL'}}</span>
+      <label for="tables"> Table Names:(Seperate with comma)</label>
+            <textarea ng-model="$parent.tableNames" class="form-control" id="tables"
+                      placeholder="table1,table2  By default,system will choose 'Default' as database,you can specify database like this 'database.table'"></textarea>
+    </div>
+    <div class="modal-footer">
+      <button class="btn btn-primary" ng-click="add()">Sync</button>
+      <button class="btn btn-primary" ng-click="cancel()">Cancel</button>
+    </div>
+  </script>
+
+  <script type="text/ng-template" id="addStreamingSource.html">
+    <div class="modal-header">
+      <h2>Create Streaming Table Schema</h2>
+    </div>
+
+    <div class="modal-body streaming-source" style="height: 660px;">
+      <div class="col-xs-5">
+        <p class="text-info">
+          Need to input streaming source record here, will detect the source schema and create a table schema for
+          streaming.
+        </p>
+
+        <div style="padding:15px;" class="has-error">
+          <small class="help-block" ng-show="streaming.sourceSchema==''&&form.setStreamingSchema.$sbumitted">Please
+            input Streaming source record to generate schema.
+          </small>
+        </div>
+        <div style="margin-bottom: 20px;">
+          <span class="label label-info">JSON</span>
+        </div>
+        <div ng-model="streaming.sourceSchema" ui-ace="{
+    useWrapMode : true,
+    mode:'json',
+    onLoad: streamingOnLoad
+  }">
+
+        </div>
+      </div>
+      <div class="col-xs-1" style="margin-top:300px;text-align:center;">
+        <button type="button" class="btn btn-primary" ng-click="streamingOnChange()"><i
+          class="fa fa-angle-double-right fa-5" style="font-size:2em;"></i></button>
+      </div>
+      <div class="col-xs-6" ng-show="table.sourceValid">
+        <ol class="text-info" style="margin-bottom: 30px;">
+          <li>Choose one 'timestamp' type column for streaming table.</li>
+          <li>Uncheck the 'timestamp' type column which will not be used.</li>
+        </ol>
+        <form class="form-horizontal" name="form.setStreamingSchema" novalidate>
+          <div class="form-group required">
+            <label class="col-xs-4 control-label" style="text-align: left;">Table Name</label>
+
+            <div class="col-xs-8"
+                 ng-class="{'has-error':form.setStreamingSchema.streamingObject.$invalid && (form.setStreamingSchema.streamingObject.$dirty||form.setStreamingSchema.$sbumitted)}">
+              <input type="text" name="streamingObject" required="" ng-model="table.name" class="form-control"/>
+              <small class="help-block"
+                     ng-show="form.setStreamingSchema.streamingObject.$error.required&&(form.setStreamingSchema.streamingObject.$dirty||form.setStreamingSchema.$sbumitted)">
+                Table name is required.
+              </small>
+            </div>
+          </div>
+        </form>
+        <table class="table table-hover table-bordered">
+          <tr>
+            <th>Check As Column</th>
+            <th>Column</th>
+            <th>Column Type</th>
+            <th>Comment</th>
+          </tr>
+          <tr ng-repeat="column in columnList">
+            <td><label style="width:100%;cursor: pointer;" for="{{column.name}}"><input style="width:1em;height:1em;"
+                                                                                        type="checkbox"
+                                                                                        id="{{column.name}}"
+                                                                                        ng-model="column.checked"
+                                                                                        ng-true-value="Y"
+                                                                                        ng-false-value="N"/></label>
+            </td>
+            <td>{{column.name}}</td>
+            <td>
+              <select chosen ng-model="column.type"
+                      ng-options="type as type for type in tableConfig.dataTypes"
+                      data-placeholder="select a column type"
+                      style="width: 200px !important;"
+                      class="chosen-select">
+              </select>
+            </td>
+            <td>
+              <label ng-if="column.type=='timestamp'&&column.fromSource=='Y'" class="badge badge-info">TIMESTAMP</label>
+              <label ng-if="column.fromSource=='N'" class="badge badge-info">AUTO APPEND</label>
+            </td>
+          </tr>
+        </table>
+
+        <div class="has-error" ng-if="rule.timestampColumnConflict">
+          <small class="help-block">
+            You should choose one, and only one 'timestamp' type column generated from source schema.
+          </small>
+        </div>
+      </div>
+    </div>
+    <div class="modal-footer">
+      <button class="btn btn-primary" ng-click="syncStreamingSchema()" ng-disabled="form.setStreamingSchema.$invalid">
+        Submit
+      </button>
+      <button class="btn btn-primary" ng-click="cancel()">Cancel</button>
+    </div>
+  </script>
\ No newline at end of file