blob: 17e89b4b9e43b2aa9b622d75083fc5597bbebfeb [file] [log] [blame]
<!--
* 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="CubeCtrl" class="nav-tabs-custom" style="margin-top:40px;">
<ul class="nav nav-tabs">
<li class="{{(!cube.visiblePage || cube.visiblePage=='metadata')? 'active':''}}">
<a href="" ng-click="cube.visiblePage='metadata'">Grid</a>
</li>
<!--</li>-->
<li class="{{cube.visiblePage=='sql'? 'active':''}}">
<a href="" ng-click="cube.visiblePage='sql';getCubeSql(cube)">SQL</a>
</li>
<li class="{{cube.visiblePage=='json'? 'active':''}}"
ng-if="userService.hasRole('ROLE_ADMIN') || hasPermission('cube',cube, permissions.ADMINISTRATION.mask) && !newAccess">
<a href="" ng-click="cube.visiblePage='json';">JSON(Cube)</a>
</li>
<!--<li class="{{cube.visiblePage=='access'? 'active':''}}"-->
<!--ng-if="!kylinConfig.isExternalAclEnabled()">-->
<!--<a href="" ng-click="cube.visiblePage='access';listAccess(cube, 'CubeInstance');">Access</a>-->
<!--</li>-->
<li class="{{cube.visiblePage=='notification'? 'active':''}}"
ng-if="userService.hasRole('ROLE_ADMIN') || hasPermission('cube',cube, permissions.ADMINISTRATION.mask) && !newAccess">
<a href="" ng-click="cube.visiblePage='notification';getNotifyListString(cube);">Notification</a>
</li>
<li class="{{cube.visiblePage=='hbase'? 'active':''}}"
ng-if="userService.hasRole('ROLE_ADMIN') || hasPermission('cube' ,cube, permissions.ADMINISTRATION.mask) && !newAccess">
<a href="" ng-click="cube.visiblePage='hbase';getHbaseInfo(cube)">Storage</a>
</li>
<li class="{{cube.visiblePage=='planner'? 'active':''}}" ng-if="(userService.hasRole('ROLE_ADMIN') || hasPermission('cube', cube, permissions.ADMINISTRATION.mask) && !newAccess) && isShowCubeplanner">
<a href="" ng-click="cube.visiblePage='planner';getCubePlanner(cube);">Planner</a>
</li>
<li class="{{cube.visiblePage=='streaming'? 'active':''}}" ng-if="(userService.hasRole('ROLE_ADMIN') || hasPermission('cube', cube, permissions.ADMINISTRATION.mask) && !newAccess) && cube.streamingV2">
<a href="" ng-click="cube.visiblePage='streaming';getStreamingInfo(cube)">Streaming</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>
</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>
</div>
<div ng-show="cube.visiblePage=='json'" class="cube-detail">
<pre ng-if="!state.jsonEdit"
style="background-color: white;border: 0px">{{angular.toJson(cleanStatus(cube.detail), true)}}</pre>
</div>
<!--<div ng-show="cube.visiblePage=='json_model'" class="cube-detail">-->
<!--<pre ng-if="!state.jsonEdit"-->
<!--style="background-color: white;border: 0px">{{angular.toJson(cleanStatus(model), true)}}</pre>-->
<!--</div>-->
<!--<div ng-show="cube.visiblePage=='graph'" id="cube_graph_{{cube.name}}" class="cube-detail cube_graph">-->
<!--</div>-->
<!--<div class="cube-detail" ng-if="cube.visiblePage=='access'">-->
<!--<div class="row">-->
<!--<div class="col-xs-1"></div>-->
<!--<div class="col-xs-10">-->
<!--<div ng-include src="'partials/common/access.html'" ng-init="entity=cube;type='CubeInstance';"></div>-->
<!--</div>-->
<!--<div class="col-xs-1"></div>-->
<!--</div>-->
<!--</div>-->
<div class="cube-detail" ng-show="cube.visiblePage=='notification'">
<div style="margin: 15px;">
<form>
<h5>Notification List(Comma Separated)</h5>
<div class="form-group">
<input ng-model="cube.notifyListString" class="form-control" placeholder="Notification List..." />
</div>
<div class="form-group">
<button class="btn btn-primary btn-sm" ng-click="updateNotifyList(cube)">Save</button>
</div>
<div class="space-4"></div>
</form>
</div>
</div>
<div class="cube-detail" ng-show="cube.visiblePage=='hbase'">
<div style="margin: 15px; overflow: hidden;">
<div ng-if="cube.hbase">
<div class="hr hr8 hr-double hr-dotted"></div>
<h5><b>Segment Number:</b> <span class="blue">{{cube.hbase.length}}</span> <b>Total Size:</b> <span class="blue">{{cube.totalSize | bytes}}</span></h5>
</div>
<div ng-repeat="table in cube.hbase" class="cube-segment-list" ng-class="{'cube-broken-segment': table.regionCount === 0}">
<h5><b>Segment:</b> {{table.segmentName}}</h5>
<ul>
<li ng-if="cube.streaming">Status: <span>{{table.segmentStatus}}</span></li>
<li ng-if="cube.model.partition_desc.partition_date_column">Start Time: <span>{{table.dateRangeStart | reverseToGMT0}}</span></li>
<li ng-if="cube.model.partition_desc.partition_date_column">End Time: <span>{{table.dateRangeEnd | reverseToGMT0}}</span></li>
<li>Source Count: <span>{{table.sourceCount}}</span></li>
<li>HBase Table: <span>{{table.tableName}}</span></li>
<li>Region Count: <span ng-class="{'red': table.regionCount == 0}">{{table.regionCount}}</span></li>
<li>Size: <span>{{table.tableSize | bytes}}</span></li>
</ul>
</div>
<div ng-if="cube.hbase.length == 0">
<h5>No Storage Info.</h5>
</div>
</div>
</div>
<div class="cube-detail" ng-if="cube.visiblePage=='planner'">
<div style="padding: 15px;">
<div class="row">
<div class="col-sm-12">
<h4 style="display: inline;">Cuboid Distribution</h4>
<button ng-if="enableRecommend" class="btn btn-success btn-sm pull-right" ng-click="getRecommendCuboids(cube)" ng-if="currentData">
Recommend
</button>
<div ng-if="cube.cuboid_last_optimized" class="pull-right" style="padding: 5px;">Last Optimized Time: {{cube.cuboid_last_optimized | utcToConfigTimeZone}}</div>
</div>
</div>
<div class="row">
<div class="col-md-6 col-sm-12">
<nvd3 options="currentOptions" data="currentData" api="currentChart.api"></nvd3>
</div>
<div class="col-md-6 col-sm-12" ng-if="recommendData">
<nvd3 options="recommendOptions" data="recommendData"></nvd3>
</div>
</div>
<div class="row cube-planner-column" ng-if="currentData || recommendData">
<table class="table table-bordered">
<tbody>
<tr ng-repeat="row in cube.detail.rowkey.rowkey_columns track by $index" ng-if="$index % 5 == 0" class="row">
<th ng-class="{'column-in-cuobid': selectCuboid.charAt($index) == 1, 'column-not-in-cuboid': selectCuboid.charAt($index) == 0}">{{cube.detail.rowkey.rowkey_columns[$index].column}}</th>
<th ng-class="{'column-in-cuobid': selectCuboid.charAt($index + 1) == 1, 'column-not-in-cuboid': selectCuboid.charAt($index + 1) == 0}">{{cube.detail.rowkey.rowkey_columns[$index + 1].column}}</th>
<th ng-class="{'column-in-cuobid': selectCuboid.charAt($index + 2) == 1, 'column-not-in-cuboid': selectCuboid.charAt($index + 2) == 0}">{{cube.detail.rowkey.rowkey_columns[$index + 2].column}}</th>
<th ng-class="{'column-in-cuobid': selectCuboid.charAt($index + 3) == 1, 'column-not-in-cuboid': selectCuboid.charAt($index + 3) == 0}">{{cube.detail.rowkey.rowkey_columns[$index + 3].column}}</th>
<th ng-class="{'column-in-cuobid': selectCuboid.charAt($index + 4) == 1, 'column-not-in-cuboid': selectCuboid.charAt($index + 4) == 0}">{{cube.detail.rowkey.rowkey_columns[$index + 4].column}}</th>
</tr>
</tbody>
</table>
</div>
<div class="row">
<div class="col-sm-12">
<div class="dropup pull-right" style="margin-left: 10px;" ng-if="recommendData">
<button class="btn btn-default dropdown-toggle" type="button" id="export" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Export
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="export">
<li><a ng-href="{{config.service.url}}cubes/{{cube.name}}/cuboids/export?top=10" target="_blank" >Top 10</a></li>
<li><a ng-href="{{config.service.url}}cubes/{{cube.name}}/cuboids/export?top=50" target="_blank" >Top 50</a></li>
<li><a ng-href="{{config.service.url}}cubes/{{cube.name}}/cuboids/export?top=100" target="_blank" >Top 100</a></li>
</ul>
</div>
<button class="btn btn-success btn-next pull-right" ng-click="optimizeCuboids(cube)" ng-if="recommendData">
Optimize
</button>
</div>
</div>
</div>
</div>
<div class="cube-detail" ng-if="cube.visiblePage=='streaming'">
<div style="padding: 15px; color: #212121;">
<div class="row" ng-repeat="(rsId, replicaSet) in replicaSets" style="padding-left: 10px; padding-right: 10px;">
<div class="col-sm-1" style="text-align: center; background-color: #f5f5f5; border: 1px solid #ffffff; height: 100px; padding-top: 30px; padding-bottom: 30px; color: #455A64;">
<span>Replica Set ID: {{rsId}}</span>
</div>
<div class="col-sm-11" style="padding-left: 0px; padding-right: 0px;">
<div class="cube-receiver-stats" ng-class="receiverStats.style" ng-repeat="(node, receiverStats) in replicaSet" ng-click="nodeStatsDetail(node, receiverStats)">
<div class="col-sm-12 node-info" ng-class="{'text-red':receiverStats.receiver_state != 'HEALTHY'}">
{{node}}
</div>
<div class="col-sm-12 rate-metric" ng-if="receiverStats.partition_consume_stats">
{{receiverStats.consumer_info.one_min_rate | number:0}} <span class="unit">msg/s</span>
</div>
<div class="col-sm-12 rate-metric" ng-if="!receiverStats.partition_consume_stats">
N/A
</div>
<div class="row">
<div class="col-sm-2 col-sm-offset-1 detail-metric">
5'
</div>
<div class="col-sm-2 detail-metric">
15'
</div>
<div class="col-sm-2 detail-metric">
avg
</div>
<div class="col-sm-2 detail-metric">
consume
</div>
<div class="col-sm-2 detail-metric">
ingest
</div>
</div>
<div class="row" ng-if="receiverStats.partition_consume_stats">
<div class="col-sm-2 col-sm-offset-1 detail-metric">
{{receiverStats.consumer_info.five_min_rate | number:0}}<span>msg/s</span>
</div>
<div class="col-sm-2 detail-metric">
{{receiverStats.consumer_info.fifteen_min_rate | number:0}}<span>msg/s</span>
</div>
<div class="col-sm-2 detail-metric">
{{receiverStats.consumer_info.avg_rate | number:0}}<span>msg/s</span>
</div>
<div class="col-sm-2 detail-metric">
{{receiverStats.consumer_info.total_consume}}
</div>
<div class="col-sm-2 detail-metric">
{{receiverStats.total_ingest}}
</div>
</div>
<div class="row" ng-if="!receiverStats.partition_consume_stats">
<div class="col-sm-2 col-sm-offset-1 detail-metric">
N/A
</div>
<div class="col-sm-2 detail-metric">
N/A
</div>
<div class="col-sm-2 detail-metric">
N/A
</div>
<div class="col-sm-2 detail-metric">
N/A
</div>
<div class="col-sm-2 detail-metric">
{{receiverStats.total_ingest || 'N/A'}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/ng-template" id="nodeStatsDetail.html">
<div class="modal-header">
<div class="box-header">
<h3 class="box-title">{{node}}</h3>
<div class="box-tools pull-right">
<button type="button" class="btn btn-box-tool" ng-click="cancel()"><i class="fa fa-times"></i></button>
</div>
</div>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-offset-1 col-md-3 text-right">Latest Event Time</div>
<div class="col-md-7">{{receiverStats.latest_event_time ? (receiverStats.latest_event_time | reverseToGMT0) : ''}}</div>
</div>
<div class="row">
<div class="col-md-offset-1 col-md-3 text-right">Latest Event Ingest Time</div>
<div class="col-md-7">{{receiverStats.latest_event_ingest_time ? (receiverStats.latest_event_ingest_time | reverseToGMT0) : ''}}</div>
</div>
<div class="row">
<div class="col-md-offset-1 col-md-3 text-right">Segments</div>
<div class="col-md-7">
<!-- TODO add color for segment & partition-->
<a href="javascript:void(0);" ng-repeat="(segmentName, segmentInfo) in receiverStats.segment_stats" kylinpopover placement="top" class="segment" title="Segment Info" trigger="focus" content="segment name: {{segmentName}}</br>segment state: {{segmentInfo.segment_state}}</br>fragment number: {{segmentInfo.store_stats.num_fragments}}</br>row number in memory: {{segmentInfo.store_stats.num_rows_in_mem}}</br>latest event latency: {{segmentInfo.latest_event_latency}}ms</br>latest event time: {{!!segmentInfo.latest_event_time ? (segmentInfo.latest_event_time | reverseToGMT0) : ''}}</br>segement create time: {{segmentInfo.segment_create_time | reverseToGMT0}}</br>last update time: {{segmentInfo.segment_last_update_time | reverseToGMT0}}">
<i class="fa fa-database" style="font-size: 1.5em; color: #86bad8; margin-right: 5px;" ng-class="{'active': segmentInfo.segment_state === 'ACTIVE'}"></i>
</a>
</div>
</div>
<div class="row">
<div class="col-md-offset-1 col-md-3 text-right">Partitions</div>
<div class="col-md-7" ng-if="receiverStats.partition_consume_stats">
<a href="javascript:void(0);" ng-repeat="partitionInfo in receiverStats.partition_consume_stats" kylinpopover placement="top" title="Partition Info" trigger="focus" content="Partition Id: {{partitionInfo.partition_id}}</br>Offset Info: {{partitionInfo.offset_info}}</br>1 Minute Rate: {{partitionInfo.one_min_rate | number:0}} msg/s</br>5 Minute Rate: {{partitionInfo.five_min_rate | number:0}} msg/s</br>15 Minute Rate: {{partitionInfo.fifteen_min_rate | number:0}} msg/s</br>AVG Rate: {{partitionInfo.avg_rate | number:0}} msg/s</br>Total Consume: {{partitionInfo.total_consume}}<br/>Cosume Lag: {{partitionInfo.consume_lag}}">
<i class="fa fa-list-ul" style="font-size:1.5em; color:#3c8dbc; margin-right: 5px;"></i>
</a>
</div>
</div>
<div class="row">
<div class="col-md-offset-1 col-md-3 text-right">Cosume Lag</div>
<div class="col-md-7">{{receiverStats.consume_lag}}</div>
</div>
</div>
</script>