Skip to content

Commit ec07047

Browse files
author
Rick Saccoccia
committed
[service] sync configured events instead of checking changes of all events. Store event ids instead of names
1 parent 6030daf commit ec07047

File tree

7 files changed

+90
-63
lines changed

7 files changed

+90
-63
lines changed

plugins/arcgis/service/src/ArcGISConfig.ts

Lines changed: 8 additions & 6 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
*/
@@ -8,10 +10,10 @@ export interface FeatureServiceConfig {
810
*/
911
url: string
1012

11-
/**
12-
* Serialized ArcGISIdentityManager
13-
*/
14-
identityManager: string
13+
/**
14+
* Serialized ArcGISIdentityManager
15+
*/
16+
identityManager: string
1517

1618
/**
1719
* The feature layers.
@@ -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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export class EventDeletionHandler {
8383
}
8484

8585
/**
86-
* Called when the query is finished. It goes through the results and gathers all even Ids currently stored
86+
* Called when the query is finished. It goes through the results and gathers all event Ids currently stored
8787
* in the arc layer. It then will remove any events from the arc layer that do not exist.
8888
* @param layerProcessor The feature layer processor.
8989
* @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/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/ObservationProcessor.ts

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { PagingParameters } from '@ngageoint/mage.service/lib/entities/entities.global';
2+
import { MageEventId } from "@ngageoint/mage.service/lib/entities/events/entities.events";
23
import { MageEventRepository } from '@ngageoint/mage.service/lib/entities/events/entities.events';
34
import { EventScopedObservationRepository, ObservationRepositoryForEvent } from '@ngageoint/mage.service/lib/entities/observations/entities.observations';
45
import { UserRepository } from '@ngageoint/mage.service/lib/entities/users/entities.users';
@@ -164,8 +165,13 @@ export class ObservationProcessor {
164165
private async updateConfig(): Promise<ArcGISPluginConfig> {
165166
const config = await this.safeGetConfig()
166167

167-
// Include form definitions while detecting changes in config
168-
const eventForms = await this._eventRepo.findAll();
168+
// Include configured eventform definitions while detecting changes in config
169+
const eventIds = config.featureServices
170+
.flatMap(service => service.layers)
171+
.flatMap(layer => layer.eventIds)
172+
.filter((eventId): eventId is MageEventId => typeof eventId === 'number');
173+
174+
const eventForms = await this._eventRepo.findAllByIds(eventIds);
169175
const fullConfig = { ...config, eventForms };
170176

171177
const configJson = JSON.stringify(fullConfig)
@@ -207,7 +213,7 @@ export class ObservationProcessor {
207213
try {
208214
const identityManager = await this._identityService.signin(service)
209215
const response = await request(service.url, { authentication: identityManager })
210-
this.handleFeatureService(response, service, config)
216+
await this.handleFeatureService(response, service, config)
211217
} catch (err) {
212218
console.error(err)
213219
}
@@ -235,25 +241,7 @@ export class ObservationProcessor {
235241
}
236242

237243
for (const featureLayer of featureServiceConfig.layers) {
238-
const eventNames: string[] = []
239-
const events = featureLayer.events
240-
if (events != null) {
241-
for (const event of events) {
242-
const eventId = Number(event);
243-
if (isNaN(eventId)) {
244-
eventNames.push(String(event));
245-
} else {
246-
const mageEvent = await this._eventRepo.findById(eventId)
247-
if (mageEvent != null) {
248-
eventNames.push(mageEvent.name);
249-
}
250-
}
251-
}
252-
}
253-
if (eventNames.length > 0) {
254-
featureLayer.events = eventNames
255-
}
256-
244+
// TODO - this used to convert event ids to names and set back on featureLayer.events. What is impact of not doing?
257245
const layer = serviceLayers.get(featureLayer.layer)
258246

259247
let layerId = undefined
@@ -270,7 +258,7 @@ export class ObservationProcessor {
270258
const featureService = new FeatureService(console, featureServiceConfig, identityManager)
271259
const layerInfo = await featureService.queryLayerInfo(layerId);
272260
const url = `${featureServiceConfig.url}/${layerId}`;
273-
this.handleLayerInfo(url, featureServiceConfig, featureLayer, layerInfo, config);
261+
await this.handleLayerInfo(url, featureServiceConfig, featureLayer, layerInfo, config);
274262
}
275263
}
276264
}
@@ -286,10 +274,10 @@ export class ObservationProcessor {
286274
*/
287275
private async handleLayerInfo(url: string, featureServiceConfig: FeatureServiceConfig, featureLayer: FeatureLayerConfig, layerInfo: LayerInfoResult, config: ArcGISPluginConfig) {
288276
if (layerInfo.geometryType != null) {
289-
const events = featureLayer.events as string[]
290277
const admin = new FeatureServiceAdmin(config, this._identityService, this._console)
278+
const eventIds = featureLayer.eventIds || []
291279
await admin.updateLayer(featureServiceConfig, featureLayer, layerInfo, this._eventRepo)
292-
const info = new LayerInfo(url, events, layerInfo)
280+
const info = new LayerInfo(url, eventIds, layerInfo)
293281
const identityManager = await this._identityService.signin(featureServiceConfig)
294282
const layerProcessor = new FeatureLayerProcessor(info, config, identityManager, this._console);
295283
this._layerProcessors.push(layerProcessor);
@@ -310,9 +298,13 @@ export class ObservationProcessor {
310298
layerProcessor.processPendingUpdates();
311299
}
312300
this._console.info('ArcGIS plugin processing new observations...');
313-
const activeEvents = await this._eventRepo.findActiveEvents();
314-
this._eventDeletionHandler.checkForEventDeletion(activeEvents, this._layerProcessors, this._firstRun);
315-
const eventsToProcessors = this._organizer.organize(activeEvents, this._layerProcessors);
301+
const enabledEvents = (await this._eventRepo.findActiveEvents()).filter(event =>
302+
this._layerProcessors.some(layerProcessor =>
303+
layerProcessor.layerInfo.hasEvent(event.id)
304+
)
305+
);
306+
this._eventDeletionHandler.checkForEventDeletion(enabledEvents, this._layerProcessors, this._firstRun);
307+
const eventsToProcessors = this._organizer.organize(enabledEvents, this._layerProcessors);
316308
const nextQueryTime = Date.now();
317309
for (const pair of eventsToProcessors) {
318310
this._console.info('ArcGIS getting newest observations for event ' + pair.event.name);

plugins/arcgis/service/src/index.ts

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import { ObservationRepositoryToken } from '@ngageoint/mage.service/lib/plugins.
44
import { MageEventRepositoryToken } from '@ngageoint/mage.service/lib/plugins.api/plugins.api.events'
55
import { UserRepositoryToken } from '@ngageoint/mage.service/lib/plugins.api/plugins.api.users'
66
import { SettingPermission } from '@ngageoint/mage.service/lib/entities/authorization/entities.permissions'
7+
import { MageEventId } from '@ngageoint/mage.service/lib/entities/events/entities.events'
78
import { ObservationProcessor } from './ObservationProcessor'
89
import { ArcGISIdentityManager, request } from "@esri/arcgis-rest-request"
9-
import { FeatureServiceConfig } from './ArcGISConfig'
10+
import { FeatureServiceConfig, FeatureLayerConfig } from './ArcGISConfig'
1011
import { URL } from "node:url"
1112
import express from 'express'
1213
import { ArcGISIdentityService, createArcGISIdentityService, getPortalUrl } from './ArcGISService'
@@ -166,16 +167,49 @@ const arcgisPluginHooks: InitPluginHook<typeof InjectedServices> = {
166167
const config = await stateRepo.get()
167168
const { featureServices: updatedServices, ...updateConfig } = req.body
168169

169-
// Map exisiting identityManager, client does not send this
170-
const featureServices: FeatureServiceConfig[] = updatedServices.map((updateService: FeatureServiceConfig) => {
171-
const existingService = config.featureServices.find((featureService: FeatureServiceConfig) => featureService.url === updateService.url)
170+
171+
// Convert event names to event IDs
172+
// Fetch all events and create a mapping of event names to event IDs
173+
const allEvents = await eventRepo.findAll();
174+
const eventNameToIdMap = new Map<string, MageEventId>();
175+
allEvents.forEach(event => {
176+
eventNameToIdMap.set(event.name, event.id);
177+
});
178+
179+
// Process the incoming feature services with eventIds instead of event names
180+
const featureServices: FeatureServiceConfig[] = updatedServices.map((updateService: any) => {
181+
const existingService = config.featureServices.find(
182+
(featureService: FeatureServiceConfig) => featureService.url === updateService.url
183+
);
184+
185+
// Process layers
186+
const layers: FeatureLayerConfig[] = updateService.layers.map((layer: any) => {
187+
// Extract event names from the incoming layer data
188+
const eventNames: string[] = layer.events || [];
189+
190+
// Convert event names to event IDs using the mapping
191+
const eventIds = eventNames
192+
.map(eventName => eventNameToIdMap.get(eventName))
193+
.filter((id): id is MageEventId => id !== undefined);
194+
195+
// Construct the FeatureLayerConfig with eventIds
196+
const featureLayerConfig: FeatureLayerConfig = {
197+
layer: layer.layer,
198+
geometryType: layer.geometryType,
199+
eventIds: eventIds,
200+
};
201+
202+
return featureLayerConfig;
203+
});
204+
172205
return {
173206
url: updateService.url,
174-
layers: updateService.layers,
175-
identityManager: existingService?.identityManager
176-
}
177-
})
178-
207+
layers: layers,
208+
// Map exisiting identityManager, client does not send this
209+
identityManager: existingService?.identityManager,
210+
};
211+
});
212+
179213
await stateRepo.patch({ ...updateConfig, featureServices })
180214

181215
// Sync configuration with feature servers by restarting observation processor

0 commit comments

Comments
 (0)