Skip to content

Commit 4824d05

Browse files
committed
Merge branch 'fix-observation-sync' of https://github.com/ngageoint/mage-server into add-arcgis-docs
2 parents 9e06fd2 + 62a608f commit 4824d05

11 files changed

+147
-187
lines changed

plugins/arcgis/service/src/ArcGISConfig.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { MageEventId } from "@ngageoint/mage.service/lib/entities/events/entities.events"
2+
13
/**
24
* Contains an arc feature service url and layers.
35
*/
@@ -9,8 +11,8 @@ export interface FeatureServiceConfig {
911
url: string
1012

1113
/**
12-
* Serialized ArcGISIdentityManager
13-
*/
14+
* Serialized ArcGISIdentityManager
15+
*/
1416
identityManager: string
1517

1618
/**
@@ -35,9 +37,9 @@ export interface FeatureLayerConfig {
3537
geometryType?: string
3638

3739
/**
38-
* The event ids or names that sync to this arc feature layer.
40+
* The event ids that sync to this arc feature layer.
3941
*/
40-
events?: (number|string)[]
42+
eventIds?: MageEventId[]
4143
}
4244

4345

plugins/arcgis/service/src/EventDeletionHandler.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ export class EventDeletionHandler {
3434
this._config = config;
3535
}
3636

37+
public updateConfig(newConfig: ArcGISPluginConfig): void {
38+
this._config = newConfig;
39+
}
40+
3741
/**
3842
*
3943
* @param activeEvents The current set of active events.
@@ -83,7 +87,7 @@ export class EventDeletionHandler {
8387
}
8488

8589
/**
86-
* Called when the query is finished. It goes through the results and gathers all even Ids currently stored
90+
* Called when the query is finished. It goes through the results and gathers all event Ids currently stored
8791
* in the arc layer. It then will remove any events from the arc layer that do not exist.
8892
* @param layerProcessor The feature layer processor.
8993
* @param result The returned results.

plugins/arcgis/service/src/EventLayerProcessorOrganizer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export class EventLayerProcessorOrganizer {
1919
for (const event of events) {
2020
let syncProcessors = new Array<FeatureLayerProcessor>();
2121
for (const layerProcessor of layerProcessors) {
22-
if (layerProcessor.layerInfo.hasEvent(event.name)) {
22+
if (layerProcessor.layerInfo.hasEvent(event.id)) {
2323
syncProcessors.push(layerProcessor);
2424
}
2525
}

plugins/arcgis/service/src/FeatureLayerProcessor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export class FeatureLayerProcessor {
4545
constructor(layerInfo: LayerInfo, config: ArcGISPluginConfig, identityManager: ArcGISIdentityManager, console: Console) {
4646
this.layerInfo = layerInfo;
4747
this.lastTimeStamp = 0;
48-
this.featureQuerier = new FeatureQuerier(layerInfo, config, identityManager,console);
48+
this.featureQuerier = new FeatureQuerier(layerInfo, config, identityManager, console);
4949
this._binner = new ObservationBinner(layerInfo, this.featureQuerier, config);
5050
this.sender = new ObservationsSender(layerInfo, config, identityManager, console);
5151
}
@@ -85,7 +85,7 @@ export class FeatureLayerProcessor {
8585

8686
for (const arcObservation of observations.deletions) {
8787
if (this.layerInfo.geometryType == arcObservation.esriGeometryType) {
88-
this.sender.sendDelete(Number(arcObservation.id));
88+
this.sender.sendDelete(arcObservation.id);
8989
}
9090
}
9191
}
Lines changed: 28 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { ArcGISPluginConfig } from "./ArcGISPluginConfig";
22
import { LayerInfo } from "./LayerInfo";
33
import { QueryObjectResult } from "./QueryObjectResult";
4-
import { ArcGISIdentityManager, request } from "@esri/arcgis-rest-request";
4+
import { ArcGISIdentityManager } from "@esri/arcgis-rest-request";
5+
import { queryFeatures } from '@esri/arcgis-rest-feature-service';
56

67
/**
78
* Performs various queries on observations for a specific arc feature layer.
@@ -52,22 +53,17 @@ export class FeatureQuerier {
5253
* @param geometry query the geometry, default is true
5354
*/
5455
async queryObservation(observationId: string, response: (result: QueryObjectResult) => void, fields?: string[], geometry?: boolean) {
55-
const queryUrl = new URL(this._url)
56-
if (this._config.eventIdField == null) {
57-
queryUrl.searchParams.set('where', `${this._config.observationIdField} LIKE '${observationId}${this._config.idSeparator}%'`);
58-
} else {
59-
queryUrl.searchParams.set('where', `${this._config.observationIdField} = ${observationId}`);
60-
}
61-
queryUrl.searchParams.set('outFields', this.outFields(fields))
62-
queryUrl.searchParams.set('returnGeometry', geometry === false ? 'false' : 'true')
63-
this._console.info('ArcGIS query: ' + queryUrl)
64-
65-
const queryResponse = await request(queryUrl.toString(), {
56+
const where = !this._config.eventIdField
57+
? `${this._config.observationIdField} LIKE '${observationId}${this._config.idSeparator}%'`
58+
: `${this._config.observationIdField} = '${observationId}'`;
59+
this._console.info('ArcGIS query observation: ' + this._url.toString() + where);
60+
await queryFeatures({
61+
url: this._url.toString(),
6662
authentication: this._identityManager,
67-
params: { f: 'json' }
68-
});
69-
70-
response(queryResponse as QueryObjectResult);
63+
where,
64+
returnGeometry: geometry,
65+
outFields: fields?.length ? fields : '*'
66+
}).then((queryResponse) => response(queryResponse as QueryObjectResult)).catch((error) => this._console.error('Error in FeatureQuerier.queryObservation :: ' + error));
7167
}
7268

7369
/**
@@ -77,19 +73,14 @@ export class FeatureQuerier {
7773
* @param geometry query the geometry, default is true
7874
*/
7975
async queryObservations(response: (result: QueryObjectResult) => void, fields?: string[], geometry?: boolean) {
80-
const queryUrl = new URL(this._url)
81-
queryUrl.searchParams.set('where', `${this._config.observationIdField} IS NOT NULL`);
82-
queryUrl.searchParams.set('outFields', this.outFields(fields));
83-
queryUrl.searchParams.set('returnGeometry', geometry === false ? 'false' : 'true');
84-
85-
this._console.info('ArcGIS query: ' + queryUrl)
86-
87-
const queryResponse = await request(queryUrl.toString(), {
76+
this._console.info('ArcGIS query observation: ' + this._url.toString());
77+
await queryFeatures({
78+
url: this._url.toString(),
8879
authentication: this._identityManager,
89-
params: { f: 'json' }
90-
});
91-
92-
response(queryResponse as QueryObjectResult);
80+
where: `${this._config.observationIdField} IS NOT NULL`,
81+
returnGeometry: geometry,
82+
outFields: fields?.length ? fields : '*'
83+
}).then((queryResponse) => response(queryResponse as QueryObjectResult)).catch((error) => this._console.error('Error in FeatureQuerier.queryObservations :: ' + error));
9384
}
9485

9586
/**
@@ -98,37 +89,14 @@ export class FeatureQuerier {
9889
* @param field field to query
9990
*/
10091
async queryDistinct(response: (result: QueryObjectResult) => void, field: string) {
101-
const queryUrl = new URL(this._url);
102-
queryUrl.searchParams.set('where', `${field} IS NOT NULL`);
103-
queryUrl.searchParams.set('returnDistinctValues', 'true');
104-
queryUrl.searchParams.set('outFields', this.outFields([field]));
105-
queryUrl.searchParams.set('returnGeometry', 'false');
106-
this._console.info('ArcGIS query: ' + queryUrl)
107-
108-
try {
109-
const queryResponse = await request(queryUrl.toString(), {
110-
authentication: this._identityManager,
111-
params: { f: 'json' }
112-
113-
});
114-
115-
response(queryResponse as QueryObjectResult);
116-
} catch (err) {
117-
console.error("could not query", err)
118-
}
119-
}
120-
121-
/**
122-
* Build the out fields query parameter
123-
* @param fields query fields
124-
* @returns out fields
125-
*/
126-
private outFields(fields?: string[]): string {
127-
if (fields != null && fields.length > 0) {
128-
return fields.join(',');
129-
} else {
130-
return '*';
131-
}
92+
this._console.info('ArcGIS query observation: ' + this._url.toString());
93+
await queryFeatures({
94+
url: this._url.toString(),
95+
authentication: this._identityManager,
96+
where: `${field} IS NOT NULL`,
97+
returnGeometry: false,
98+
outFields: field ? [field] : '*',
99+
returnDistinctValues: true
100+
}).then((queryResponse) => response(queryResponse as QueryObjectResult)).catch((error) => this._console.error('Error in FeatureQuerier.queryDistinct :: ' + error));
132101
}
133-
134102
}

plugins/arcgis/service/src/FeatureServiceAdmin.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { ArcGISPluginConfig } from "./ArcGISPluginConfig"
22
import { FeatureServiceConfig, FeatureLayerConfig } from "./ArcGISConfig"
3-
import { MageEvent, MageEventRepository } from '@ngageoint/mage.service/lib/entities/events/entities.events'
3+
import { MageEvent, MageEventId, MageEventRepository } from '@ngageoint/mage.service/lib/entities/events/entities.events'
44
import { Layer, Field } from "./AddLayersRequest"
55
import { Form, FormField, FormFieldType, FormId } from '@ngageoint/mage.service/lib/entities/events/entities.events.forms'
66
import { ObservationsTransformer } from "./ObservationsTransformer"
@@ -120,29 +120,29 @@ export class FeatureServiceAdmin {
120120
}
121121

122122
/**
123-
* Get the layer events
123+
* Get the Mage layer events
124124
* @param layer feature layer
125125
* @param eventRepo event repository
126-
* @returns layer events
126+
* @returns Mage layer events
127127
*/
128128
private async layerEvents(layer: FeatureLayerConfig, eventRepo: MageEventRepository): Promise<MageEvent[]> {
129-
const layerEvents: Set<number|string> = new Set()
130-
if (layer.events != null) {
131-
for (const layerEvent of layer.events) {
132-
layerEvents.add(layerEvent)
129+
const layerEventIds: Set<MageEventId> = new Set()
130+
if (layer.eventIds != null) {
131+
for (const layerEventId of layer.eventIds) {
132+
layerEventIds.add(layerEventId)
133133
}
134134
}
135135

136136
let mageEvents
137-
if (layerEvents.size > 0) {
137+
if (layerEventIds.size > 0) {
138138
mageEvents = await eventRepo.findAll()
139139
} else {
140140
mageEvents = await eventRepo.findActiveEvents()
141141
}
142142

143143
const events: MageEvent[] = []
144144
for (const mageEvent of mageEvents) {
145-
if (layerEvents.size == 0 || layerEvents.has(mageEvent.name) || layerEvents.has(mageEvent.id)) {
145+
if (layerEventIds.size == 0 || layerEventIds.has(mageEvent.id)) {
146146
const event = await eventRepo.findById(mageEvent.id)
147147
if (event != null) {
148148
events.push(event)

plugins/arcgis/service/src/LayerInfo.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { MageEventId } from "@ngageoint/mage.service/lib/entities/events/entities.events";
12
import { LayerInfoResult, LayerField } from "./LayerInfoResult";
23

34
/**
@@ -28,7 +29,7 @@ export class LayerInfo {
2829
/**
2930
* The events that are synching to this layer.
3031
*/
31-
events: Set<string> = new Set<string>()
32+
events: Set<MageEventId> = new Set<MageEventId>()
3233

3334
/**
3435
* Constructor.
@@ -37,12 +38,10 @@ export class LayerInfo {
3738
* @param layerInfo The layer info.
3839
* @param token The access token.
3940
*/
40-
constructor(url: string, events: string[], layerInfo: LayerInfoResult) {
41+
constructor(url: string, events: MageEventId[], layerInfo: LayerInfoResult) {
4142
this.url = url
42-
if (events != undefined && events != null && events.length == 0) {
43-
this.events.add('nothing to sync')
44-
}
45-
if (events != undefined || events != null) {
43+
44+
if (events && events.length > 0) {
4645
for (const event of events) {
4746
this.events.add(event);
4847
}
@@ -69,11 +68,11 @@ export class LayerInfo {
6968

7069
/**
7170
* Determine if the layer is enabled for the event.
72-
* @param event The event.
71+
* @param eventId The event.
7372
* @return true if enabled
7473
*/
75-
hasEvent(event: string) {
76-
return this.events.size == 0 || this.events.has(event)
74+
hasEvent(eventId: MageEventId) {
75+
return this.events.size == 0 || this.events.has(eventId)
7776
}
7877

7978
}

plugins/arcgis/service/src/ObservationBinner.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ export class ObservationBinner {
8989
const bins = new ObservationBins();
9090

9191
for (const arcObservation of observations.observations) {
92-
if (arcObservation.lastModified != arcObservation.createdAt) {
92+
// TODO: Would probably want a better way to determine which observations need to be updated in arcgis
93+
if (observations.firstRun || arcObservation.lastModified != arcObservation.createdAt) {
9394
bins.updates.add(arcObservation);
9495
} else if (!this._addedObs.has(arcObservation.id)) {
9596
bins.adds.add(arcObservation);

0 commit comments

Comments
 (0)