YARN-7957. [UI2] YARN service delete option disappears after stopping application. Contributed by Akhil PB.

(cherry picked from commit 751f626e50)
This commit is contained in:
Sunil G 2018-10-05 12:28:09 +05:30
parent fae24b4747
commit 6407f2a0ed
10 changed files with 185 additions and 18 deletions

View File

@ -0,0 +1,32 @@
/**
* 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.
*/
import RESTAbstractAdapter from './restabstract';
export default RESTAbstractAdapter.extend({
address: "rmWebAddress",
restNameSpace: "dashService",
serverName: "DASH",
urlForQueryRecord(query/*, modelName*/) {
var url = this.buildURL();
url += '/' + query.serviceName;
delete query.serviceName;
return url;
}
});

View File

@ -85,7 +85,7 @@ export default Ember.Controller.extend({
contentPath: 'startTime', contentPath: 'startTime',
facetType: null, facetType: null,
getCellContent: function(row) { getCellContent: function(row) {
return Converter.timeStampToDate(row.get('startTime')); return row.get('formattedStartTime');
} }
}, { }, {
id: 'elTime', id: 'elTime',
@ -100,7 +100,10 @@ export default Ember.Controller.extend({
headerTitle: 'Finished Time', headerTitle: 'Finished Time',
contentPath: 'validatedFinishedTs', contentPath: 'validatedFinishedTs',
facetType: null, facetType: null,
observePath: true observePath: true,
getCellContent: function(row) {
return row.get('formattedFinishedTime');
}
}, { }, {
id: 'priority', id: 'priority',
headerTitle: 'Priority', headerTitle: 'Priority',
@ -174,14 +177,17 @@ export default Ember.Controller.extend({
contentPath: 'startTime', contentPath: 'startTime',
facetType: null, facetType: null,
getCellContent: function(row) { getCellContent: function(row) {
return Converter.timeStampToDate(row.get('startTime')); return row.get('formattedStartTime');
} }
}, { }, {
id: 'finishTime', id: 'finishTime',
headerTitle: 'Finished Time', headerTitle: 'Finished Time',
contentPath: 'validatedFinishedTs', contentPath: 'validatedFinishedTs',
facetType: null, facetType: null,
observePath: true observePath: true,
getCellContent: function(row) {
return row.get('formattedFinishedTime');
}
}); });
return ColumnDef.make(colums); return ColumnDef.make(colums);
}.property(), }.property(),

View File

@ -160,11 +160,29 @@ export default Ember.Controller.extend({
return amHostAddress; return amHostAddress;
}), }),
isKillable: Ember.computed("model.app.state", function () { isAppKillable: Ember.computed("model.app.state", function () {
if (this.get("model.app.applicationType") === 'yarn-service') { if (this.get("model.app.applicationType") === 'yarn-service') {
return false; return false;
} }
const killableStates = ['NEW', 'NEW_SAVING', 'SUBMITTED', 'ACCEPTED', 'RUNNING']; const killableStates = ['NEW', 'NEW_SAVING', 'SUBMITTED', 'ACCEPTED', 'RUNNING'];
return killableStates.indexOf(this.get("model.app.state")) > -1; return killableStates.indexOf(this.get("model.app.state")) > -1;
}),
isServiceDeployedOrRunning: Ember.computed('model.serviceInfo', function() {
const serviceInfo = this.get('model.serviceInfo');
const stoppedStates = ['STOPPED', 'SUCCEEDED', 'FAILED'];
if (serviceInfo) {
return stoppedStates.indexOf(serviceInfo.get('state')) === -1;
}
return false;
}),
isServiceStoppped: Ember.computed('model.serviceInfo', function() {
const serviceInfo = this.get('model.serviceInfo');
const stoppedStates = ['STOPPED', 'SUCCEEDED'];
if (serviceInfo) {
return stoppedStates.indexOf(serviceInfo.get('state')) > -1;
}
return false;
}) })
}); });

View File

@ -24,10 +24,10 @@ export default DS.Model.extend({
user: DS.attr("string"), user: DS.attr("string"),
queue: DS.attr("string"), queue: DS.attr("string"),
state: DS.attr("string"), state: DS.attr("string"),
startTime: DS.attr("string"), startTime: DS.attr("number"),
elapsedTime: DS.attr("string"), elapsedTime: DS.attr("string"),
finalStatus: DS.attr("string"), finalStatus: DS.attr("string"),
finishedTime: DS.attr("finishedTime"), finishedTime: DS.attr("number"),
progress: DS.attr("number"), progress: DS.attr("number"),
diagnostics: DS.attr("string"), diagnostics: DS.attr("string"),
amHostHttpAddress: DS.attr("string"), amHostHttpAddress: DS.attr("string"),
@ -71,6 +71,17 @@ export default DS.Model.extend({
return this.get("finishedTime") >= this.get("startTime"); return this.get("finishedTime") >= this.get("startTime");
}.property("hasFinishedTime"), }.property("hasFinishedTime"),
formattedStartTime: function() {
return Converter.timeStampToDate(this.get('startTime'));
}.property('startTime'),
formattedFinishedTime: function() {
if (this.get("finishedTime") < this.get("startTime")) {
return "N/A";
}
return Converter.timeStampToDate(this.get("finishedTime"));
}.property('finishedTime'),
formattedElapsedTime: function() { formattedElapsedTime: function() {
return Converter.msToElapsedTimeUnit(this.get("elapsedTime")); return Converter.msToElapsedTimeUnit(this.get("elapsedTime"));
}.property("elapsedTime"), }.property("elapsedTime"),

View File

@ -0,0 +1,30 @@
/**
* 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.
*/
import DS from 'ember-data';
export default DS.Model.extend({
appId: DS.attr('string'),
name: DS.attr('string'),
state: DS.attr('string'),
version: DS.attr('string'),
lifetime: DS.attr('string'),
components: DS.attr(),
configuration: DS.attr(),
quicklinks: DS.attr()
});

View File

@ -37,6 +37,18 @@ export default AbstractRoute.extend(AppAttemptMixin, {
return []; return [];
}, function () { }, function () {
return []; return [];
}),
serviceInfo: new Ember.RSVP.Promise(resolve => {
if (service) {
this.store.queryRecord('yarn-service', {serviceName: service}).then(function(info) {
resolve(info);
}, function() {
resolve(null);
});
} else {
resolve(null);
}
}) })
}); });
}, },

View File

@ -42,9 +42,9 @@ export default DS.JSONAPISerializer.extend({
user: payload.user, user: payload.user,
queue: payload.queue, queue: payload.queue,
state: payload.state, state: payload.state,
startTime: payload.startedTime, // will be formatted in em-table startTime: payload.startedTime, // will be formatted in yarn-app model
elapsedTime: payload.elapsedTime, elapsedTime: payload.elapsedTime,
finishedTime: Converter.timeStampToDate(payload.finishedTime), finishedTime: payload.finishedTime, // will be formatted in yarn-app model
finalStatus: payload.finalStatus, finalStatus: payload.finalStatus,
progress: payload.progress, progress: payload.progress,
applicationType: payload.applicationType, applicationType: payload.applicationType,

View File

@ -0,0 +1,44 @@
/**
* 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.
*/
import DS from 'ember-data';
export default DS.JSONAPISerializer.extend({
internalNormalizeSingleResponse(store, primaryModelClass, payload) {
const fixedPayload = {
id: 'yarn_service_' + (payload.id || Date.now()),
type: primaryModelClass.modelName,
attributes: {
appId: payload.id,
name: payload.name,
state: payload.state,
version: payload.version,
lifetime: payload.lifetime,
components: payload.components,
configuration: payload.configuration,
quicklinks: payload.quicklinks
}
};
return fixedPayload;
},
normalizeSingleResponse(store, primaryModelClass, payload/*, id, requestType*/) {
const pl = this.internalNormalizeSingleResponse(store, primaryModelClass, payload);
return {data: pl};
}
});

View File

@ -60,14 +60,14 @@
<i class="glyphicon glyphicon-user glyphicon-gray" /> {{model.app.user}} <i class="glyphicon glyphicon-user glyphicon-gray" /> {{model.app.user}}
</div> </div>
{{#if model.app.hasFinishedTime}} {{#if model.app.hasFinishedTime}}
<div title="Started at {{model.app.startTime}}. &#10; Ran for {{model.app.formattedElapsedTime}}" class="yarn-tooltip"> <div title="Started at {{model.app.formattedStartTime}}. &#10; Ran for {{model.app.formattedElapsedTime}}" class="yarn-tooltip">
<i class="glyphicon glyphicon-time glyphicon-gray" /> <i class="glyphicon glyphicon-time glyphicon-gray" />
Finished at {{model.app.validatedFinishedTs}} Finished at {{model.app.formattedFinishedTime}}
</div> </div>
{{else}} {{else}}
<div title="Running for {{model.app.formattedElapsedTime}}" class="yarn-tooltip"> <div title="Running for {{model.app.formattedElapsedTime}}" class="yarn-tooltip">
<i class="glyphicon glyphicon-time glyphicon-gray" /> <i class="glyphicon glyphicon-time glyphicon-gray" />
Started at {{model.app.startTime}} Started at {{model.app.formattedStartTime}}
</div> </div>
{{/if}} {{/if}}
</div> </div>
@ -75,21 +75,33 @@
<div class="flex-right"> <div class="flex-right">
<div class="links"> <div class="links">
{{#if (or isRunningService isKillable)}} {{#if (or (or isServiceDeployedOrRunning isServiceStoppped) isAppKillable)}}
<div class="btn-group"> <div class="btn-group">
<button type="button" class="btn btn-unstyled dropdown-toggle" title="Settings" <button type="button" class="btn btn-unstyled dropdown-toggle" title="Settings"
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="margin-left: -5px;"> data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="margin-left: -5px;">
<i class="glyphicon glyphicon-cog"/> Settings <i class="glyphicon glyphicon-cog"/> Settings
</button> </button>
<ul class="dropdown-menu dropdown-menu-right"> <ul class="dropdown-menu dropdown-menu-right">
{{#if isRunningService}} {{#if isServiceDeployedOrRunning}}
<li> <li>
<a href="#" {{action "showStopServiceConfirm"}} target="_blank"><i class="glyphicon glyphicon-stop" /> &nbsp;Stop Service</a> <a href="#" {{action "showStopServiceConfirm"}} target="_blank">
<i class="glyphicon glyphicon-stop" /> &nbsp;Stop Service
</a>
</li> </li>
<li> <li>
<a href="#" target="_blank" {{action "showDeleteServiceConfirm"}}><i class="glyphicon glyphicon-trash" /> &nbsp;Delete Service </a> <a href="#" target="_blank" {{action "showDeleteServiceConfirm"}}>
<i class="glyphicon glyphicon-trash" /> &nbsp;Delete Service
</a>
</li> </li>
{{else if isKillable}} {{/if}}
{{#if isServiceStoppped}}
<li>
<a href="#" target="_blank" {{action "showDeleteServiceConfirm"}}>
<i class="glyphicon glyphicon-trash" /> &nbsp;Delete Service
</a>
</li>
{{/if}}
{{#if isAppKillable}}
<li> <li>
<a href="#" {{action "showKillApplicationConfirm"}} target="_blank"> <a href="#" {{action "showKillApplicationConfirm"}} target="_blank">
<i class="glyphicon glyphicon-stop" />&nbsp;Kill Application <i class="glyphicon glyphicon-stop" />&nbsp;Kill Application

View File

@ -17,7 +17,9 @@
--}} --}}
{{breadcrumb-bar breadcrumbs=breadcrumbs}} {{breadcrumb-bar breadcrumbs=breadcrumbs}}
<div class="col-md-12">
<a class="btn btn-primary pull-right" href="#/yarn-deploy-service">New Service</a> <a class="btn btn-primary pull-right" href="#/yarn-deploy-service">New Service</a>
</div>
<div class="col-md-12 container-fluid yarn-applications-container"> <div class="col-md-12 container-fluid yarn-applications-container">
{{#if model.apps}} {{#if model.apps}}
{{em-table columns=serviceColumns rows=model.apps definition=tableDefinition}} {{em-table columns=serviceColumns rows=model.apps definition=tableDefinition}}