@contrail/flexplm 1.8.1-alpha.85853aa → 2.0.0-alpha.9af4b96

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/lib/__tests__/telemetry-test-utils.d.ts +8 -0
  2. package/lib/__tests__/telemetry-test-utils.js +30 -0
  3. package/lib/cli/commands/compile.js +17 -7
  4. package/lib/cli/commands/compile.spec.js +17 -7
  5. package/lib/cli/commands/create.js +17 -7
  6. package/lib/cli/commands/create.spec.js +17 -7
  7. package/lib/cli/commands/upload.js +17 -7
  8. package/lib/cli/index.js +2 -2
  9. package/lib/entity-processor/base-entity-processor.d.ts +29 -0
  10. package/lib/entity-processor/base-entity-processor.js +238 -143
  11. package/lib/entity-processor/base-entity-processor.spec.js +212 -0
  12. package/lib/index.d.ts +1 -0
  13. package/lib/index.js +1 -0
  14. package/lib/interfaces/interfaces.d.ts +1 -1
  15. package/lib/publish/base-process-publish-assortment-callback.js +30 -0
  16. package/lib/publish/base-process-publish-assortment-callback.spec.d.ts +1 -0
  17. package/lib/publish/base-process-publish-assortment-callback.spec.js +62 -0
  18. package/lib/publish/base-process-publish-assortment.d.ts +24 -0
  19. package/lib/publish/base-process-publish-assortment.js +243 -132
  20. package/lib/publish/base-process-publish-assortment.spec.js +188 -0
  21. package/lib/util/config-defaults.js +2 -0
  22. package/lib/util/error-response-object.js +2 -0
  23. package/lib/util/event-short-message-status.js +1 -1
  24. package/lib/util/flexplm-connect.d.ts +4 -0
  25. package/lib/util/flexplm-connect.js +210 -145
  26. package/lib/util/flexplm-connect.telemetry.spec.d.ts +1 -0
  27. package/lib/util/flexplm-connect.telemetry.spec.js +212 -0
  28. package/lib/util/logger-config.js +1 -2
  29. package/lib/util/telemetry-attributes.d.ts +68 -0
  30. package/lib/util/telemetry-attributes.js +73 -0
  31. package/lib/util/telemetry-utils.d.ts +3 -0
  32. package/lib/util/telemetry-utils.js +10 -0
  33. package/lib/util/thumbnail-util.d.ts +2 -1
  34. package/lib/util/thumbnail-util.js +35 -7
  35. package/lib/util/thumbnail-util.spec.js +42 -0
  36. package/package.json +10 -3
@@ -8,10 +8,17 @@ const sdk_1 = require("@contrail/sdk");
8
8
  const type_conversion_utils_1 = require("../util/type-conversion-utils");
9
9
  const thumbnail_util_1 = require("../util/thumbnail-util");
10
10
  const event_short_message_status_1 = require("../util/event-short-message-status");
11
+ const telemetry_1 = require("@contrail/telemetry");
12
+ const telemetry_utils_1 = require("../util/telemetry-utils");
13
+ const telemetry_attributes_1 = require("../util/telemetry-attributes");
11
14
  const UNSUPPORTED_TYPE = 'Unsupported eventType.';
12
15
  class IncomingEntityResponse {
13
16
  }
14
17
  exports.IncomingEntityResponse = IncomingEntityResponse;
18
+ const FLEXPLM_ITEM_STATUS_OK = 'OK';
19
+ const hasUpdates = (updates) => !!updates && Object.keys(updates).length > 0;
20
+ const getResponseItemStatus = (flexResponse) => flexResponse?.data?.payload?.[0]?.status;
21
+ const countProperties = (object) => (object && typeof object === 'object') ? Object.keys(object).length : 0;
15
22
  class BaseEntityProcessor {
16
23
  constructor(config, dc, mapFileUtil, baseType) {
17
24
  this.config = config;
@@ -25,33 +32,37 @@ class BaseEntityProcessor {
25
32
  }
26
33
  // inbound
27
34
  async inbound(event) {
28
- const eventType = event.eventType;
29
- console.log(`inbound entity: ${eventType}:${event.objectClass}`);
30
- switch (eventType) {
31
- case 'PERSIST':
32
- return await this.handleIncomingUpsert(event);
33
- case 'DELETE':
34
- return await this.handleIncomingDelete(event);
35
- default:
36
- console.error(UNSUPPORTED_TYPE);
37
- return {
38
- status: 500,
39
- data: { UNSUPPORTED_TYPE }
40
- };
41
- }
35
+ return (0, telemetry_1.traceSection)('process_inbound_entity', {
36
+ [telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_TYPE]: this.baseType,
37
+ [telemetry_attributes_1.ATTR_FLEXPLM_EVENT_OBJECT_CLASS]: event?.objectClass,
38
+ [telemetry_attributes_1.ATTR_FLEXPLM_EVENT_TYPE]: event?.eventType,
39
+ }, async () => {
40
+ const eventType = event.eventType;
41
+ switch (eventType) {
42
+ case 'PERSIST':
43
+ return await this.handleIncomingUpsert(event);
44
+ case 'DELETE':
45
+ return await this.handleIncomingDelete(event);
46
+ default:
47
+ telemetry_1.logger.warn({ flexplm: { direction: 'inbound', event_type: eventType, entity_type: this.baseType } }, 'Unsupported FlexPLM event type');
48
+ return {
49
+ status: 500,
50
+ data: { UNSUPPORTED_TYPE }
51
+ };
52
+ }
53
+ });
42
54
  }
43
55
  async handleIncomingUpsert(event) {
44
56
  const inboundData = await this.getTransformedData(event);
45
57
  const incomingEntityResponse = await this.getIncomingEntity(event, inboundData);
46
58
  // This case means there was an early return in the getIncomingEntity method
47
59
  if (incomingEntityResponse.earlyReturn) {
48
- const statusMsg = this.getInboundStatusMessage({
60
+ this.recordInboundStatus({
49
61
  status: event_short_message_status_1.EventShortMessageStatus.FAILURE,
50
62
  statusMessage: incomingEntityResponse.earlyReturn.shortStatusMessage || '',
51
63
  objectClass: event.objectClass,
52
64
  federatedId: event.federatedId
53
65
  });
54
- console.log(statusMsg);
55
66
  return incomingEntityResponse.earlyReturn;
56
67
  }
57
68
  const entity = incomingEntityResponse.entity;
@@ -61,13 +72,12 @@ class BaseEntityProcessor {
61
72
  const status = (createEntityResponse.earlyReturn.shortStatusMessage === event_short_message_status_1.EventShortMessageStatus.NOT_CREATABLE)
62
73
  ? event_short_message_status_1.EventShortMessageStatus.SUCCESS
63
74
  : event_short_message_status_1.EventShortMessageStatus.FAILURE;
64
- const statusMsg = this.getInboundStatusMessage({
75
+ this.recordInboundStatus({
65
76
  status,
66
77
  statusMessage: createEntityResponse.earlyReturn.shortStatusMessage || '',
67
78
  objectClass: event.objectClass,
68
79
  federatedId: event.federatedId
69
80
  });
70
- console.log(statusMsg);
71
81
  return createEntityResponse.earlyReturn;
72
82
  }
73
83
  let createdEntity = await this.createEntity(this.baseType, createEntityResponse.entity);
@@ -75,14 +85,13 @@ class BaseEntityProcessor {
75
85
  if (shouldSyncThumbnail) {
76
86
  createdEntity = await new thumbnail_util_1.ThumbnailUtil(this.config).syncThumbnailToVibeIQ({ entityId: createdEntity.id, primaryViewableId: createdEntity.primaryViewableId, event, entityName: this.baseType }) || createdEntity;
77
87
  }
78
- const statusMsg = this.getInboundStatusMessage({
88
+ this.recordInboundStatus({
79
89
  status: event_short_message_status_1.EventShortMessageStatus.SUCCESS,
80
90
  statusMessage: event_short_message_status_1.EventShortMessageStatus.CREATED,
81
91
  objectClass: event.objectClass,
82
- entityId: 'id',
92
+ entityId: createdEntity?.id,
83
93
  federatedId: event.federatedId
84
94
  });
85
- console.log(statusMsg);
86
95
  return createdEntity;
87
96
  }
88
97
  const diffs = await this.getUpdatesForEntity(entity, inboundData, event.data);
@@ -93,25 +102,23 @@ class BaseEntityProcessor {
93
102
  }
94
103
  const hasPropertyChanges = Object.getOwnPropertyNames(diffs).length > 0;
95
104
  if (!hasPropertyChanges && thumbnailEntity) {
96
- const statusMsg = this.getInboundStatusMessage({
105
+ this.recordInboundStatus({
97
106
  status: event_short_message_status_1.EventShortMessageStatus.SUCCESS,
98
107
  statusMessage: event_short_message_status_1.EventShortMessageStatus.PRIMARY_CONTENT_UPDATED,
99
108
  objectClass: event.objectClass,
100
109
  entityId: entity.id,
101
110
  federatedId: event.federatedId
102
111
  });
103
- console.log(statusMsg);
104
112
  return thumbnailEntity;
105
113
  }
106
114
  if (!hasPropertyChanges) {
107
- const statusMsg = this.getInboundStatusMessage({
115
+ this.recordInboundStatus({
108
116
  status: event_short_message_status_1.EventShortMessageStatus.SUCCESS,
109
117
  statusMessage: event_short_message_status_1.EventShortMessageStatus.NO_CHANGES,
110
118
  objectClass: event.objectClass,
111
119
  entityId: entity.id,
112
120
  federatedId: event.federatedId
113
121
  });
114
- console.log(statusMsg);
115
122
  const message = 'No Changes to persist for entity: ' + entity.id;
116
123
  return {
117
124
  status: 200,
@@ -119,16 +126,16 @@ class BaseEntityProcessor {
119
126
  };
120
127
  }
121
128
  const updatedEntity = await this.updateEntity(this.baseType, entity, diffs);
122
- const statusMsg = this.getInboundStatusMessage({
129
+ this.recordInboundStatus({
123
130
  status: event_short_message_status_1.EventShortMessageStatus.SUCCESS,
124
131
  statusMessage: event_short_message_status_1.EventShortMessageStatus.UPDATED,
125
132
  objectClass: event.objectClass,
126
133
  entityId: entity.id,
127
134
  federatedId: event.federatedId
128
135
  });
129
- console.log(statusMsg);
130
136
  return updatedEntity;
131
137
  }
138
+ /** @deprecated Use {@link recordInboundStatus}, which logs structured fields and sets span attributes. */
132
139
  getInboundStatusMessage(statusObject) {
133
140
  return 'BaseEntityProcessor: inbound: status: ' + statusObject.status
134
141
  + ', statusMessage: ' + statusObject.statusMessage
@@ -138,6 +145,60 @@ class BaseEntityProcessor {
138
145
  + ', federatedId: ' + statusObject.federatedId
139
146
  + ', orgSlug: ' + this.orgSlug;
140
147
  }
148
+ /** Records the result of one inbound event: attributes on the active span plus one structured log.
149
+ * A Failure here is a handled early return, so it is a warning and the span stays OK.
150
+ */
151
+ recordInboundStatus(statusObject) {
152
+ const { status, statusMessage, objectClass, entityId, federatedId } = statusObject;
153
+ (0, telemetry_utils_1.setActiveSpanAttributes)({
154
+ [telemetry_attributes_1.ATTR_FLEXPLM_STATUS]: status,
155
+ [telemetry_attributes_1.ATTR_FLEXPLM_OUTCOME]: statusMessage,
156
+ [telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_TYPE]: this.baseType,
157
+ [telemetry_attributes_1.ATTR_FLEXPLM_EVENT_OBJECT_CLASS]: objectClass,
158
+ [telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_ID]: entityId,
159
+ [telemetry_attributes_1.ATTR_FLEXPLM_FEDERATED_ID]: federatedId,
160
+ });
161
+ const fields = { flexplm: {
162
+ direction: 'inbound', status, outcome: statusMessage, entity_type: this.baseType,
163
+ entity_id: entityId, object_class: objectClass, federated_id: federatedId,
164
+ } };
165
+ if (status === event_short_message_status_1.EventShortMessageStatus.FAILURE) {
166
+ telemetry_1.logger.warn(fields, 'FlexPLM inbound entity not processed: %j', fields.flexplm);
167
+ }
168
+ else {
169
+ telemetry_1.logger.info(fields, 'FlexPLM inbound entity processed: %j', fields.flexplm);
170
+ }
171
+ }
172
+ /** Records the result of sending one entity to FlexPLM: attributes on the active span plus one structured log.
173
+ * On failure the caller still rethrows; the log keeps the entity context that the action's error log lacks.
174
+ * A Success whose response item status is not 'OK' is recorded as a Failure: FlexPLM accepted the request
175
+ * but rejected the item. Nothing is thrown for it, so it is a warning and the span stays OK.
176
+ */
177
+ recordOutboundStatus(statusObject) {
178
+ const { entityId, objectClass, httpStatus, updatedFromResponse, itemStatus, error } = statusObject;
179
+ const rejected = statusObject.status === event_short_message_status_1.EventShortMessageStatus.SUCCESS && !!itemStatus && itemStatus !== FLEXPLM_ITEM_STATUS_OK;
180
+ const status = rejected ? event_short_message_status_1.EventShortMessageStatus.FAILURE : statusObject.status;
181
+ (0, telemetry_utils_1.setActiveSpanAttributes)({
182
+ [telemetry_attributes_1.ATTR_FLEXPLM_STATUS]: status,
183
+ [telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_ID]: entityId,
184
+ [telemetry_attributes_1.ATTR_FLEXPLM_EVENT_OBJECT_CLASS]: objectClass,
185
+ [telemetry_attributes_1.ATTR_FLEXPLM_UPDATED_FROM_RESPONSE]: updatedFromResponse,
186
+ [telemetry_attributes_1.ATTR_FLEXPLM_RESPONSE_ITEM_STATUS]: itemStatus,
187
+ });
188
+ const flexplm = {
189
+ direction: 'outbound', status, entity_type: this.baseType, entity_id: entityId,
190
+ object_class: objectClass, http_status: httpStatus, item_status: itemStatus, updated_from_response: updatedFromResponse,
191
+ };
192
+ if (rejected) {
193
+ telemetry_1.logger.warn({ flexplm }, 'FlexPLM outbound entity rejected: %j', flexplm);
194
+ }
195
+ else if (status === event_short_message_status_1.EventShortMessageStatus.FAILURE) {
196
+ telemetry_1.logger.error({ error, flexplm }, 'FlexPLM outbound entity failed: %j', flexplm);
197
+ }
198
+ else {
199
+ telemetry_1.logger.info({ flexplm }, 'FlexPLM outbound entity sent: %j', flexplm);
200
+ }
201
+ }
141
202
  /** Looks up an identity record from the identity service based on the passed in criteria.
142
203
  * If no identity record is found, returns undefined. If multiple are found, throws an error.
143
204
  *
@@ -178,25 +239,29 @@ class BaseEntityProcessor {
178
239
  * @throws error if multiple identity entities are found, or if required parameters are missing
179
240
  */
180
241
  async getEntityUsingIdentityService(params) {
181
- const identityEntity = await this.getIdentityEntity(params);
182
- if (!identityEntity) {
183
- return undefined;
184
- }
185
- const entityReference = identityEntity.entityReference;
186
- if (typeof entityReference !== 'string' || !entityReference.includes(':')) {
187
- throw new Error(`Invalid identity entityReference: ${String(entityReference)}`);
188
- }
189
- const firstColonIndex = entityReference.indexOf(':');
190
- if (firstColonIndex === 0 || firstColonIndex === entityReference.length - 1) {
191
- throw new Error('Invalid identity entityReference: ' + entityReference);
192
- }
193
- const entityName = entityReference.slice(0, firstColonIndex);
194
- const id = entityReference.slice(firstColonIndex + 1);
195
- const entity = await this.entities.get({
196
- entityName,
197
- id
242
+ return (0, telemetry_1.traceSection)('get_entity_by_identity', { [telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_TYPE]: this.baseType }, async (span) => {
243
+ const identityEntity = await this.getIdentityEntity(params);
244
+ if (!identityEntity) {
245
+ span.setAttribute(telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_FOUND, false);
246
+ return undefined;
247
+ }
248
+ const entityReference = identityEntity.entityReference;
249
+ if (typeof entityReference !== 'string' || !entityReference.includes(':')) {
250
+ throw new Error(`Invalid identity entityReference: ${String(entityReference)}`);
251
+ }
252
+ const firstColonIndex = entityReference.indexOf(':');
253
+ if (firstColonIndex === 0 || firstColonIndex === entityReference.length - 1) {
254
+ throw new Error('Invalid identity entityReference: ' + entityReference);
255
+ }
256
+ const entityName = entityReference.slice(0, firstColonIndex);
257
+ const id = entityReference.slice(firstColonIndex + 1);
258
+ const entity = await this.entities.get({
259
+ entityName,
260
+ id
261
+ });
262
+ span.setAttribute(telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_FOUND, !!entity);
263
+ return entity;
198
264
  });
199
- return entity;
200
265
  }
201
266
  /**This will query for the entity, and handle post-processing
202
267
  * of any critieria that is defined at the sub-type level.
@@ -216,9 +281,12 @@ class BaseEntityProcessor {
216
281
  if (!propertyCriteria || Object.getOwnPropertyNames(propertyCriteria).length == 0) {
217
282
  throw new Error('propertyCriteria must be defined and have at least one property');
218
283
  }
219
- const { rootTypeCriteria, subTypeCriteria } = await this.getCriteriaForEntity(entityType, entityTypePath, propertyCriteria);
220
- const returnedEntities = await this.dc.getAllObjectReferences(entityType, rootTypeCriteria, subTypeCriteria);
221
- return returnedEntities;
284
+ return (0, telemetry_1.traceSection)('query_entities_by_criteria', { [telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_TYPE]: entityType }, async (span) => {
285
+ const { rootTypeCriteria, subTypeCriteria } = await this.getCriteriaForEntity(entityType, entityTypePath, propertyCriteria);
286
+ const returnedEntities = await this.dc.getAllObjectReferences(entityType, rootTypeCriteria, subTypeCriteria);
287
+ span.setAttribute(telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_RESULT_COUNT, Array.isArray(returnedEntities) ? returnedEntities.length : 0);
288
+ return returnedEntities;
289
+ });
222
290
  }
223
291
  /** This is to get the criteria for the entity that is being processed.
224
292
  * This is to be overridden for item & project-item because of the need for
@@ -268,7 +336,11 @@ class BaseEntityProcessor {
268
336
  return rootTypePropertyKeys;
269
337
  }
270
338
  async handleIncomingDelete(event) {
271
- console.warn('delete is not configured', event);
339
+ // Only identifying fields are logged, not the event data.
340
+ telemetry_1.logger.warn({ flexplm: {
341
+ direction: 'inbound', event_type: event?.eventType, entity_type: this.baseType,
342
+ object_class: event?.objectClass, federated_id: event?.federatedId,
343
+ } }, 'FlexPLM delete is not configured');
272
344
  }
273
345
  async getTransformedData(event) {
274
346
  let inboundData = event.data;
@@ -327,7 +399,15 @@ class BaseEntityProcessor {
327
399
  object: changes,
328
400
  };
329
401
  console.log("createEntity: " + JSON.stringify(options));
330
- return await new sdk_1.Entities().create(options);
402
+ return (0, telemetry_1.traceSection)('create_vibeiq_entity', {
403
+ [telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_TYPE]: entityName,
404
+ [telemetry_attributes_1.ATTR_FLEXPLM_CHANGED_PROPERTY_COUNT]: countProperties(changes),
405
+ }, async (span) => {
406
+ const created = await new sdk_1.Entities().create(options);
407
+ if (created?.id)
408
+ span.setAttribute(telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_ID, created.id);
409
+ return created;
410
+ });
331
411
  }
332
412
  async updateEntity(entityName, entity, diffs) {
333
413
  const options = {
@@ -336,68 +416,78 @@ class BaseEntityProcessor {
336
416
  object: diffs
337
417
  };
338
418
  console.log('updateEntity: ' + JSON.stringify(options));
339
- return await new sdk_1.Entities().update(options);
419
+ return (0, telemetry_1.traceSection)('update_vibeiq_entity', {
420
+ [telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_TYPE]: entityName,
421
+ [telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_ID]: entity?.['id'],
422
+ [telemetry_attributes_1.ATTR_FLEXPLM_CHANGED_PROPERTY_COUNT]: countProperties(diffs),
423
+ }, () => new sdk_1.Entities().update(options));
340
424
  }
341
425
  // outbound
342
426
  async outbound(event) {
343
- const entityType = event.entityType;
344
- const eventType = event.eventType;
345
- const entityId = event.id;
346
- console.log(`outbound: ${entityType}:${entityId}`);
347
- switch (eventType) {
348
- case 'update':
349
- case 'create':
350
- return await this.handleOutgoingUpsert(entityType, event);
351
- case 'delete':
352
- return await this.handleOutgoingDelete(entityType, event);
353
- case 'sendUpsertToFlexPLM':
354
- return await this.sendUpsertToFlexPLM(event);
355
- default:
356
- console.log(UNSUPPORTED_TYPE);
427
+ return (0, telemetry_1.traceSection)('process_outbound_entity', {
428
+ [telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_TYPE]: this.baseType,
429
+ [telemetry_attributes_1.ATTR_FLEXPLM_EVENT_TYPE]: event?.eventType,
430
+ }, async () => {
431
+ const entityType = event.entityType;
432
+ const eventType = event.eventType;
433
+ (0, telemetry_utils_1.setActiveSpanAttributes)({ [telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_ID]: event.id });
434
+ switch (eventType) {
435
+ case 'update':
436
+ case 'create':
437
+ return await this.handleOutgoingUpsert(entityType, event);
438
+ case 'delete':
439
+ return await this.handleOutgoingDelete(entityType, event);
440
+ case 'sendUpsertToFlexPLM':
441
+ return await this.sendUpsertToFlexPLM(event);
442
+ default:
443
+ telemetry_1.logger.warn({ flexplm: { direction: 'outbound', event_type: eventType, entity_type: this.baseType, entity_id: event.id } }, 'Unsupported FlexPLM event type');
444
+ return {
445
+ status: 500,
446
+ data: { UNSUPPORTED_TYPE }
447
+ };
448
+ }
449
+ });
450
+ }
451
+ async handleOutgoingUpsert(entityType, event) {
452
+ return (0, telemetry_1.traceSection)('upsert_entity_in_flexplm', { [telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_TYPE]: this.baseType }, async () => {
453
+ const objectClass = await type_conversion_utils_1.TypeConversionUtils.getObjectClass(this.transformMapFile, this.mapFileUtil, event.newData);
454
+ if (!objectClass) {
455
+ const message = 'ObjectClass must have a value.';
456
+ telemetry_1.logger.warn({ flexplm: { direction: 'outbound', entity_type: this.baseType, entity_id: event.id } }, message);
357
457
  return {
358
458
  status: 500,
359
- data: { UNSUPPORTED_TYPE }
459
+ data: { message }
360
460
  };
361
- }
362
- }
363
- async handleOutgoingUpsert(entityType, event) {
364
- const objectClass = await type_conversion_utils_1.TypeConversionUtils.getObjectClass(this.transformMapFile, this.mapFileUtil, event.newData);
365
- if (!objectClass) {
366
- const message = 'ObjectClass must have a value.';
367
- console.log(message);
368
- return {
369
- status: 500,
370
- data: { message }
371
- };
372
- }
373
- try {
374
- const payload = await this.getOutgoingUpsertPayload(entityType, event);
375
- const flexResponse = await new flexplm_connect_1.FlexPLMConnect(this.config).sendToFlexPLM(payload);
376
- const outboundEntityUpdates = await this.getOutboundEntityUpdates(event, flexResponse);
377
- if (outboundEntityUpdates) {
378
- flexResponse['outboundEntityUpdates'] = outboundEntityUpdates;
379
461
  }
380
- const statusMsg = 'BaseEntityProcessor: outbound: status: ' + event_short_message_status_1.EventShortMessageStatus.SUCCESS
381
- + ', statusMessage: ' + flexResponse.status
382
- + ', entityType: ' + this.baseType
383
- + ', entityId: ' + event.id
384
- + ', objectClass: ' + payload.objectClass
385
- + ', updateFromResponse: ' + ((outboundEntityUpdates && Object.keys(outboundEntityUpdates).length > 0) ? 'true' : 'false')
386
- + ', orgSlug: ' + this.orgSlug;
387
- console.log(statusMsg);
388
- return flexResponse;
389
- }
390
- catch (e) {
391
- const statusMsg = 'BaseEntityProcessor: outbound: status: ' + event_short_message_status_1.EventShortMessageStatus.FAILURE
392
- + ', statusMessage: ' + e.httpResponseStatus
393
- + ', entityType: ' + this.baseType
394
- + ', entityId: ' + event.id
395
- + ', objectClass: ' + objectClass
396
- + ', updateFromResponse: ' + 'false'
397
- + ', orgSlug: ' + this.orgSlug;
398
- console.log(statusMsg);
399
- throw e;
400
- }
462
+ try {
463
+ const payload = await this.getOutgoingUpsertPayload(entityType, event);
464
+ const flexResponse = await new flexplm_connect_1.FlexPLMConnect(this.config).sendToFlexPLM(payload);
465
+ const outboundEntityUpdates = await this.getOutboundEntityUpdates(event, flexResponse);
466
+ if (outboundEntityUpdates) {
467
+ flexResponse['outboundEntityUpdates'] = outboundEntityUpdates;
468
+ }
469
+ this.recordOutboundStatus({
470
+ status: event_short_message_status_1.EventShortMessageStatus.SUCCESS,
471
+ entityId: event.id,
472
+ objectClass: payload.objectClass,
473
+ httpStatus: flexResponse.status,
474
+ updatedFromResponse: hasUpdates(outboundEntityUpdates),
475
+ itemStatus: getResponseItemStatus(flexResponse),
476
+ });
477
+ return flexResponse;
478
+ }
479
+ catch (e) {
480
+ this.recordOutboundStatus({
481
+ status: event_short_message_status_1.EventShortMessageStatus.FAILURE,
482
+ entityId: event.id,
483
+ objectClass,
484
+ httpStatus: e.httpResponseStatus,
485
+ updatedFromResponse: false,
486
+ error: e,
487
+ });
488
+ throw e;
489
+ }
490
+ });
401
491
  }
402
492
  async getOutboundEntityUpdates(event, flexResponse) {
403
493
  const payload = flexResponse?.data?.payload;
@@ -413,7 +503,10 @@ class BaseEntityProcessor {
413
503
  return outboundEntityUpdates;
414
504
  }
415
505
  async handleOutgoingDelete(entityType, event) {
416
- console.warn('delete is not configured', entityType, event.oldData);
506
+ // Only identifying fields are logged, not oldData.
507
+ telemetry_1.logger.warn({ flexplm: {
508
+ direction: 'outbound', event_type: event?.eventType, entity_type: entityType, entity_id: event?.id,
509
+ } }, 'FlexPLM delete is not configured');
417
510
  }
418
511
  /** Create a new event-workflow-request to rerun sending the entity to FlexPLM
419
512
  * The event must contain any information needed to ensure it is put in the correct queue for the entity
@@ -440,44 +533,46 @@ class BaseEntityProcessor {
440
533
  * @returns results of sending the entity to FlexPLM
441
534
  */
442
535
  async sendUpsertToFlexPLM(event) {
443
- const payload = await this.getEntityCurrentStateUpsertPayload(event);
444
- if (!payload) {
445
- const message = 'No payload to send to FlexPLM';
446
- console.log(message);
447
- return {
448
- status: 500,
449
- data: { message }
450
- };
451
- }
452
- ;
453
- let objectClass = payload.objectClass;
454
- try {
455
- const flexResponse = await new flexplm_connect_1.FlexPLMConnect(this.config).sendToFlexPLM(payload);
456
- const outboundEntityUpdates = await this.getOutboundEntityUpdates(event, flexResponse);
457
- if (outboundEntityUpdates) {
458
- flexResponse['outboundEntityUpdates'] = outboundEntityUpdates;
536
+ return (0, telemetry_1.traceSection)('send_current_entity_to_flexplm', { [telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_TYPE]: this.baseType }, async () => {
537
+ const payload = await this.getEntityCurrentStateUpsertPayload(event);
538
+ if (!payload) {
539
+ const message = 'No payload to send to FlexPLM';
540
+ telemetry_1.logger.warn({ flexplm: { direction: 'outbound', entity_type: this.baseType, entity_id: event.id } }, message);
541
+ return {
542
+ status: 500,
543
+ data: { message }
544
+ };
459
545
  }
460
- const statusMsg = 'BaseEntityProcessor: outbound: status: ' + event_short_message_status_1.EventShortMessageStatus.SUCCESS
461
- + ', statusMessage: ' + flexResponse.status
462
- + ', entityType: ' + this.baseType
463
- + ', entityId: ' + event.id
464
- + ', objectClass: ' + objectClass
465
- + ', updateFromResponse: ' + ((outboundEntityUpdates && Object.keys(outboundEntityUpdates).length > 0) ? 'true' : 'false')
466
- + ', orgSlug: ' + this.orgSlug;
467
- console.log(statusMsg);
468
- return flexResponse;
469
- }
470
- catch (e) {
471
- const statusMsg = 'BaseEntityProcessor: outbound: status: ' + event_short_message_status_1.EventShortMessageStatus.FAILURE
472
- + ', statusMessage: ' + e.httpResponseStatus
473
- + ', entityType: ' + this.baseType
474
- + ', entityId: ' + event.id
475
- + ', objectClass: ' + objectClass
476
- + ', updateFromResponse: ' + 'false'
477
- + ', orgSlug: ' + this.orgSlug;
478
- console.log(statusMsg);
479
- throw e;
480
- }
546
+ ;
547
+ let objectClass = payload.objectClass;
548
+ try {
549
+ const flexResponse = await new flexplm_connect_1.FlexPLMConnect(this.config).sendToFlexPLM(payload);
550
+ const outboundEntityUpdates = await this.getOutboundEntityUpdates(event, flexResponse);
551
+ if (outboundEntityUpdates) {
552
+ flexResponse['outboundEntityUpdates'] = outboundEntityUpdates;
553
+ }
554
+ this.recordOutboundStatus({
555
+ status: event_short_message_status_1.EventShortMessageStatus.SUCCESS,
556
+ entityId: event.id,
557
+ objectClass,
558
+ httpStatus: flexResponse.status,
559
+ updatedFromResponse: hasUpdates(outboundEntityUpdates),
560
+ itemStatus: getResponseItemStatus(flexResponse),
561
+ });
562
+ return flexResponse;
563
+ }
564
+ catch (e) {
565
+ this.recordOutboundStatus({
566
+ status: event_short_message_status_1.EventShortMessageStatus.FAILURE,
567
+ entityId: event.id,
568
+ objectClass,
569
+ httpStatus: e.httpResponseStatus,
570
+ updatedFromResponse: false,
571
+ error: e,
572
+ });
573
+ throw e;
574
+ }
575
+ });
481
576
  }
482
577
  /** Generates the payload to send to FlexPLM, based on the current state of the entity.
483
578
  * The current state of the entity are used as the newData and oldData; which is passed