From 92a3f7f19e859eecc9945cbad1d8fe533abed16a Mon Sep 17 00:00:00 2001 From: Seyi Adebajo Date: Wed, 28 Feb 2018 16:31:37 -0800 Subject: [PATCH] converts a dataset id to urn using urntoid endpoint. refactors a check for notfound into an api utility function --- .../datasets/containers/dataset-compliance.ts | 5 +- .../app/controllers/datasets/dataset.js | 3 +- wherehows-web/app/routes/datasets/dataset.js | 5 +- .../app/utils/api/datasets/compliance.ts | 5 +- .../app/utils/api/datasets/dataset.ts | 89 ++----------------- .../app/utils/api/datasets/owners.ts | 5 +- wherehows-web/app/utils/api/fetcher.ts | 8 +- wherehows-web/app/utils/api/shared.ts | 9 ++ 8 files changed, 33 insertions(+), 96 deletions(-) diff --git a/wherehows-web/app/components/datasets/containers/dataset-compliance.ts b/wherehows-web/app/components/datasets/containers/dataset-compliance.ts index b84f010878..ec10a69733 100644 --- a/wherehows-web/app/components/datasets/containers/dataset-compliance.ts +++ b/wherehows-web/app/components/datasets/containers/dataset-compliance.ts @@ -11,15 +11,14 @@ import { IDatasetView } from 'wherehows-web/typings/api/datasets/dataset'; import { IDatasetSchema } from 'wherehows-web/typings/api/datasets/schema'; import { IComplianceDataType } from 'wherehows-web/typings/api/list/compliance-datatypes'; import { - ApiResponseStatus, IReadComplianceResult, + notFoundApiError, readDatasetComplianceByUrn, readDatasetComplianceSuggestionByUrn, saveDatasetComplianceByUrn } from 'wherehows-web/utils/api'; import { columnDataTypesAndFieldNames } from 'wherehows-web/utils/api/datasets/columns'; import { readDatasetSchemaByUrn } from 'wherehows-web/utils/api/datasets/schema'; -import { ApiError } from 'wherehows-web/utils/api/errors/errors'; import { readComplianceDataTypes } from 'wherehows-web/utils/api/list/compliance-datatypes'; import { compliancePolicyStrings, removeReadonlyAttr, filterEditableEntities } from 'wherehows-web/constants'; @@ -160,7 +159,7 @@ export default class DatasetComplianceContainer extends Component { setProperties(this, { schemaFieldNamesMappedToDataTypes, schemaless }); } catch (e) { // If this schema is missing, silence exception, otherwise propagate - if (!(e instanceof ApiError && e.status === ApiResponseStatus.NotFound)) { + if (!notFoundApiError(e)) { throw e; } } diff --git a/wherehows-web/app/controllers/datasets/dataset.js b/wherehows-web/app/controllers/datasets/dataset.js index 347070dd4a..1ee2e649a5 100644 --- a/wherehows-web/app/controllers/datasets/dataset.js +++ b/wherehows-web/app/controllers/datasets/dataset.js @@ -1,9 +1,9 @@ import Controller from '@ember/controller'; import { computed, set, get, setProperties, getProperties, getWithDefault } from '@ember/object'; import { debug } from '@ember/debug'; +import $ from 'jquery'; import { inject as service } from '@ember/service'; import { run, scheduleOnce } from '@ember/runloop'; -import $ from 'jquery'; import { datasetComplianceUrlById, createDatasetComment, @@ -13,7 +13,6 @@ import { } from 'wherehows-web/utils/api'; import { encodeUrn } from 'wherehows-web/utils/validators/urn'; import { updateDatasetDeprecation } from 'wherehows-web/utils/api/datasets/properties'; -import { readDatasetView } from 'wherehows-web/utils/api/datasets/dataset'; import { readDatasetOwners, updateDatasetOwners } from 'wherehows-web/utils/api/datasets/owners'; import { Tabs } from 'wherehows-web/constants/datasets/shared'; import { action } from 'ember-decorators/object'; diff --git a/wherehows-web/app/routes/datasets/dataset.js b/wherehows-web/app/routes/datasets/dataset.js index 2b45651cee..8cba4acf6e 100644 --- a/wherehows-web/app/routes/datasets/dataset.js +++ b/wherehows-web/app/routes/datasets/dataset.js @@ -3,7 +3,7 @@ import { set, get, setProperties } from '@ember/object'; import { inject } from '@ember/service'; import { makeUrnBreadcrumbs } from 'wherehows-web/utils/entities'; import { isRequiredMinOwnersNotConfirmed } from 'wherehows-web/constants/datasets/owner'; -import { readDatasetById, readDatasetByUrn } from 'wherehows-web/utils/api/datasets/dataset'; +import { datasetIdToUrn, readDatasetByUrn } from 'wherehows-web/utils/api/datasets/dataset'; import isUrn, { isWhUrn, isLiUrn, convertWhUrnToLiUrn, encodeUrn, decodeUrn } from 'wherehows-web/utils/validators/urn'; import { checkAclAccess } from 'wherehows-web/utils/api/datasets/acl-access'; @@ -48,7 +48,8 @@ export default Route.extend({ }); } - return await readDatasetById(identifier); + // recurse with dataset urn from id + return this.model({ dataset_id: await datasetIdToUrn(identifier) }); }, /** diff --git a/wherehows-web/app/utils/api/datasets/compliance.ts b/wherehows-web/app/utils/api/datasets/compliance.ts index 9e8a22377c..72c3838503 100644 --- a/wherehows-web/app/utils/api/datasets/compliance.ts +++ b/wherehows-web/app/utils/api/datasets/compliance.ts @@ -1,6 +1,5 @@ import { assert } from '@ember/debug'; -import { ApiResponseStatus } from 'wherehows-web/utils/api'; -import { ApiError } from 'wherehows-web/utils/api/errors/errors'; +import { notFoundApiError } from 'wherehows-web/utils/api'; import { createInitialComplianceInfo } from 'wherehows-web/utils/datasets/compliance-policy'; import { datasetUrlById, datasetUrlByUrn } from 'wherehows-web/utils/api/datasets/shared'; import { ApiStatus } from 'wherehows-web/utils/api/shared'; @@ -98,7 +97,7 @@ const readDatasetComplianceByUrn = async (urn: string): Promise `${datasetUrlById(id)}/view`; - -/** - * Reads the dataset object from the get endpoint for the given dataset id - * @param {number} id the id of the dataset - * @return {Promise} - */ -const readDatasetById = async (id: number | string): Promise => { - id = parseInt(id + '', 10); - // if id is less than or equal 0, throw illegal dataset error - if (id <= 0 || !Number.isInteger(id)) { - throw new TypeError(datasetIdException); - } - - const { status, dataset, message } = await getJSON({ url: datasetUrlById(id) }); - let errorMessage = message || datasetApiException; - - if (status === ApiStatus.OK && dataset) { - return dataset; - } - - throw new Error(errorMessage); -}; - /** * Reads a dataset by urn, in the li format * @param {string} urn @@ -61,54 +24,20 @@ const readDatasetByUrn = async (urn: string = ''): Promise => { }; /** - * Reads the response from the datasetView endpoint for the provided dataset id + * Constructs a url to get a dataset urn given a dataset id * @param {number} id - * @returns {Promise} - */ -const readDatasetView = async (id: number): Promise => { - const { status, dataset } = await getJSON({ url: datasetViewUrlById(id) }); - - if (status === ApiStatus.OK && dataset) { - return dataset; - } - - throw new Error(datasetApiException); -}; - -/** - * Constructs a url to get a dataset id given a dataset urn - * @param {string} urn * @return {string} */ -const datasetIdTranslationUrlByUrn = (urn: string): string => { - return `${datasetsUrlRoot('v1')}/urntoid/${encodeURIComponent(urn)}`; -}; +const datasetUrnTranslationUrlByUrn = (id: number): string => `${datasetsUrlRoot('v2')}/idtourn/${id}`; /** - * Translates a dataset urn string to a dataset id, using the endpoint at datasetIdTranslationUrlByUrn() - * if a dataset id is not found - * or an exception occurs, the value returned is zero, which is an illegal dataset id - * and should be treated as an exception. - * @param {string} urn - * @return {Promise} + * Translates a dataset id to a dataset urn, using the endpoint at datasetIdTranslationUrlByUrn() + * @param {number} id + * @return {Promise} */ -const datasetUrnToId = async (urn: string): Promise => { - let datasetId = 0; - - try { - // The headers object is a Header - const headers = await getHeaders({ url: datasetIdTranslationUrlByUrn(urn) }); - const stringId = headers.get('datasetid'); - - // If stringId is not falsey, parse as int and return, otherwise use default - if (stringId) { - datasetId = parseInt(stringId, 10); - } - } catch (e) { - warn(`Exception occurred translating datasetUrn: ${e.message}`); - } - - return datasetId; +const datasetIdToUrn = async (id: number) => { + const headers = await getHeaders({ url: datasetUrnTranslationUrlByUrn(id) }); + return headers.get('whUrn'); }; /** @@ -140,4 +69,4 @@ const readDatasetsCount = async ({ platform, prefix }: Partial({ url }); }; -export { readDatasetById, datasetUrnToId, readDatasetView, readDatasets, readDatasetsCount, readDatasetByUrn }; +export { readDatasets, readDatasetsCount, readDatasetByUrn, datasetIdToUrn }; diff --git a/wherehows-web/app/utils/api/datasets/owners.ts b/wherehows-web/app/utils/api/datasets/owners.ts index 69da042e7e..4b00f6461d 100644 --- a/wherehows-web/app/utils/api/datasets/owners.ts +++ b/wherehows-web/app/utils/api/datasets/owners.ts @@ -10,9 +10,8 @@ import { IPartyProps, IUserEntityMap } from 'wherehows-web/typings/api/datasets/party-entities'; -import { ApiResponseStatus } from 'wherehows-web/utils/api'; +import { notFoundApiError } from 'wherehows-web/utils/api'; import { datasetUrlById, datasetUrlByUrn } from 'wherehows-web/utils/api/datasets/shared'; -import { ApiError } from 'wherehows-web/utils/api/errors/errors'; import { getJSON, postJSON } from 'wherehows-web/utils/api/fetcher'; import { getApiRoot, ApiStatus } from 'wherehows-web/utils/api/shared'; import { arrayFilter, arrayMap } from 'wherehows-web/utils/array'; @@ -128,7 +127,7 @@ const readDatasetOwnersByUrn = async (urn: string): Promise> => { ({ owners = [] } = await getJSON>({ url: datasetOwnersUrlByUrn(urn) })); return ownersWithModifiedTimeAsDate(owners); } catch (e) { - if (e instanceof ApiError && e.status === ApiResponseStatus.NotFound) { + if (notFoundApiError(e)) { return owners; } else { throw e; diff --git a/wherehows-web/app/utils/api/fetcher.ts b/wherehows-web/app/utils/api/fetcher.ts index 5cf20b5979..ebc0af0845 100644 --- a/wherehows-web/app/utils/api/fetcher.ts +++ b/wherehows-web/app/utils/api/fetcher.ts @@ -1,5 +1,6 @@ import fetch from 'fetch'; -import { throwIfApiError } from 'wherehows-web/utils/api/errors/errors'; +import { apiErrorStatusMessage } from 'wherehows-web/constants/errors/errors'; +import { ApiError, throwIfApiError } from 'wherehows-web/utils/api/errors/errors'; /** * Describes the attributes on the fetch configuration object @@ -112,13 +113,14 @@ const getHeaders = async (config: FetchConfig): Promise => { ...withBaseFetchHeaders(config.headers), method: 'HEAD' }; - const { ok, headers, statusText } = await fetch(config.url, fetchConfig); + const response = await fetch(config.url, fetchConfig); + const { ok, headers, status } = response; if (ok) { return headers; } - throw new Error(statusText); + throw new ApiError(status, apiErrorStatusMessage(status)); }; export { getJSON, postJSON, deleteJSON, putJSON, getHeaders }; diff --git a/wherehows-web/app/utils/api/shared.ts b/wherehows-web/app/utils/api/shared.ts index e529ce9394..df9fac0d63 100644 --- a/wherehows-web/app/utils/api/shared.ts +++ b/wherehows-web/app/utils/api/shared.ts @@ -1,6 +1,8 @@ /** * Defines available api version types */ +import { ApiError } from 'wherehows-web/utils/api/errors/errors'; + export type ApiVersion = 'v1' | 'v2'; /** @@ -31,3 +33,10 @@ export enum ApiResponseStatus { UnAuthorized = 401, InternalServerError = 500 } + +/** + * Convenience function to ascertain if an api error is a not found code + * @param {Error} e + * @return {boolean} + */ +export const notFoundApiError = (e: Error) => e instanceof ApiError && e.status === ApiResponseStatus.NotFound;