Skip to content
This repository has been archived by the owner on Nov 22, 2019. It is now read-only.

Commit

Permalink
TEIIDTOOLS-330: Provides publishing notification
Browse files Browse the repository at this point in the history
* Provides a cog icon in top-left of dataservice cards indicating their
  published (to Openshift) status

* Updates in the same manner as dataservice deployment status

* Uses a Virtualization as the model for holding the status information
  for a published service. Only the PublishState is used currently but
  their is scope for providing the other information for greater monitoring
  and management.
  • Loading branch information
phantomjinx committed Mar 26, 2018
1 parent 66b4b8e commit 1ed97ff
Show file tree
Hide file tree
Showing 11 changed files with 394 additions and 33 deletions.
Expand Up @@ -6,7 +6,7 @@

.card-toolbar .secondary-action[title="Publish"]:before {
color: var(--card-action-icon-color);
content: "\f08e";
content: "\f085";
font-family: "FontAwesome";
}

Expand Down
Expand Up @@ -78,6 +78,35 @@
data-placement="right"
title="Edit">
</span>

<span class="pull-left fa fa-cogs fa-2x card-action-icon"
style="color:grey;"
*ngIf="dataservice.serviceNotPublished"
data-toggle="tooltip"
data-placement="right"
title="Not Published">
</span>
<span class="pull-left fa fa-cogs fa-2x card-action-icon"
style="color:red;"
*ngIf="dataservice.servicePublishFailed"
data-toggle="tooltip"
data-placement="right"
title="Publishing Failed">
</span>
<span class="pull-left fa fa-cog fa-spin fa-2x card-action-icon"
style="color:orange;"
*ngIf="dataservice.servicePublishing"
data-toggle="tooltip"
data-placement="right"
title="Publishing">
</span>
<span class="pull-left fa fa-cogs fa-2x card-action-icon"
style="color:green;"
*ngIf="dataservice.servicePublished"
data-toggle="tooltip"
data-placement="right"
title="Published">
</span>
</div>
<div class="row card-pf-title text-center object-card-title">
<span class="fa fa-table object-inline-icon"></span>
Expand Down
Expand Up @@ -8,7 +8,7 @@
/* Adds an icon to the left of the publish action item in dropdown of kebab. */
.object-list .secondary-action[title*="Publish"]:before {
color: var(--card-action-icon-color);
content: "\f08e";
content: "\f085";
font-family: "FontAwesome";
}

Expand Down
49 changes: 36 additions & 13 deletions ngapp/src/app/dataservices/dataservices.component.ts
Expand Up @@ -25,6 +25,8 @@ import { Dataservice } from "@dataservices/shared/dataservice.model";
import { DataserviceService } from "@dataservices/shared/dataservice.service";
import { DataservicesConstants } from "@dataservices/shared/dataservices-constants";
import { DeploymentState } from "@dataservices/shared/deployment-state.enum";
import { PublishState } from "@dataservices/shared/publish-state.enum";
import { Virtualization } from "@dataservices/shared/virtualization.model";
import { NotifierService } from "@dataservices/shared/notifier.service";
import { Table } from "@dataservices/shared/table.model";
import { VdbService } from "@dataservices/shared/vdb.service";
Expand Down Expand Up @@ -58,8 +60,8 @@ import { Subscription } from "rxjs/Subscription";
export class DataservicesComponent extends AbstractPageComponent implements OnInit {

public readonly exportInProgressHeader: string = "Publishing: ";
public readonly exportSuccessHeader: string = "Publish Succeeded: ";
public readonly exportFailedHeader: string = "Publish Failed: ";
public readonly exportSuccessHeader: string = "Publishing Begun: ";
public readonly exportFailedHeader: string = "Publishing Failed: ";
public readonly connectionsLoadedTag = "connections";

public readonly downloadInProgressHeader: string = "Downloading: ";
Expand Down Expand Up @@ -97,7 +99,8 @@ export class DataservicesComponent extends AbstractPageComponent implements OnIn
private exportNotificationMessage: string;
private exportNotificationType = NotificationType.SUCCESS;
private exportNotificationVisible = false;
private dataserviceStateSubscription: Subscription;
private dataserviceDeployStateSubscription: Subscription;
private dataservicePublishStateSubscription: Subscription;
private notifierService: NotifierService;
private wizardService: WizardService;
private selectedSvcViews: Table[] = [];
Expand All @@ -116,9 +119,13 @@ export class DataservicesComponent extends AbstractPageComponent implements OnIn
this.vdbService = vdbService;
this.notifierService = notifierService;
this.wizardService = wizardService;
// Register for dataservice deployment state changes
this.dataserviceDeployStateSubscription = this.notifierService.getDataserviceDeployStateMap().subscribe((serviceStateMap) => {
this.onDataserviceDeploymentStateChanged(serviceStateMap);
});
// Register for dataservice state changes
this.dataserviceStateSubscription = this.notifierService.getDataserviceStateMap().subscribe((serviceStateMap) => {
this.onDataserviceStateChanged(serviceStateMap);
this.dataservicePublishStateSubscription = this.notifierService.getDataserviceVirtualizationMap().subscribe((serviceStateMap) => {
this.onDataservicePublishStateChanged(serviceStateMap);
});
this.connectionService = connectionService;
}
Expand Down Expand Up @@ -438,6 +445,9 @@ export class DataservicesComponent extends AbstractPageComponent implements OnIn
}

public onPublish(svcName: string): void {
const selectedService = this.filteredDataservices.find((x) => x.getId() === svcName);
const virtual: Virtualization = new Virtualization(selectedService.getServiceVdbName(), PublishState.PUBLISHING);
selectedService.setServiceVirtualization(virtual);
this.setQuickLookPanelOpenState(false);

this.exportNotificationHeader = this.exportInProgressHeader;
Expand All @@ -449,15 +459,15 @@ export class DataservicesComponent extends AbstractPageComponent implements OnIn
this.dataserviceService
.publishDataservice(svcName)
.subscribe(
(wasSuccess) => {
(status) => {
self.exportNotificationHeader = this.exportSuccessHeader;
self.exportNotificationMessage = " " + svcName + " publishing successfully initiated!";
self.exportNotificationType = NotificationType.SUCCESS;
this.logger.log("[DataservicesPageComponent] Dataservice publishing initiation was successful");
self.exportNotificationMessage = " " + svcName + " publishing successfully initiated.";
self.exportNotificationType = NotificationType.INFO;
this.logger.log("[DataservicesPageComponent] Initiated publishing of dataservice");
},
(error) => {
self.exportNotificationHeader = this.exportFailedHeader;
self.exportNotificationMessage = " Failed to publish dataservice " + svcName + "!";
self.exportNotificationMessage = " Failed to publish dataservice " + svcName + ".";
self.exportNotificationType = NotificationType.DANGER;
this.logger.log("[DataservicesPageComponent] Publish dataservice " + svcName + " failed.");
}
Expand Down Expand Up @@ -675,10 +685,10 @@ export class DataservicesComponent extends AbstractPageComponent implements OnIn
}

/*
* Update the displayed dataservice states using the provided states
* Update the displayed dataservice deployment states using the provided states
*/
private onDataserviceStateChanged(stateMap: Map<string, DeploymentState>): void {
// For displayed dataservices, update the State using supplied services
private onDataserviceDeploymentStateChanged(stateMap: Map<string, DeploymentState>): void {
// For displayed dataservices, update the Deployment State using supplied services
for ( const dService of this.filteredDataservices ) {
const serviceId = dService.getId();
if (stateMap && stateMap.has(serviceId)) {
Expand All @@ -687,6 +697,19 @@ export class DataservicesComponent extends AbstractPageComponent implements OnIn
}
}

/*
* Update the displayed dataservice publish states using the provided states
*/
private onDataservicePublishStateChanged(stateMap: Map<string, Virtualization>): void {
// For displayed dataservices, update the Publish State using supplied services
for ( const dService of this.filteredDataservices ) {
const serviceId = dService.getId();
if (stateMap && stateMap.has(serviceId)) {
dService.setServiceVirtualization(stateMap.get(serviceId));
}
}
}

/*
* Update quick look results using the supplied dataservice
* @param {string} svcName the dataservice name
Expand Down
49 changes: 49 additions & 0 deletions ngapp/src/app/dataservices/shared/dataservice.model.ts
Expand Up @@ -16,6 +16,8 @@
*/

import { DeploymentState } from "@dataservices/shared/deployment-state.enum";
import { PublishState } from "@dataservices/shared/publish-state.enum";
import { Virtualization } from "@dataservices/shared/virtualization.model";
import { Identifiable } from "@shared/identifiable";
import { SortDirection } from "@shared/sort-direction.enum";

Expand All @@ -29,6 +31,7 @@ export class Dataservice implements Identifiable< string > {
private serviceViewModel: string;
private serviceViewTables: string[];
private deploymentState: DeploymentState = DeploymentState.LOADING;
private virtualization: Virtualization = null;

/**
* @param {Object} json the JSON representation of a Dataservice
Expand Down Expand Up @@ -190,6 +193,45 @@ export class Dataservice implements Identifiable< string > {
return this.deploymentState === DeploymentState.NOT_DEPLOYED;
}

/**
* @returns {DeploymentState} the dataservice Deployment state
*/
public getServicePublishState(): PublishState {
return this.virtualization ? this.virtualization.getPublishState() : PublishState.NOT_PUBLISHED;
}

/**
* Accessor to determine if service has not been published
* @returns {boolean} the dataservice service not published state
*/
public get serviceNotPublished(): boolean {
return this.getServicePublishState() === PublishState.NOT_PUBLISHED;
}

/**
* Accessor to determine if service publishing is active
* @returns {boolean} the dataservice service publishing active state
*/
public get servicePublishing(): boolean {
return this.getServicePublishState() === PublishState.PUBLISHING;
}

/**
* Accessor to determine if service has been published
* @returns {boolean} the dataservice service published state
*/
public get servicePublished(): boolean {
return this.getServicePublishState() === PublishState.PUBLISHED;
}

/**
* Accessor to determine if service has failed publishing
* @returns {boolean} the dataservice service publishing failed state
*/
public get servicePublishFailed(): boolean {
return this.getServicePublishState() === PublishState.FAILED;
}

/**
* @param {string} id the dataservice identifier (optional)
*/
Expand Down Expand Up @@ -246,6 +288,13 @@ export class Dataservice implements Identifiable< string > {
this.deploymentState = state;
}

/**
* @param {Virtualization} state the dataservice virtualization
*/
public setServiceVirtualization( state: Virtualization ): void {
this.virtualization = state ? state : null;
}

// overrides toJSON - we do not want the appSettings
public toJSON(): {} {
return {
Expand Down
68 changes: 58 additions & 10 deletions ngapp/src/app/dataservices/shared/dataservice.service.ts
Expand Up @@ -24,13 +24,15 @@ import { Connection } from "@connections/shared/connection.model";
import { Dataservice } from "@dataservices/shared/dataservice.model";
import { DataservicesConstants } from "@dataservices/shared/dataservices-constants";
import { DeploymentState } from "@dataservices/shared/deployment-state.enum";
import { PublishState } from "@dataservices/shared/publish-state.enum";
import { NewDataservice } from "@dataservices/shared/new-dataservice.model";
import { NotifierService } from "@dataservices/shared/notifier.service";
import { QueryResults } from "@dataservices/shared/query-results.model";
import { Table } from "@dataservices/shared/table.model";
import { VdbStatus } from "@dataservices/shared/vdb-status.model";
import { VdbService } from "@dataservices/shared/vdb.service";
import { VdbsConstants } from "@dataservices/shared/vdbs-constants";
import { Virtualization } from "@dataservices/shared/virtualization.model";
import { environment } from "@environments/environment";
import { Observable } from "rxjs/Observable";
import { ReplaySubject } from "rxjs/ReplaySubject";
Expand All @@ -55,7 +57,8 @@ export class DataserviceService extends ApiService {
private vdbService: VdbService;
private selectedDataservice: Dataservice;
private dataserviceCurrentView: Table[] = [];
private cachedDataserviceStates: Map<string, DeploymentState> = new Map<string, DeploymentState>();
private cachedDataserviceDeployStates: Map<string, DeploymentState> = new Map<string, DeploymentState>();
private cachedDataserviceVirtualizations: Map<string, Virtualization> = new Map<string, Virtualization>();
private updatesSubscription: Subscription;

constructor(http: Http, vdbService: VdbService, appSettings: AppSettingsService,
Expand Down Expand Up @@ -244,8 +247,7 @@ export class DataserviceService extends ApiService {
* @param {string} model1Name,
* @returns {Observable<boolean>}
*/
public createReadonlyDataRole(dataserviceName: string, model1Name: string): Observable<boolean> {
const serviceVdbName = dataserviceName + this.serviceVdbSuffix;
public createReadonlyDataRole(serviceVdbName: string, model1Name: string): Observable<boolean> {
const READ_ONLY_DATA_ROLE_NAME = VdbsConstants.DEFAULT_READONLY_DATA_ROLE;
const VIEW_MODEL = VdbsConstants.SERVICE_VIEW_MODEL_NAME;
const userWorkspacePath = this.getKomodoUserWorkspacePath();
Expand Down Expand Up @@ -440,7 +442,6 @@ export class DataserviceService extends ApiService {
.post(url, payload, this.getAuthRequestOptions())
.map((response) => {
let status = response.json();
console.log("Response: " + response);

if (! status.downloadable) {
throw new Error(payload.dataPath + " is not downloadable");
Expand Down Expand Up @@ -483,6 +484,12 @@ export class DataserviceService extends ApiService {
return this.http
.post(url, payload, this.getAuthRequestOptions())
.map((response) => {
let status = response.json();

if (status.Information && status.Information['Build Status'] === 'FAILED') {
throw new Error(status.Information['Build Message']);
}

return response.ok;
})
.catch( ( error ) => this.handleError( error ) );
Expand Down Expand Up @@ -524,11 +531,12 @@ export class DataserviceService extends ApiService {
this.getAllDataservices()
.subscribe(
(dataservices) => {
self.updateServiceStateMap(dataservices);
self.updateServiceStateMaps(dataservices);
},
(error) => {
// On error, broadcast the cached states
this.notifierService.sendDataserviceStateMap(this.cachedDataserviceStates);
this.notifierService.sendDataserviceDeployStateMap(this.cachedDataserviceDeployStates);
this.notifierService.sendDataserviceVirtualizationMap(this.cachedDataserviceVirtualizations);
}
);
}
Expand All @@ -552,17 +560,28 @@ export class DataserviceService extends ApiService {
* Get updates for the provided array of Dataservices and broadcast the map of states
* @param {Dataservice[]} services the array of Dataservices
*/
private updateServiceStateMap(services: Dataservice[]): void {
private updateServiceStateMaps(services: Dataservice[]): void {
const self = this;
this.vdbService.getTeiidVdbStatuses()
.subscribe(
(vdbStatuses) => {
self.cachedDataserviceStates = self.createDeploymentStateMap(services, vdbStatuses);
this.notifierService.sendDataserviceStateMap(self.cachedDataserviceStates);
self.cachedDataserviceDeployStates = self.createDeploymentStateMap(services, vdbStatuses);
this.notifierService.sendDataserviceDeployStateMap(self.cachedDataserviceDeployStates);
},
(error) => {
// On error, broadcast the cached states
this.notifierService.sendDataserviceStateMap(self.cachedDataserviceStates);
this.notifierService.sendDataserviceDeployStateMap(self.cachedDataserviceDeployStates);
}
);
this.vdbService.getVirtualizations()
.subscribe(
(vdbStatuses) => {
self.cachedDataserviceVirtualizations = self.createPublishStateMap(services, vdbStatuses);
this.notifierService.sendDataserviceVirtualizationMap(self.cachedDataserviceVirtualizations);
},
(error) => {
// On error, broadcast the cached states
this.notifierService.sendDataserviceVirtualizationMap(self.cachedDataserviceVirtualizations);
}
);
}
Expand Down Expand Up @@ -603,4 +622,33 @@ export class DataserviceService extends ApiService {
return dsStateMap;
}

/*
* Creates a Map of dataservice name to PublishState, given the list of dataservices and virtualizations
* @param {Dataservice[]} dataservices the Dataservice array
* @param {virtualization[]} virtualizations the Virtualization array
* @returns {Map<string,PublishState>} the map of dataservice name to PublishState
*/
private createPublishStateMap(dataservices: Dataservice[], virtualizations: Virtualization[]): Map<string, Virtualization> {
const dsStateMap: Map<string, Virtualization> = new Map<string, Virtualization>();

// For each dataservice, find the corresponding Virtualization. Add the map entry
for ( const dService of dataservices ) {
const serviceId = dService.getId();
const serviceVdbName = dService.getServiceVdbName();
let statusFound = false;
for ( const virtualization of virtualizations ) {
if ( virtualization.getVdbName() === serviceVdbName ) {
statusFound = true;
dsStateMap.set(serviceId, virtualization);
}
}

if ( !statusFound ) {
const virtual = new Virtualization(serviceVdbName, PublishState.NOT_PUBLISHED);
dsStateMap.set(serviceId, virtual);
}
}

return dsStateMap;
}
}

0 comments on commit 1ed97ff

Please sign in to comment.