mirror of
				https://github.com/datahub-project/datahub.git
				synced 2025-10-31 02:37:05 +00:00 
			
		
		
		
	Finalize handling for api for metadata health endpoint and showing results
This commit is contained in:
		
							parent
							
								
									7cc30b7e8b
								
							
						
					
					
						commit
						1ececa7c1b
					
				| @ -4,10 +4,12 @@ import { task } from 'ember-concurrency'; | ||||
| import ComputedProperty from '@ember/object/computed'; | ||||
| import { IChartDatum } from 'wherehows-web/typings/app/visualization/charts'; | ||||
| import { IHealthScore, IDatasetHealth } from 'wherehows-web/typings/api/datasets/health'; | ||||
| import { healthCategories, healthSeverity, healthDetail } from 'wherehows-web/constants/data/temp-mock/health'; | ||||
| import { readDatasetHealthByUrn } from 'wherehows-web/utils/api/datasets/health'; | ||||
| import { readDatasetHealthByUrn, getCategory } from 'wherehows-web/utils/api/datasets/health'; | ||||
| import { Tabs } from 'wherehows-web/constants/datasets/shared'; | ||||
| import { equal } from '@ember-decorators/object/computed'; | ||||
| import { IObject } from 'wherehows-web/typings/generic'; | ||||
| import { service } from '@ember-decorators/service'; | ||||
| import DatasetMeta from 'wherehows-web/services/dataset-meta'; | ||||
| 
 | ||||
| /** | ||||
|  * Used for the dataset health tab, represents the fieldnames for the health score table | ||||
| @ -88,6 +90,9 @@ export default class DatasetHealthContainer extends Component { | ||||
|   @equal('tabSelected', Tabs.Health) | ||||
|   isActiveTab: boolean; | ||||
| 
 | ||||
|   @service | ||||
|   datasetMeta: ComputedProperty<DatasetMeta>; | ||||
| 
 | ||||
|   /** | ||||
|    * Modified categoryMetrics to add properties that will help us render our actual charts without modifying the original | ||||
|    * data | ||||
| @ -145,21 +150,40 @@ export default class DatasetHealthContainer extends Component { | ||||
|    * @type {Task<TaskInstance<Promise<any>>, (a?: any) => TaskInstance<TaskInstance<Promise<any>>>>} | ||||
|    */ | ||||
|   getContainerDataTask = task(function*(this: DatasetHealthContainer): IterableIterator<Promise<IDatasetHealth>> { | ||||
|     const { health } = yield readDatasetHealthByUrn(get(this, 'urn')); | ||||
|     // Pretend like we're getting data from somehwere
 | ||||
|     const healthData = { | ||||
|       categories: healthCategories, | ||||
|       severity: healthSeverity, | ||||
|       detail: healthDetail | ||||
|     }; | ||||
|     const health = <IDatasetHealth>yield readDatasetHealthByUrn(get(this, 'urn')); | ||||
| 
 | ||||
|     setProperties(this, { | ||||
|       categoryMetrics: healthData.categories, | ||||
|       severityMetrics: healthData.severity, | ||||
|       tableData: healthData.detail | ||||
|     const details = health.validations || []; | ||||
|     const total = details.length; | ||||
|     const categories: IObject<number> = {}; | ||||
|     const severities: IObject<number> = {}; | ||||
| 
 | ||||
|     // Go through the details and find the COUNT of severity and category groupings
 | ||||
|     const tableData: Array<IHealthScore> = details.map(detail => { | ||||
|       const category = getCategory(detail.validator); | ||||
|       const severity = detail.tier || 'none'; | ||||
|       categories[category] = (categories[category] || 0) + 1; | ||||
|       severities[severity] = (severities[severity] || 0) + 1; | ||||
| 
 | ||||
|       return { category, severity, description: detail.description, score: detail.score * 100 }; | ||||
|     }); | ||||
| 
 | ||||
|     return health; // Do something with health information
 | ||||
|     const categoryMetrics: Array<IChartDatum> = Object.keys(categories).map(category => ({ | ||||
|       name: category, | ||||
|       value: Math.round((categories[category] / total) * 100) | ||||
|     })); | ||||
| 
 | ||||
|     const severityMetrics: Array<IChartDatum> = Object.keys(severities).map(severity => ({ | ||||
|       name: severity, | ||||
|       value: Math.round((severities[severity] / total) * 100) | ||||
|     })); | ||||
| 
 | ||||
|     get(this, 'datasetMeta').set('healthScore', health.score * 100 || 0); | ||||
| 
 | ||||
|     setProperties(this, { | ||||
|       categoryMetrics, | ||||
|       severityMetrics, | ||||
|       tableData | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   /** | ||||
|  | ||||
| @ -7,6 +7,9 @@ import { Tabs } from 'wherehows-web/constants/datasets/shared'; | ||||
| import { action } from '@ember-decorators/object'; | ||||
| import { DatasetPlatform } from 'wherehows-web/constants'; | ||||
| import { IDatasetView } from 'wherehows-web/typings/api/datasets/dataset'; | ||||
| import { alias } from '@ember-decorators/object/computed'; | ||||
| import DatasetMeta from 'wherehows-web/services/dataset-meta'; | ||||
| import { service } from '@ember-decorators/service'; | ||||
| 
 | ||||
| export default class DatasetController extends Controller { | ||||
|   queryParams = ['urn']; | ||||
| @ -102,6 +105,21 @@ export default class DatasetController extends Controller { | ||||
|    */ | ||||
|   datasetContainsPersonalData: boolean; | ||||
| 
 | ||||
|   /** | ||||
|    * Including the datasetmeta property that is connected to each child container for the routable | ||||
|    * tabs. Can be used to share information between these tabs from a higher level | ||||
|    * @type {Ember.Service} | ||||
|    */ | ||||
|   @service | ||||
|   datasetMeta: ComputedProperty<DatasetMeta>; | ||||
| 
 | ||||
|   /** | ||||
|    * Easy access in the template to the datasetMeta health score provided by the /health endpoint | ||||
|    * called in the dataset-health container | ||||
|    */ | ||||
|   @alias('datasetMeta.healthScore') | ||||
|   datasetHealthScore: ComputedProperty<number>; | ||||
| 
 | ||||
|   /** | ||||
|    * Flag indicating that the compliance policy needs user attention | ||||
|    * @type {ComputedProperty<boolean>} | ||||
| @ -121,6 +139,12 @@ export default class DatasetController extends Controller { | ||||
|     return encodeUrn(uri); | ||||
|   }); | ||||
| 
 | ||||
|   shouldShowHealthGauge: ComputedProperty<boolean> = computed('datasetHealthScore', function( | ||||
|     this: DatasetController | ||||
|   ): boolean { | ||||
|     return typeof get(this, 'datasetHealthScore') === 'number'; | ||||
|   }); | ||||
| 
 | ||||
|   /** | ||||
|    * Checks if the current platform exists in the supported list of JIT ACL whitelisted platforms | ||||
|    * @type {ComputedProperty<boolean>} | ||||
|  | ||||
							
								
								
									
										15
									
								
								wherehows-web/app/services/dataset-meta.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								wherehows-web/app/services/dataset-meta.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| import Service from '@ember/service'; | ||||
| 
 | ||||
| /** | ||||
|  * The dataset meta service can be used to share information between dataset route containers. | ||||
|  * Used to share health score but can be expanded to other meta informations | ||||
|  */ | ||||
| export default class DatasetMeta extends Service { | ||||
|   healthScore: number; | ||||
| } | ||||
| 
 | ||||
| declare module '@ember/service' { | ||||
|   interface Registry { | ||||
|     'dataset-meta': DatasetMeta; | ||||
|   } | ||||
| } | ||||
| @ -62,10 +62,12 @@ | ||||
|               class="dataset-owner-list" | ||||
|               shouldShowDatasetHealth=shouldShowDatasetHealth}} | ||||
| 
 | ||||
|             {{visualization/charts/score-gauge | ||||
|               class="dataset-health-score" | ||||
|               score=83 | ||||
|               title="Health Score:"}} | ||||
|             {{#if shouldShowHealthGauge}} | ||||
|               {{visualization/charts/score-gauge | ||||
|                 class="dataset-health-score" | ||||
|                 score=datasetHealthScore | ||||
|                 title="Health Score:"}} | ||||
|             {{/if}} | ||||
|           {{/if}} | ||||
|         </div> | ||||
| 
 | ||||
|  | ||||
| @ -9,6 +9,26 @@ import { IHealthScoreResponse, IDatasetHealth } from 'wherehows-web/typings/api/ | ||||
|  */ | ||||
| const datasetHealthUrlByUrn = (urn: string): string => `${datasetUrlByUrn(urn)}/health`; | ||||
| 
 | ||||
| /** | ||||
|  * Constant for formatting of the validator string | ||||
|  * @type {string} | ||||
|  */ | ||||
| const validatorFormat = 'com.linkedin.metadata.validators'; | ||||
| 
 | ||||
| /** | ||||
|  * Useful for removing extraneous information outside of category | ||||
|  * @type {RegExp} | ||||
|  */ | ||||
| const validationRegex = new RegExp(`${validatorFormat}.|Validator`, 'gi'); | ||||
| 
 | ||||
| /** | ||||
|  * Given a string in the format 'com.linkedin.metadata.validators.[Category]Validator', extract | ||||
|  * Category and return it. | ||||
|  * @param validator - Given validator string | ||||
|  * @returns {string} | ||||
|  */ | ||||
| export const getCategory = (validator: string) => validator.replace(validationRegex, ''); | ||||
| 
 | ||||
| export const readDatasetHealthByUrn = async (urn: string): Promise<IDatasetHealth> => { | ||||
|   const defaultResponse = { score: 0, validations: [] }; | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										14
									
								
								wherehows-web/tests/unit/services/dataset-meta-test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								wherehows-web/tests/unit/services/dataset-meta-test.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| import { module, test } from 'qunit'; | ||||
| import { setupTest } from 'ember-qunit'; | ||||
| 
 | ||||
| module('Unit | Service | dataset-meta', function(hooks) { | ||||
|   setupTest(hooks); | ||||
| 
 | ||||
|   test('it exists', function(assert) { | ||||
|     let service = this.owner.lookup('service:dataset-meta'); | ||||
|     assert.ok(service); | ||||
| 
 | ||||
|     service.set('healthScore', 50); | ||||
|     assert.equal(service.get('healthScore'), 50); | ||||
|   }); | ||||
| }); | ||||
| @ -0,0 +1,10 @@ | ||||
| import { module, test } from 'qunit'; | ||||
| import { getCategory } from 'wherehows-web/utils/api/datasets/health'; | ||||
| 
 | ||||
| module('Unit | Utility | api/datasets/health', function() { | ||||
|   test('extracting category from validator string works', function(assert) { | ||||
|     const testSTtring = 'com.linkedin.metadata.validators.OwnershipValidator'; | ||||
| 
 | ||||
|     assert.equal(getCategory(testSTtring), 'Ownership'); | ||||
|   }); | ||||
| }); | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 cptran777
						cptran777