Skip to content

Commit

Permalink
Merge pull request #454 from Esri/f/165476-public-hub-lock
Browse files Browse the repository at this point in the history
f/165476 added target change to allow locking of private non-enterpri…
  • Loading branch information
drspacemanphd authored Jan 26, 2021
2 parents f4fe9f2 + 97723e6 commit 6596ac9
Show file tree
Hide file tree
Showing 14 changed files with 1,558 additions and 180 deletions.
4 changes: 4 additions & 0 deletions packages/downloads/src/download-status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ export enum DownloadStatus {
READY_UNKNOWN = "ready_unknown",
STALE = "stale",
NOT_READY = "not_ready",
LOCKED = "locked",
STALE_LOCKED = "stale_locked",
CREATING = "creating",
UPDATING = "updating",
ERROR_CREATING = "error_creating",
Expand All @@ -15,6 +17,8 @@ export type DownloadStatuses =
| "ready_unknown"
| "stale"
| "not_ready"
| "locked"
| "stale_locked"
| "creating"
| "updating"
| "error_creating"
Expand Down
1 change: 1 addition & 0 deletions packages/downloads/src/download-target.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type DownloadTarget = "hub" | "portal" | "enterprise";
3 changes: 2 additions & 1 deletion packages/downloads/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/* Copyright (c) 2020 Environmental Systems Research Institute, Inc.
* Apache-2.0 */

export * from "./poll-download-metadata"
export * from "./poll-download-metadata";
export * from "./request-dataset-export";
export * from "./request-download-metadata";
export * from "./download-format";
export * from "./download-target";
export * from "./poller";
29 changes: 15 additions & 14 deletions packages/downloads/src/poll-download-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,16 @@ import { UserSession } from "@esri/arcgis-rest-auth";
import { hubPollDownloadMetadata } from "./hub/hub-poll-download-metadata";
import { portalPollExportJobStatus } from "./portal/portal-poll-export-job-status";
import { DownloadFormat } from "./download-format";
import { DownloadTarget } from "./download-target";
import { IPoller } from "./poller";

export interface IPollDownloadMetadataRequestParams {
/* Identifier for the download. Used to emit events for success or failure */
downloadId: string;
eventEmitter: EventEmitter;
pollingInterval: number;
/* API target for downloads: 'hub' (default) or 'portal' */
target?: string;
/* API target for downloads: 'hub' (default), 'portal' or 'enterprise' */
target?: DownloadTarget;
/* Hub API host name. Not required for Portal API downloads (stored in the authentication object) */
host?: string;
/* ID for the downloads source dataset; e.g. "abcdef0123456789abcdef0123456789_0" */
Expand Down Expand Up @@ -60,32 +61,32 @@ export function pollDownloadMetadata(
existingFileDate
} = params;

if (target === "portal") {
return portalPollExportJobStatus({
if (!target || target === "hub") {
return hubPollDownloadMetadata({
host,
downloadId,
datasetId,
jobId,
authentication,
exportCreated,
format,
spatialRefId,
eventEmitter,
pollingInterval,
spatialRefId,
geometry,
where
where,
existingFileDate
});
}

return hubPollDownloadMetadata({
host,
return portalPollExportJobStatus({
downloadId,
datasetId,
jobId,
authentication,
exportCreated,
format,
spatialRefId,
eventEmitter,
pollingInterval,
spatialRefId,
geometry,
where,
existingFileDate
where
});
}
28 changes: 21 additions & 7 deletions packages/downloads/src/portal/portal-request-download-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import {
} from "@esri/arcgis-rest-feature-layer";
import { DownloadFormat, DownloadFormats } from "../download-format";
import { urlBuilder, composeDownloadId } from "../utils";
import { DownloadTarget } from "../download-target";
import { DownloadStatus } from "../download-status";
import { isRecentlyUpdated } from "./utils";

enum ItemTypes {
FeatureService = "Feature Service",
Expand All @@ -26,6 +28,7 @@ export interface IPortalDownloadMetadataRequestParams {
format: DownloadFormat;
authentication: UserSession;
spatialRefId?: string;
target?: DownloadTarget;
}

/**
Expand All @@ -42,7 +45,7 @@ export interface ICacheSearchMetadata {
export function portalRequestDownloadMetadata(
params: IPortalDownloadMetadataRequestParams
): Promise<any> {
const { datasetId, authentication, format, spatialRefId } = params;
const { datasetId, authentication, format, spatialRefId, target } = params;

const [itemId, layerId] = datasetId.split("_");
let serviceLastEditDate: number | undefined;
Expand Down Expand Up @@ -83,7 +86,8 @@ export function portalRequestDownloadMetadata(
serviceLastEditDate,
itemModifiedDate,
itemType,
authentication
authentication,
target
});
})
.catch((err: any) => {
Expand Down Expand Up @@ -149,16 +153,22 @@ function extractLastEditDate(layers: ILayerDefinition[]) {
}

function formatDownloadMetadata(params: any) {
const { cachedDownload, serviceLastEditDate, authentication } = params;
const {
cachedDownload,
serviceLastEditDate,
authentication,
target
} = params;

const lastEditDate =
serviceLastEditDate === undefined
? undefined
: new Date(serviceLastEditDate).toISOString();

const { created, id } = cachedDownload || {};
const recentlyUpdated = isRecentlyUpdated(target, serviceLastEditDate);

const status = determineStatus(serviceLastEditDate, created);
const status = determineStatus(serviceLastEditDate, created, recentlyUpdated);

if (!cachedDownload) {
return {
Expand All @@ -182,15 +192,19 @@ function formatDownloadMetadata(params: any) {
};
}

function determineStatus(serviceLastEditDate: Date, exportCreatedDate: Date) {
function determineStatus(
serviceLastEditDate: Date,
exportCreatedDate: Date,
recentlyUpdated: boolean
) {
if (!exportCreatedDate) {
return DownloadStatus.NOT_READY;
return recentlyUpdated ? DownloadStatus.LOCKED : DownloadStatus.NOT_READY;
}
if (!serviceLastEditDate) {
return DownloadStatus.READY_UNKNOWN;
}
if (serviceLastEditDate > exportCreatedDate) {
return DownloadStatus.STALE;
return recentlyUpdated ? DownloadStatus.STALE_LOCKED : DownloadStatus.STALE;
}
return DownloadStatus.READY;
}
17 changes: 17 additions & 0 deletions packages/downloads/src/portal/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { DownloadTarget } from "../download-target";

const DOWNLOADS_LOCK_MS = 10 * 60 * 1000;

/**
* @private
*/
export function isRecentlyUpdated(
target: DownloadTarget,
lastEditDate: number
): boolean {
return (
target === "portal" &&
lastEditDate &&
new Date().getTime() - lastEditDate <= DOWNLOADS_LOCK_MS
);
}
19 changes: 10 additions & 9 deletions packages/downloads/src/request-dataset-export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { UserSession } from "@esri/arcgis-rest-auth";
import { hubRequestDatasetExport } from "./hub/hub-request-dataset-export";
import { portalRequestDatasetExport } from "./portal/portal-request-dataset-export";
import { DownloadFormat } from "./download-format";
import { DownloadTarget } from "./download-target";

export interface IDatasetExportRequestParams {
/* API target for downloads: 'hub' (default) or 'portal' */
target?: string;
/* API target for downloads: 'hub' (default), 'portal', or 'enterprise' */
target?: DownloadTarget;
/* Hub API host name. Required for Hub API exports (stored in the authentication object) */
host?: string;
/* ID for the downloads source dataset; e.g. "abcdef0123456789abcdef0123456789_0" */
Expand Down Expand Up @@ -56,23 +57,23 @@ export function requestDatasetExport(
authentication
} = params;

if (target === "portal") {
return portalRequestDatasetExport({
if (!target || target === "hub") {
return hubRequestDatasetExport({
host,
datasetId,
format,
title,
authentication,
spatialRefId,
geometry,
where
});
}

return hubRequestDatasetExport({
host,
return portalRequestDatasetExport({
datasetId,
format,
title,
authentication,
spatialRefId,
geometry,
where
});
}
22 changes: 12 additions & 10 deletions packages/downloads/src/request-download-metadata.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { portalRequestDownloadMetadata } from "./portal/portal-request-download-metadata";
import { hubRequestDownloadMetadata } from "./hub/hub-request-download-metadata";
import { DownloadFormat } from "./download-format";
import { DownloadTarget } from "./download-target";
import { DownloadStatuses } from "./download-status";
import { UserSession } from "@esri/arcgis-rest-auth";

export interface IDownloadMetadataRequestParams {
/* API target for downloads: 'hub' (default) or 'portal' */
target?: string;
/* API target for downloads: 'hub' (default), 'portal', 'enterprise' */
target?: DownloadTarget;
/* Hub API host name. Not required for Portal API downloads (stored in the authentication object) */
host?: string;
/* ID for the downloads source dataset; e.g. "abcdef0123456789abcdef0123456789_0" */
Expand Down Expand Up @@ -93,21 +94,22 @@ export function requestDownloadMetadata(
authentication
} = params;

if (target === "portal") {
return portalRequestDownloadMetadata({
if (!target || target === "hub") {
return hubRequestDownloadMetadata({
host,
datasetId,
format,
authentication,
spatialRefId
spatialRefId,
geometry,
where
});
}

return hubRequestDownloadMetadata({
host,
return portalRequestDownloadMetadata({
datasetId,
format,
authentication,
spatialRefId,
geometry,
where
target
});
}
63 changes: 62 additions & 1 deletion packages/downloads/test/poll-download-metadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ describe("pollDownloadMetadata", () => {
spyOn(mockEventEmitter, "emit");

spyOn(hubPoller, "hubPollDownloadMetadata").and.returnValue(
new Promise((resolve, reject) => {
new Promise((resolve, _reject) => {
resolve();
})
);
Expand Down Expand Up @@ -110,4 +110,65 @@ describe("pollDownloadMetadata", () => {
done();
}
});

it("handle enterprise download", async done => {
const authentication = new UserSession({
username: "portal-user",
portal: "http://portal.com/sharing/rest",
token: "123"
});
authentication.getToken = () =>
new Promise(resolve => {
resolve("123");
});

try {
const mockEventEmitter = new EventEmitter();
spyOn(mockEventEmitter, "emit");

spyOn(portalPoller, "portalPollExportJobStatus").and.returnValue(
new Promise((resolve, reject) => {
resolve();
})
);

pollDownloadMetadata({
target: "enterprise",
datasetId: "abcdef0123456789abcdef0123456789_0",
spatialRefId: "4326",
format: "CSV",
downloadId: "download-id",
jobId: "job-id",
exportCreated: 1000,
eventEmitter: mockEventEmitter,
pollingInterval: 10,
authentication
});

expect(
portalPoller.portalPollExportJobStatus as any
).toHaveBeenCalledTimes(1);
expect(
(portalPoller.portalPollExportJobStatus as any).calls.first().args
).toEqual([
{
downloadId: "download-id",
datasetId: "abcdef0123456789abcdef0123456789_0",
jobId: "job-id",
format: "CSV",
spatialRefId: "4326",
eventEmitter: mockEventEmitter,
pollingInterval: 10,
authentication,
exportCreated: 1000,
geometry: undefined,
where: undefined
}
]);
} catch (err) {
expect(err).toBeUndefined();
} finally {
done();
}
});
});
Loading

0 comments on commit 6596ac9

Please sign in to comment.