@contrail/flexplm 1.1.51 → 1.1.53
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.
- package/lib/entity-processor/base-entity-processor.d.ts +1 -0
- package/lib/entity-processor/base-entity-processor.js +100 -14
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/publish/base-process-publish-assortment.d.ts +18 -0
- package/lib/publish/base-process-publish-assortment.js +35 -4
- package/lib/transform/identifier-conversion-spec-mockData.d.ts +0 -0
- package/lib/transform/identifier-conversion-spec-mockData.js +444 -0
- package/lib/transform/identifier-conversion.d.ts +6 -0
- package/lib/transform/identifier-conversion.js +47 -0
- package/lib/transform/identifier-conversion.spec.d.ts +1 -0
- package/lib/transform/identifier-conversion.spec.js +339 -0
- package/lib/util/event-short-message-status.d.ts +14 -0
- package/lib/util/event-short-message-status.js +18 -0
- package/lib/util/flexplm-connect.js +6 -2
- package/package.json +1 -1
- package/src/entity-processor/base-entity-processor.ts +106 -20
- package/src/index.ts +1 -0
- package/src/publish/base-process-publish-assortment.ts +44 -9
- package/src/transform/identifier-conversion-spec-mockData.ts +496 -0
- package/src/transform/identifier-conversion.spec.ts +354 -0
- package/src/transform/identifier-conversion.ts +56 -0
- package/src/util/event-short-message-status.ts +17 -0
- package/src/util/flexplm-connect.ts +7 -3
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const transform_data_1 = require("@contrail/transform-data");
|
|
4
|
+
const identifier_conversion_1 = require("./identifier-conversion");
|
|
5
|
+
const data_converter_1 = require("../util/data-converter");
|
|
6
|
+
const sdk_1 = require("@contrail/sdk");
|
|
7
|
+
const mapFile1Data = require('./identifier-conversion-spec-mockData');
|
|
8
|
+
const mapFile1Mappings = mapFile1Data?.mapping;
|
|
9
|
+
const mapFile2Mappings = mapFile1Data?.mapping2;
|
|
10
|
+
const mappings = {
|
|
11
|
+
mapFile1: mapFile1Mappings,
|
|
12
|
+
mapFile2: mapFile2Mappings
|
|
13
|
+
};
|
|
14
|
+
describe('getAssortmentFromObject', () => {
|
|
15
|
+
const transformMapFile1 = 'mapFile1';
|
|
16
|
+
const transformMapFile2 = 'mapFile2';
|
|
17
|
+
const config = {};
|
|
18
|
+
const mapFileUtil = new transform_data_1.MapFileUtil(new sdk_1.Entities());
|
|
19
|
+
mapFileUtil.getMapFile = async (fileId) => {
|
|
20
|
+
return mappings[fileId];
|
|
21
|
+
};
|
|
22
|
+
const dc = new data_converter_1.DataConverter(config, mapFileUtil);
|
|
23
|
+
dc.getEntityValues = async (objectClass, data, keysToSkip = []) => {
|
|
24
|
+
const entityValues = {};
|
|
25
|
+
for (const key of Object.keys(data)) {
|
|
26
|
+
const value = data[key];
|
|
27
|
+
if (value) {
|
|
28
|
+
const to = typeof value;
|
|
29
|
+
if (['string', 'number', 'boolean'].includes(to)) {
|
|
30
|
+
entityValues[key] = value;
|
|
31
|
+
}
|
|
32
|
+
else if (Array.isArray(value)) {
|
|
33
|
+
entityValues[key] = value.map((v) => v.value);
|
|
34
|
+
}
|
|
35
|
+
else if (value.value) {
|
|
36
|
+
entityValues[key] = value.value;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return entityValues;
|
|
41
|
+
};
|
|
42
|
+
it('should error if no object is provided', async () => {
|
|
43
|
+
try {
|
|
44
|
+
await identifier_conversion_1.IdentifierConversion.getAssortmentCriteriaFromObject(transformMapFile1, mapFileUtil, dc, null);
|
|
45
|
+
}
|
|
46
|
+
catch (e) {
|
|
47
|
+
expect(e.message).toEqual(expect.stringContaining(identifier_conversion_1.IdentifierConversion.MISSING_OBJECT));
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
it('should error if no flexPLMObjectClass is provided', async () => {
|
|
51
|
+
try {
|
|
52
|
+
await identifier_conversion_1.IdentifierConversion.getAssortmentCriteriaFromObject(transformMapFile1, mapFileUtil, dc, {});
|
|
53
|
+
}
|
|
54
|
+
catch (e) {
|
|
55
|
+
expect(e.message).toEqual(expect.stringContaining(identifier_conversion_1.IdentifierConversion.MISSING_FLEXPLM_OBJECT_CLASS));
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
it('should return the assortment criteria from the object - flexPLMSeasonName', async () => {
|
|
59
|
+
const object = {
|
|
60
|
+
"brand": {
|
|
61
|
+
"display": "Vibe IQ",
|
|
62
|
+
"value": "vibeiq"
|
|
63
|
+
},
|
|
64
|
+
"flexPLMObjectClass": "LCSSeason",
|
|
65
|
+
"flexPLMTypePath": "Season",
|
|
66
|
+
"seasonName": "Vibe IQ Spring 2004",
|
|
67
|
+
"seasonType": {
|
|
68
|
+
"display": "Spring",
|
|
69
|
+
"value": "spring"
|
|
70
|
+
},
|
|
71
|
+
"year": {
|
|
72
|
+
"display": "2004",
|
|
73
|
+
"value": "2004"
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
const criteriaObject = {
|
|
77
|
+
flexPLMObjectClass: 'LCSSeason',
|
|
78
|
+
flexPLMSeasonName: 'Vibe IQ Spring 2004',
|
|
79
|
+
flexPLMTypePath: 'Season'
|
|
80
|
+
};
|
|
81
|
+
const resultsObject = {
|
|
82
|
+
flexPLMSeasonName: 'Vibe IQ Spring 2004'
|
|
83
|
+
};
|
|
84
|
+
let getEntityValuesSpyOn = undefined;
|
|
85
|
+
try {
|
|
86
|
+
getEntityValuesSpyOn = jest.spyOn(dc, 'getEntityValues');
|
|
87
|
+
const result = await identifier_conversion_1.IdentifierConversion.getAssortmentCriteriaFromObject(transformMapFile1, mapFileUtil, dc, object);
|
|
88
|
+
expect(getEntityValuesSpyOn).toHaveBeenCalledWith('LCSSeason', criteriaObject, []);
|
|
89
|
+
expect(result).toEqual(resultsObject);
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
if (getEntityValuesSpyOn) {
|
|
93
|
+
getEntityValuesSpyOn.mockRestore();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
it('should return the assortment criteria from the object - brand,year,seasonType', async () => {
|
|
98
|
+
const object = {
|
|
99
|
+
brand: {
|
|
100
|
+
display: "Vibe IQ",
|
|
101
|
+
value: "vibeiq"
|
|
102
|
+
},
|
|
103
|
+
flexPLMObjectClass: "LCSSeason",
|
|
104
|
+
flexPLMTypePath: "Season",
|
|
105
|
+
seasonName: "Vibe IQ Spring 2004",
|
|
106
|
+
seasonType: {
|
|
107
|
+
display: "Spring",
|
|
108
|
+
value: "spring"
|
|
109
|
+
},
|
|
110
|
+
year: {
|
|
111
|
+
"display": "2004",
|
|
112
|
+
"value": "2004"
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
const criteriaObject = {
|
|
116
|
+
flexPLMObjectClass: 'LCSSeason',
|
|
117
|
+
brand: {
|
|
118
|
+
"display": "Vibe IQ",
|
|
119
|
+
"value": "vibeiq"
|
|
120
|
+
},
|
|
121
|
+
year: {
|
|
122
|
+
"display": "2004",
|
|
123
|
+
"value": "2004"
|
|
124
|
+
},
|
|
125
|
+
seasonType: {
|
|
126
|
+
"display": "Spring",
|
|
127
|
+
"value": "spring"
|
|
128
|
+
},
|
|
129
|
+
flexPLMTypePath: 'Season'
|
|
130
|
+
};
|
|
131
|
+
const resultsObject = {
|
|
132
|
+
brand: 'vibeiq',
|
|
133
|
+
year: '2004',
|
|
134
|
+
seasonType: 'spring'
|
|
135
|
+
};
|
|
136
|
+
let getEntityValuesSpyOn = undefined;
|
|
137
|
+
try {
|
|
138
|
+
getEntityValuesSpyOn = jest.spyOn(dc, 'getEntityValues');
|
|
139
|
+
const result = await identifier_conversion_1.IdentifierConversion.getAssortmentCriteriaFromObject(transformMapFile2, mapFileUtil, dc, object);
|
|
140
|
+
expect(getEntityValuesSpyOn).toHaveBeenCalledWith('LCSSeason', criteriaObject, []);
|
|
141
|
+
expect(result).toEqual(resultsObject);
|
|
142
|
+
}
|
|
143
|
+
finally {
|
|
144
|
+
if (getEntityValuesSpyOn) {
|
|
145
|
+
getEntityValuesSpyOn.mockRestore();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
describe('getItemCriteriaFromObject', () => {
|
|
151
|
+
const transformMapFile1 = 'mapFile1';
|
|
152
|
+
const transformMapFile2 = 'mapFile2';
|
|
153
|
+
const config = {};
|
|
154
|
+
const mapFileUtil = new transform_data_1.MapFileUtil(new sdk_1.Entities());
|
|
155
|
+
mapFileUtil.getMapFile = async (fileId) => {
|
|
156
|
+
return mappings[fileId];
|
|
157
|
+
};
|
|
158
|
+
const dc = new data_converter_1.DataConverter(config, mapFileUtil);
|
|
159
|
+
dc.getEntityValues = async (objectClass, data, keysToSkip = []) => {
|
|
160
|
+
const entityValues = {};
|
|
161
|
+
for (const key of Object.keys(data)) {
|
|
162
|
+
const value = data[key];
|
|
163
|
+
if (value) {
|
|
164
|
+
const to = typeof value;
|
|
165
|
+
if (['string', 'number', 'boolean'].includes(to)) {
|
|
166
|
+
entityValues[key] = value;
|
|
167
|
+
}
|
|
168
|
+
else if (Array.isArray(value)) {
|
|
169
|
+
entityValues[key] = value.map((v) => v.value);
|
|
170
|
+
}
|
|
171
|
+
else if (value.value) {
|
|
172
|
+
entityValues[key] = value.value;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return entityValues;
|
|
177
|
+
};
|
|
178
|
+
it('should error if no object is provided', async () => {
|
|
179
|
+
try {
|
|
180
|
+
await identifier_conversion_1.IdentifierConversion.getItemCriteriaFromObject(transformMapFile1, mapFileUtil, dc, null);
|
|
181
|
+
}
|
|
182
|
+
catch (e) {
|
|
183
|
+
expect(e.message).toEqual(expect.stringContaining(identifier_conversion_1.IdentifierConversion.MISSING_OBJECT));
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
it('should error if no flexPLMObjectClass is provided', async () => {
|
|
187
|
+
try {
|
|
188
|
+
await identifier_conversion_1.IdentifierConversion.getItemCriteriaFromObject(transformMapFile1, mapFileUtil, dc, {});
|
|
189
|
+
}
|
|
190
|
+
catch (e) {
|
|
191
|
+
expect(e.message).toEqual(expect.stringContaining(identifier_conversion_1.IdentifierConversion.MISSING_FLEXPLM_OBJECT_CLASS));
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
it('should error if missing identifier properties -itemNumber', async () => {
|
|
195
|
+
const object = {
|
|
196
|
+
"flexBoolean": false,
|
|
197
|
+
"flexMultiSelect": [],
|
|
198
|
+
"flexNumber": 0,
|
|
199
|
+
"flexPLMObjectClass": "LCSProduct",
|
|
200
|
+
"flexPLMTypePath": "Product\\Pants",
|
|
201
|
+
"flexSingleList": {
|
|
202
|
+
"display": "Five",
|
|
203
|
+
"value": "five"
|
|
204
|
+
},
|
|
205
|
+
"productName": "Feb 3 - 1 Option A",
|
|
206
|
+
"NotvibeIQIdentifier": 966
|
|
207
|
+
};
|
|
208
|
+
const criteriaObject = {
|
|
209
|
+
flexPLMObjectClass: 'LCSProduct',
|
|
210
|
+
flexPLMTypePath: 'Product\\Pants',
|
|
211
|
+
};
|
|
212
|
+
let getEntityValuesSpyOn = undefined;
|
|
213
|
+
try {
|
|
214
|
+
getEntityValuesSpyOn = jest.spyOn(dc, 'getEntityValues');
|
|
215
|
+
await identifier_conversion_1.IdentifierConversion.getItemCriteriaFromObject(transformMapFile1, mapFileUtil, dc, object);
|
|
216
|
+
}
|
|
217
|
+
catch (e) {
|
|
218
|
+
expect(getEntityValuesSpyOn).toHaveBeenCalledWith('LCSProduct', criteriaObject, []);
|
|
219
|
+
expect(e.message).toEqual(expect.stringContaining(identifier_conversion_1.IdentifierConversion.INBOUND_ENTITY_MISSING_IDENIFIER_PROPS));
|
|
220
|
+
}
|
|
221
|
+
finally {
|
|
222
|
+
if (getEntityValuesSpyOn) {
|
|
223
|
+
getEntityValuesSpyOn.mockRestore();
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
it('should return the item family criteria from the object -itemNumber', async () => {
|
|
228
|
+
const object = {
|
|
229
|
+
"flexBoolean": false,
|
|
230
|
+
"flexMultiSelect": [],
|
|
231
|
+
"flexNumber": 0,
|
|
232
|
+
"flexPLMObjectClass": "LCSProduct",
|
|
233
|
+
"flexPLMTypePath": "Product\\Pants",
|
|
234
|
+
"flexSingleList": {
|
|
235
|
+
"display": "Five",
|
|
236
|
+
"value": "five"
|
|
237
|
+
},
|
|
238
|
+
"productName": "Feb 3 - 1 Option A",
|
|
239
|
+
"vibeIQIdentifier": 966
|
|
240
|
+
};
|
|
241
|
+
const criteriaObject = {
|
|
242
|
+
flexPLMObjectClass: 'LCSProduct',
|
|
243
|
+
itemNumber: 966,
|
|
244
|
+
flexPLMTypePath: 'Product\\Pants',
|
|
245
|
+
};
|
|
246
|
+
const resultsObject = {
|
|
247
|
+
roles: 'family',
|
|
248
|
+
itemNumber: 966
|
|
249
|
+
};
|
|
250
|
+
let getEntityValuesSpyOn = undefined;
|
|
251
|
+
try {
|
|
252
|
+
getEntityValuesSpyOn = jest.spyOn(dc, 'getEntityValues');
|
|
253
|
+
const result = await identifier_conversion_1.IdentifierConversion.getItemCriteriaFromObject(transformMapFile1, mapFileUtil, dc, object);
|
|
254
|
+
expect(getEntityValuesSpyOn).toHaveBeenCalledWith('LCSProduct', criteriaObject, []);
|
|
255
|
+
expect(result).toEqual(resultsObject);
|
|
256
|
+
}
|
|
257
|
+
finally {
|
|
258
|
+
if (getEntityValuesSpyOn) {
|
|
259
|
+
getEntityValuesSpyOn.mockRestore();
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
it('should return the item option criteria from the object -itemNumber', async () => {
|
|
264
|
+
const object = {
|
|
265
|
+
"flexBoolean": false,
|
|
266
|
+
"flexMultiSelect": [],
|
|
267
|
+
"flexNumber": 0,
|
|
268
|
+
"flexPLMObjectClass": "LCSSKU",
|
|
269
|
+
"flexPLMTypePath": "Product\\Pants",
|
|
270
|
+
"flexSingleList": {
|
|
271
|
+
"display": "Five",
|
|
272
|
+
"value": "five"
|
|
273
|
+
},
|
|
274
|
+
"productName": "Feb 3 - 1 Option A",
|
|
275
|
+
"vibeIQIdentifier": 2876
|
|
276
|
+
};
|
|
277
|
+
const criteriaObject = {
|
|
278
|
+
flexPLMObjectClass: 'LCSSKU',
|
|
279
|
+
itemNumber: 2876,
|
|
280
|
+
flexPLMTypePath: 'Product\\Pants',
|
|
281
|
+
};
|
|
282
|
+
const resultsObject = {
|
|
283
|
+
roles: 'color',
|
|
284
|
+
itemNumber: 2876
|
|
285
|
+
};
|
|
286
|
+
let getEntityValuesSpyOn = undefined;
|
|
287
|
+
try {
|
|
288
|
+
getEntityValuesSpyOn = jest.spyOn(dc, 'getEntityValues');
|
|
289
|
+
const result = await identifier_conversion_1.IdentifierConversion.getItemCriteriaFromObject(transformMapFile1, mapFileUtil, dc, object);
|
|
290
|
+
expect(getEntityValuesSpyOn).toHaveBeenCalledWith('LCSSKU', criteriaObject, []);
|
|
291
|
+
expect(result).toEqual(resultsObject);
|
|
292
|
+
}
|
|
293
|
+
finally {
|
|
294
|
+
if (getEntityValuesSpyOn) {
|
|
295
|
+
getEntityValuesSpyOn.mockRestore();
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
it('should return the item option criteria from the object -uniqueIdentifierA, uniqueIdentifierB', async () => {
|
|
300
|
+
const object = {
|
|
301
|
+
"flexBoolean": false,
|
|
302
|
+
"flexMultiSelect": [],
|
|
303
|
+
"flexNumber": 0,
|
|
304
|
+
"flexPLMObjectClass": "LCSSKU",
|
|
305
|
+
"flexPLMTypePath": "Product\\Pants",
|
|
306
|
+
"flexSingleList": {
|
|
307
|
+
"display": "Five",
|
|
308
|
+
"value": "five"
|
|
309
|
+
},
|
|
310
|
+
"productName": "Feb 3 - 1 Option A",
|
|
311
|
+
uniqueIdentifierA: 28,
|
|
312
|
+
uniqueIdentifierB: 29,
|
|
313
|
+
"vibeIQIdentifier": 2876
|
|
314
|
+
};
|
|
315
|
+
const criteriaObject = {
|
|
316
|
+
flexPLMObjectClass: 'LCSSKU',
|
|
317
|
+
uniqueIdentifierA: 28,
|
|
318
|
+
uniqueIdentifierB: 29,
|
|
319
|
+
flexPLMTypePath: 'Product\\Pants',
|
|
320
|
+
};
|
|
321
|
+
const resultsObject = {
|
|
322
|
+
roles: 'color',
|
|
323
|
+
uniqueIdentifierA: 28,
|
|
324
|
+
uniqueIdentifierB: 29,
|
|
325
|
+
};
|
|
326
|
+
let getEntityValuesSpyOn = undefined;
|
|
327
|
+
try {
|
|
328
|
+
getEntityValuesSpyOn = jest.spyOn(dc, 'getEntityValues');
|
|
329
|
+
const result = await identifier_conversion_1.IdentifierConversion.getItemCriteriaFromObject(transformMapFile2, mapFileUtil, dc, object);
|
|
330
|
+
expect(getEntityValuesSpyOn).toHaveBeenCalledWith('LCSSKU', criteriaObject, []);
|
|
331
|
+
expect(result).toEqual(resultsObject);
|
|
332
|
+
}
|
|
333
|
+
finally {
|
|
334
|
+
if (getEntityValuesSpyOn) {
|
|
335
|
+
getEntityValuesSpyOn.mockRestore();
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare enum EventShortMessageStatus {
|
|
2
|
+
SUCCESS = "Success",
|
|
3
|
+
FAILURE = "Failure",
|
|
4
|
+
CREATED = "Created",
|
|
5
|
+
MISSING_IDENTIFIER_PROPERTIES = "Missing_identifier_properties",
|
|
6
|
+
MISSING_INPUT = "Missing_input",
|
|
7
|
+
NOT_CREATABLE = "Not_creatable",
|
|
8
|
+
NO_CHANGES = "No_Changes",
|
|
9
|
+
TOO_MANY_ENTITIES_FOUND = "Too_Many_Entities_Found",
|
|
10
|
+
UPDATED = "Updated",
|
|
11
|
+
NOT_PUBLISHABLE = "Not_Publishable",
|
|
12
|
+
NO_FEDERATION_INFO = "No_Federation_Information",
|
|
13
|
+
NO_EVENTS_TO_SEND = "No_Events_to_Send"
|
|
14
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EventShortMessageStatus = void 0;
|
|
4
|
+
var EventShortMessageStatus;
|
|
5
|
+
(function (EventShortMessageStatus) {
|
|
6
|
+
EventShortMessageStatus["SUCCESS"] = "Success";
|
|
7
|
+
EventShortMessageStatus["FAILURE"] = "Failure";
|
|
8
|
+
EventShortMessageStatus["CREATED"] = "Created";
|
|
9
|
+
EventShortMessageStatus["MISSING_IDENTIFIER_PROPERTIES"] = "Missing_identifier_properties";
|
|
10
|
+
EventShortMessageStatus["MISSING_INPUT"] = "Missing_input";
|
|
11
|
+
EventShortMessageStatus["NOT_CREATABLE"] = "Not_creatable";
|
|
12
|
+
EventShortMessageStatus["NO_CHANGES"] = "No_Changes";
|
|
13
|
+
EventShortMessageStatus["TOO_MANY_ENTITIES_FOUND"] = "Too_Many_Entities_Found";
|
|
14
|
+
EventShortMessageStatus["UPDATED"] = "Updated";
|
|
15
|
+
EventShortMessageStatus["NOT_PUBLISHABLE"] = "Not_Publishable";
|
|
16
|
+
EventShortMessageStatus["NO_FEDERATION_INFO"] = "No_Federation_Information";
|
|
17
|
+
EventShortMessageStatus["NO_EVENTS_TO_SEND"] = "No_Events_to_Send";
|
|
18
|
+
})(EventShortMessageStatus = exports.EventShortMessageStatus || (exports.EventShortMessageStatus = {}));
|
|
@@ -48,7 +48,9 @@ class FlexPLMConnect {
|
|
|
48
48
|
const message = 'Error connecting to FlexPLM:status: ' + response.status;
|
|
49
49
|
console.error(message);
|
|
50
50
|
console.error(await response.text());
|
|
51
|
-
|
|
51
|
+
const e = new Error(message);
|
|
52
|
+
e['httpResponseStatus'] = response.status;
|
|
53
|
+
throw e;
|
|
52
54
|
}
|
|
53
55
|
try {
|
|
54
56
|
const body = await response.json();
|
|
@@ -109,7 +111,9 @@ class FlexPLMConnect {
|
|
|
109
111
|
const message = 'Error sending data to FlexPLM:status: ' + response.status;
|
|
110
112
|
console.error(message);
|
|
111
113
|
console.error(await response.text());
|
|
112
|
-
|
|
114
|
+
const e = new Error(message);
|
|
115
|
+
e['httpResponseStatus'] = status;
|
|
116
|
+
throw e;
|
|
113
117
|
}
|
|
114
118
|
try {
|
|
115
119
|
const res = {
|
package/package.json
CHANGED
|
@@ -6,6 +6,7 @@ import { MapUtil } from '../util/map-utils';
|
|
|
6
6
|
import { MapFileUtil } from '@contrail/transform-data';
|
|
7
7
|
import { Entities } from '@contrail/sdk';
|
|
8
8
|
import { TypeConversionUtils } from '../util/type-conversion-utils';
|
|
9
|
+
import { EventShortMessageStatus } from '../util/event-short-message-status';
|
|
9
10
|
|
|
10
11
|
const UNSUPPORTED_TYPE = 'Unsupported eventType.';
|
|
11
12
|
export class IncomingEntityResponse {
|
|
@@ -14,6 +15,7 @@ export class IncomingEntityResponse {
|
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
export abstract class BaseEntityProcessor {
|
|
18
|
+
|
|
17
19
|
protected typeUtil: TypeUtils;
|
|
18
20
|
protected transformMapFile: string;
|
|
19
21
|
protected entities;
|
|
@@ -52,6 +54,13 @@ export abstract class BaseEntityProcessor {
|
|
|
52
54
|
const incomingEntityResponse = await this.getIncomingEntity(event, inboundData);
|
|
53
55
|
// This case means there was an early return in the getIncomingEntity method
|
|
54
56
|
if (incomingEntityResponse.earlyReturn) {
|
|
57
|
+
const statusMsg = this.getInboundStatusMessage({
|
|
58
|
+
status: EventShortMessageStatus.FAILURE,
|
|
59
|
+
statusMessage: incomingEntityResponse.earlyReturn.shortStatusMessage || '',
|
|
60
|
+
objectClass: event.objectClass,
|
|
61
|
+
federatedId: event.federatedId
|
|
62
|
+
});
|
|
63
|
+
console.log(statusMsg);
|
|
55
64
|
return incomingEntityResponse.earlyReturn;
|
|
56
65
|
}
|
|
57
66
|
|
|
@@ -59,25 +68,68 @@ export abstract class BaseEntityProcessor {
|
|
|
59
68
|
if (!entity) {
|
|
60
69
|
const createEntityResponse = await this.getCreateEntity(inboundData);
|
|
61
70
|
if (createEntityResponse.earlyReturn) {
|
|
62
|
-
|
|
71
|
+
const status = (createEntityResponse.earlyReturn.shortStatusMessage === EventShortMessageStatus.NOT_CREATABLE)
|
|
72
|
+
? EventShortMessageStatus.SUCCESS
|
|
73
|
+
: EventShortMessageStatus.FAILURE;
|
|
74
|
+
const statusMsg = this.getInboundStatusMessage({
|
|
75
|
+
status,
|
|
76
|
+
statusMessage: createEntityResponse.earlyReturn.shortStatusMessage ||'',
|
|
77
|
+
objectClass: event.objectClass,
|
|
78
|
+
federatedId: event.federatedId
|
|
79
|
+
});
|
|
80
|
+
console.log(statusMsg);
|
|
81
|
+
return createEntityResponse.earlyReturn;
|
|
63
82
|
}
|
|
64
|
-
|
|
65
|
-
|
|
83
|
+
const createdEntity = await this.createEntity(this.baseType, createEntityResponse.entity);
|
|
84
|
+
const statusMsg = this.getInboundStatusMessage({
|
|
85
|
+
status: EventShortMessageStatus.SUCCESS,
|
|
86
|
+
statusMessage: EventShortMessageStatus.CREATED,
|
|
87
|
+
objectClass: event.objectClass,
|
|
88
|
+
entityId: 'id',
|
|
89
|
+
federatedId: event.federatedId
|
|
90
|
+
});
|
|
91
|
+
console.log(statusMsg);
|
|
92
|
+
return createdEntity;
|
|
66
93
|
}
|
|
67
94
|
|
|
68
95
|
const diffs = await this.getUpdatesForEntity(entity, inboundData);
|
|
69
96
|
if(Object.getOwnPropertyNames(diffs).length == 0){
|
|
97
|
+
const statusMsg = this.getInboundStatusMessage({
|
|
98
|
+
status: EventShortMessageStatus.SUCCESS,
|
|
99
|
+
statusMessage: EventShortMessageStatus.NO_CHANGES,
|
|
100
|
+
objectClass: event.objectClass,
|
|
101
|
+
entityId: entity.id,
|
|
102
|
+
federatedId: event.federatedId
|
|
103
|
+
});
|
|
104
|
+
console.log(statusMsg);
|
|
70
105
|
const message = 'No Changes to persist for entity: ' + entity.id;
|
|
71
|
-
console.log(message);
|
|
72
106
|
return {
|
|
73
107
|
status: 200,
|
|
74
108
|
data: {message}
|
|
75
109
|
};
|
|
76
110
|
}
|
|
77
111
|
|
|
78
|
-
|
|
112
|
+
const updatedEntity = await this.updateEntity(this.baseType, entity, diffs);
|
|
113
|
+
const statusMsg = this.getInboundStatusMessage({
|
|
114
|
+
status: EventShortMessageStatus.SUCCESS,
|
|
115
|
+
statusMessage: EventShortMessageStatus.UPDATED,
|
|
116
|
+
objectClass: event.objectClass,
|
|
117
|
+
entityId: entity.id,
|
|
118
|
+
federatedId: event.federatedId
|
|
119
|
+
});
|
|
120
|
+
console.log(statusMsg);
|
|
121
|
+
return updatedEntity;
|
|
79
122
|
}
|
|
80
123
|
|
|
124
|
+
getInboundStatusMessage(statusObject){
|
|
125
|
+
return 'BaseEntityProcessor: inbound: status: ' + statusObject.status
|
|
126
|
+
+ ', statusMessage: ' + statusObject.statusMessage
|
|
127
|
+
+ ', entityType: ' + this.baseType
|
|
128
|
+
+ ', entityId: ' + statusObject.entityId
|
|
129
|
+
+ ', objectClass: ' + statusObject.objectClass
|
|
130
|
+
+ ', federatedId: ' + statusObject.federatedId;
|
|
131
|
+
}
|
|
132
|
+
|
|
81
133
|
async handleIncomingDelete(event) {
|
|
82
134
|
console.warn('delete is not configured', event);
|
|
83
135
|
}
|
|
@@ -90,7 +142,7 @@ export abstract class BaseEntityProcessor {
|
|
|
90
142
|
inboundData = await MapUtil.applyTransformMap(this.transformMapFile, this.mapFileUtil, inboundData, mapKey, TypeConversionUtils.FLEX2VIBE_DIRECTION);
|
|
91
143
|
console.debug('Transformed-inboundData: ' + JSON.stringify(inboundData));
|
|
92
144
|
|
|
93
|
-
|
|
145
|
+
|
|
94
146
|
|
|
95
147
|
return inboundData;
|
|
96
148
|
}
|
|
@@ -198,15 +250,33 @@ export abstract class BaseEntityProcessor {
|
|
|
198
250
|
};
|
|
199
251
|
}
|
|
200
252
|
|
|
201
|
-
|
|
202
|
-
|
|
253
|
+
try {
|
|
254
|
+
const payload = await this.getOutgoingUpsertPayload(entityType, event);
|
|
255
|
+
const flexResponse: any = await new FlexPLMConnect(this.config).sendToFlexPLM(payload);
|
|
203
256
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
257
|
+
const outboundEntityUpdates = await this.getOutboundEntityUpdates(event, flexResponse);
|
|
258
|
+
if(outboundEntityUpdates){
|
|
259
|
+
flexResponse['outboundEntityUpdates'] = outboundEntityUpdates;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const statusMsg = 'BaseEntityProcessor: outbound: ' + flexResponse.status
|
|
263
|
+
+ ', entityType: ' + this.baseType
|
|
264
|
+
+ ', entityId: ' + event.id
|
|
265
|
+
+ ', objectClass: ' + payload.objectClass
|
|
266
|
+
+ ', updateFromResponse: ' + (( outboundEntityUpdates &&Object.keys(outboundEntityUpdates).length > 0)? 'true' : 'false');
|
|
267
|
+
console.log(statusMsg);
|
|
268
|
+
|
|
269
|
+
return flexResponse;
|
|
270
|
+
|
|
271
|
+
} catch(e){
|
|
272
|
+
const statusMsg = 'BaseEntityProcessor: outbound: ' + e.httpResponseStatus
|
|
273
|
+
+ ', entityType: ' + this.baseType
|
|
274
|
+
+ ', entityId: ' + event.id
|
|
275
|
+
+ ', objectClass: ' + objectClass
|
|
276
|
+
+ ', updateFromResponse: ' + 'false';
|
|
277
|
+
console.log(statusMsg);
|
|
278
|
+
throw e;
|
|
207
279
|
}
|
|
208
|
-
|
|
209
|
-
return flexResponse;
|
|
210
280
|
}
|
|
211
281
|
|
|
212
282
|
async getOutboundEntityUpdates(event, flexResponse): Promise<any> {
|
|
@@ -264,15 +334,31 @@ export abstract class BaseEntityProcessor {
|
|
|
264
334
|
data: {message}
|
|
265
335
|
};
|
|
266
336
|
};
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
if(outboundEntityUpdates){
|
|
271
|
-
flexResponse['outboundEntityUpdates'] = outboundEntityUpdates;
|
|
272
|
-
}
|
|
337
|
+
let objectClass = payload.objectClass;
|
|
338
|
+
try {
|
|
339
|
+
const flexResponse: any = await new FlexPLMConnect(this.config).sendToFlexPLM(payload);
|
|
273
340
|
|
|
274
|
-
|
|
341
|
+
const outboundEntityUpdates = await this.getOutboundEntityUpdates(event, flexResponse);
|
|
342
|
+
if(outboundEntityUpdates){
|
|
343
|
+
flexResponse['outboundEntityUpdates'] = outboundEntityUpdates;
|
|
344
|
+
}
|
|
275
345
|
|
|
346
|
+
const statusMsg = 'BaseEntityProcessor: outbound: ' + flexResponse.status
|
|
347
|
+
+ ', entityType: ' + this.baseType
|
|
348
|
+
+ ', entityId: ' + event.id
|
|
349
|
+
+ ', objectClass: ' + objectClass
|
|
350
|
+
+ ', updateFromResponse: ' + ((outboundEntityUpdates &&Object.keys(outboundEntityUpdates).length > 0)? 'true' : 'false');
|
|
351
|
+
console.log(statusMsg);
|
|
352
|
+
return flexResponse;
|
|
353
|
+
}catch(e){
|
|
354
|
+
const statusMsg = 'BaseEntityProcessor: outbound: ' + e.httpResponseStatus
|
|
355
|
+
+ ', entityType: ' + this.baseType
|
|
356
|
+
+ ', entityId: ' + event.id
|
|
357
|
+
+ ', objectClass: ' + objectClass
|
|
358
|
+
+ ', updateFromResponse: ' + 'false';
|
|
359
|
+
console.log(statusMsg);
|
|
360
|
+
throw e;
|
|
361
|
+
}
|
|
276
362
|
}
|
|
277
363
|
|
|
278
364
|
/** Generates the payload to send to FlexPLM, based on the current state of the entity.
|
package/src/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from './flexplm-utils';
|
|
|
3
3
|
export * from './util/config-defaults';
|
|
4
4
|
export * from './util/data-converter';
|
|
5
5
|
export * from './util/error-response-object';
|
|
6
|
+
export * from './util/event-short-message-status';
|
|
6
7
|
export * from './util/federation';
|
|
7
8
|
export * from './util/flexplm-connect';
|
|
8
9
|
export * from './interfaces/interfaces';
|