@adobe/acc-js-sdk 1.1.40 → 1.1.42
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/docs/Gemfile.lock +2 -1
- package/docs/_config.yml +5 -0
- package/docs/_posts/2022-10-14-welcome.html +0 -1
- package/docs/_posts/2023-12-08-manipulateSchemas.html +364 -0
- package/docs/_posts/2023-12-09-createFDASchema.html +429 -0
- package/docs/blog.html +1 -1
- package/docs/changeLog.html +25 -0
- package/docs/connecting.html +1 -1
- package/docs/xtkJob.html +25 -0
- package/package-lock.json +299 -130
- package/package.json +1 -1
- package/src/client.js +4 -1
- package/src/xtkJob.js +33 -14
- package/test/client.test.js +49 -0
- package/test/xtkJob.test.js +42 -17
package/docs/Gemfile.lock
CHANGED
package/docs/_config.yml
CHANGED
|
@@ -34,6 +34,11 @@ github_username: mkiki
|
|
|
34
34
|
plugins:
|
|
35
35
|
- jekyll-feed
|
|
36
36
|
|
|
37
|
+
collections:
|
|
38
|
+
posts:
|
|
39
|
+
output: true
|
|
40
|
+
|
|
41
|
+
|
|
37
42
|
# Exclude from processing.
|
|
38
43
|
# The following items will not be processed, by default.
|
|
39
44
|
# Any item listed under the `exclude:` key here will be automatically added to
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: post
|
|
3
|
+
title: "Manipulating schemas"
|
|
4
|
+
author: Alexandre Morin
|
|
5
|
+
tags: schemas soap
|
|
6
|
+
excerpt: Sequence of APIs to discover and create a FDA schema
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
<p>
|
|
11
|
+
This article will illustrate how to use APIs to create and manipulate schemas
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<h1>Schemas</h1>
|
|
15
|
+
|
|
16
|
+
<p>
|
|
17
|
+
There are 3 types of schemas in Campaign
|
|
18
|
+
<ul>
|
|
19
|
+
<li>Source schemas (xtk:srcSchema)</li>
|
|
20
|
+
<li>Schemas (xtk:schema)</li>
|
|
21
|
+
<li>SQL schemas (xtk:sqlSchema)</li>
|
|
22
|
+
</ul>
|
|
23
|
+
</p>
|
|
24
|
+
|
|
25
|
+
<p>
|
|
26
|
+
Users normally only create source schemas. Those are then "compiled" into schemas and SQL schemas.
|
|
27
|
+
The compilation process (called "build schemas") can take several seconds and is performed via an API call.
|
|
28
|
+
This means that the <b>xtk:builder#BuildSchema</b> (or similar API) must be called after schemas are
|
|
29
|
+
modified or created, to ensure overall consistency.
|
|
30
|
+
</p>
|
|
31
|
+
|
|
32
|
+
<p>
|
|
33
|
+
Once source schemas are created and compiled, you will usually use schemas and not source schemas because
|
|
34
|
+
source schemas are just the various elements that build up the final schemas. You will probably never need
|
|
35
|
+
to use sql schemas directly. They are used internally to map schemas to SQL tables.
|
|
36
|
+
</p>
|
|
37
|
+
<p>
|
|
38
|
+
Of course you can read and use source schemas as well but this is usually limited to schema authoring
|
|
39
|
+
use cases.
|
|
40
|
+
</p>
|
|
41
|
+
|
|
42
|
+
<table>
|
|
43
|
+
<thead>
|
|
44
|
+
<tr><th>Attribute/Method</th><th>Description</th></tr>
|
|
45
|
+
</thead>
|
|
46
|
+
<tbody>
|
|
47
|
+
<tr><td>Create or modify</td><td>Use source schemas and BuildSchema API</td></tr>
|
|
48
|
+
<tr><td>Delete</td><td></td></tr>
|
|
49
|
+
<tr><td>Use</td><td>Use schemas</td></tr>
|
|
50
|
+
</tbody>
|
|
51
|
+
</table>
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
<h1>Reading schemas</h1>
|
|
55
|
+
|
|
56
|
+
<h2>Get a schema as a JSON object</h2>
|
|
57
|
+
<p>
|
|
58
|
+
The simplest way to read a schema is to use the <b>getSchema</b> SDK APIs which also provide client-side caching.
|
|
59
|
+
</p>
|
|
60
|
+
|
|
61
|
+
<p>
|
|
62
|
+
The <b>client.getSchema()</b> API returns a JSON or XML object representing the (compiled) schema requested.
|
|
63
|
+
See the <a href="{{ site.baseurl }}/xtkSchema.html">Schema API</a> page for more details.
|
|
64
|
+
</p>
|
|
65
|
+
|
|
66
|
+
<pre class="code">
|
|
67
|
+
const schema = await client.getSchema("nms:recipient");
|
|
68
|
+
console.log(JSON.stringify(schema));
|
|
69
|
+
</pre>
|
|
70
|
+
|
|
71
|
+
<h2>Get a schema as a convenient JavaScript object</h2>
|
|
72
|
+
<p>
|
|
73
|
+
The <b>application.getSchema()</b> API is built on top of the previous one and returns a schema object which
|
|
74
|
+
is more convenient to use that a raw JSON object. See the <a href="{{ site.baseurl }}/application.html">Application</a> object for more details.
|
|
75
|
+
</p>
|
|
76
|
+
|
|
77
|
+
<pre class="code">
|
|
78
|
+
const schema = await client.application.getSchema("nms:recipient");
|
|
79
|
+
</pre>
|
|
80
|
+
|
|
81
|
+
<h2>List schemas using a query</h2>
|
|
82
|
+
<p>
|
|
83
|
+
It is also possible to use the <a href="{{ site.baseurl }}/xtkQueryDef.html">QueryDef</a> API to read schemas and source schemas.
|
|
84
|
+
</p>
|
|
85
|
+
<p>
|
|
86
|
+
Let's first get the list of source schemas in the custom namespace "cus". The following will return then
|
|
87
|
+
names and labels of 10 source schemas in the cus namespace.
|
|
88
|
+
</p>
|
|
89
|
+
|
|
90
|
+
<pre class="code">
|
|
91
|
+
|
|
92
|
+
const queryDef = {
|
|
93
|
+
schema: "xtk:srcSchema",
|
|
94
|
+
operation: "select",
|
|
95
|
+
lineCount: 10,
|
|
96
|
+
select: {
|
|
97
|
+
node: [
|
|
98
|
+
{ expr: "@name" },
|
|
99
|
+
{ expr: "@namespace" },
|
|
100
|
+
{ expr: "@label" }
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
where: {
|
|
104
|
+
condition: [
|
|
105
|
+
{ expr:`@namespace = 'cus'` }
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
const query = client.NLWS.xtkQueryDef.create(queryDef);
|
|
110
|
+
const srcSchemas = await query.executeQuery();
|
|
111
|
+
</pre>
|
|
112
|
+
|
|
113
|
+
<p>
|
|
114
|
+
To return schemas instead of source schemas, use "xtk:schema" instead of "xtk:srcSchema" in the QueryDef.
|
|
115
|
+
</p>
|
|
116
|
+
|
|
117
|
+
<p>
|
|
118
|
+
If you want both schemas and source schemas, you can query the "xtk:entity" schema instead. But this requires an
|
|
119
|
+
additional condition en the "@entitySchema" attribute. If not, you will also get custom forms, javascript, etc.
|
|
120
|
+
</p>
|
|
121
|
+
|
|
122
|
+
<pre class="code">
|
|
123
|
+
|
|
124
|
+
const queryDef = {
|
|
125
|
+
schema: "xtk:entity",
|
|
126
|
+
operation: "select",
|
|
127
|
+
lineCount: 10,
|
|
128
|
+
select: {
|
|
129
|
+
node: [
|
|
130
|
+
{ expr: "@name" },
|
|
131
|
+
{ expr: "@namespace" },
|
|
132
|
+
{ expr: "@label" },
|
|
133
|
+
{ expr: "@entitySchema" },
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
where: {
|
|
137
|
+
condition: [
|
|
138
|
+
{ expr:`@namespace = 'cus'` },
|
|
139
|
+
{ expr:`@entitySchema IN ('xtk:schema', 'xtk:srcSchema')` }
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
const query = client.NLWS.xtkQueryDef.create(queryDef);
|
|
144
|
+
const entities = await query.executeQuery();
|
|
145
|
+
</pre>
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
<h2>Use a query to get schema details</h2>
|
|
149
|
+
|
|
150
|
+
<p>
|
|
151
|
+
Schemas are stored into the xtk:entity table. The main fields (@name, @label, @namespace) are stored directly
|
|
152
|
+
as SQL columns, but the schema definition is actually stored as XML.
|
|
153
|
+
Getting the XML requires to query at least one of attibutes which is stored in XML, for example
|
|
154
|
+
the @library attribute.
|
|
155
|
+
</p>
|
|
156
|
+
|
|
157
|
+
<pre class="code">
|
|
158
|
+
|
|
159
|
+
const queryDef = {
|
|
160
|
+
schema: "xtk:schema",
|
|
161
|
+
operation: "get",
|
|
162
|
+
select: {
|
|
163
|
+
node: [
|
|
164
|
+
{ expr: "@name" },
|
|
165
|
+
{ expr: "@namespace" },
|
|
166
|
+
{ expr: "@label" },
|
|
167
|
+
{ expr: "@library" },
|
|
168
|
+
]
|
|
169
|
+
},
|
|
170
|
+
where: {
|
|
171
|
+
condition: [
|
|
172
|
+
{ expr:`@namespace = 'nms' and @name='recipient'` },
|
|
173
|
+
]
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
const query = client.NLWS.xtkQueryDef.create(queryDef);
|
|
177
|
+
const schema = await query.executeQuery();
|
|
178
|
+
</pre>
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
<p>
|
|
182
|
+
Note that querying for schemas (as opposed to srcSchemas) the id is the id of the top most src schema (i.e. "nms:recipient" and not "cus:recipient").
|
|
183
|
+
The reason is that all source schemas (nms:recipient, cus:recipient, etc.) are merged into a single schema (nms:recipient) when compiled.
|
|
184
|
+
You can, however, query individual source schemas even if they are extension schemas
|
|
185
|
+
</p>
|
|
186
|
+
|
|
187
|
+
<pre class="code">
|
|
188
|
+
const queryDef = {
|
|
189
|
+
schema: "xtk:srcSchema",
|
|
190
|
+
operation: "get",
|
|
191
|
+
select: {
|
|
192
|
+
node: [
|
|
193
|
+
{ expr: "@name" },
|
|
194
|
+
{ expr: "@namespace" },
|
|
195
|
+
{ expr: "@label" },
|
|
196
|
+
{ expr: "@library" },
|
|
197
|
+
]
|
|
198
|
+
},
|
|
199
|
+
where: {
|
|
200
|
+
condition: [
|
|
201
|
+
{ expr:`@namespace = 'gov' and @name='recipient'` },
|
|
202
|
+
]
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
const query = client.NLWS.xtkQueryDef.create(queryDef);
|
|
206
|
+
const srcSchema = await query.executeQuery();
|
|
207
|
+
</pre>
|
|
208
|
+
|
|
209
|
+
<h2>Use GetEntityIfMoreRecent</h2>
|
|
210
|
+
<p>
|
|
211
|
+
Last, but not least, you can use the <b>xtk:persist#GetEntityIfMoreRecent</b> method to return a (compiled) schema. This is the method internally
|
|
212
|
+
used by the SDK. This method is useful if you already have the schema but you are not sure it's up to date. Calling this method is usefull to
|
|
213
|
+
save network bandwidth as it will only return the schema if it has changed.
|
|
214
|
+
</p>
|
|
215
|
+
<p>
|
|
216
|
+
For this, you need to keep both the schema and its md5 hash (@md5 attribute). Then you can call the method as follows:
|
|
217
|
+
<ul>
|
|
218
|
+
<li>Pass an identifier to the schema. As GetEntityIfMoreRecent works with any type of entities, the id is formatted as "xtk:srcSchema:{schemaId}" or "xtk:schema:{schemaId}" </li>
|
|
219
|
+
<li>Pass the MD5 of the schema if you have it. If you pass undefined, the API call will return the full schema. If you pass a md5, the API will only return a schema if it has changed</li>
|
|
220
|
+
<li>Pass a boolean indicating if you expect the requested entity to exist. If false, then the API will return null for non existent entities</li>
|
|
221
|
+
</ul>
|
|
222
|
+
</p>
|
|
223
|
+
|
|
224
|
+
<pre class="code">
|
|
225
|
+
const schema = await client.NLWS.xtkSession.getEntityIfMoreRecent("xtk:srcSchema|nms:notFound", md5, mustExist);
|
|
226
|
+
</pre>
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
<h1>Creating and updating schemas</h1>
|
|
231
|
+
|
|
232
|
+
<p>
|
|
233
|
+
The following API calls can be used to either create or update schemas. Note the builtin schemas cannot be updated.
|
|
234
|
+
The operation is always a two-step process:
|
|
235
|
+
<ui>
|
|
236
|
+
<li>Create or modify a source schema</li>
|
|
237
|
+
<li>Call one of the <b>BuildSchema</b> methods</li>
|
|
238
|
+
</ui>
|
|
239
|
+
</p>
|
|
240
|
+
|
|
241
|
+
<p class="warning">Always work with source schemas for creation and update. Tampering with (compiled) schemas can lead to inconsistencies and unpredictable results.</p>
|
|
242
|
+
|
|
243
|
+
<h2>Create (or modify) a custom schema</h2>
|
|
244
|
+
|
|
245
|
+
<p>
|
|
246
|
+
In this example we'll create or update a simple custom schema. This is the simplest scenario, there's no schema extension, etc.
|
|
247
|
+
</p>
|
|
248
|
+
|
|
249
|
+
<pre class="code">
|
|
250
|
+
await client.NLWS.xtkSession.write({
|
|
251
|
+
xtkschema: "xtk:srcSchema",
|
|
252
|
+
namespace: "cus",
|
|
253
|
+
name: "foo",
|
|
254
|
+
label: "Foos",
|
|
255
|
+
labelSingular: "Foo",
|
|
256
|
+
desc: "This is a fooooo",
|
|
257
|
+
mappingType: "sql",
|
|
258
|
+
element: [
|
|
259
|
+
{
|
|
260
|
+
name: "foo",
|
|
261
|
+
key: [
|
|
262
|
+
{
|
|
263
|
+
name: "id",
|
|
264
|
+
keyfield: [
|
|
265
|
+
{
|
|
266
|
+
xpath: "@id"
|
|
267
|
+
}
|
|
268
|
+
]
|
|
269
|
+
}
|
|
270
|
+
],
|
|
271
|
+
attribute: [
|
|
272
|
+
{
|
|
273
|
+
name: "id",
|
|
274
|
+
label: "Id",
|
|
275
|
+
type: "string",
|
|
276
|
+
length: 100
|
|
277
|
+
}
|
|
278
|
+
]
|
|
279
|
+
}
|
|
280
|
+
]
|
|
281
|
+
});
|
|
282
|
+
</pre>
|
|
283
|
+
|
|
284
|
+
<p>
|
|
285
|
+
<ul>
|
|
286
|
+
<li>Make sure to pass the attribute xtkschema: "xtk:srcSchema". This means that we are creating or updating a source schema</li>
|
|
287
|
+
<li>Do not modify (compiled) schemas directly</li>
|
|
288
|
+
<li>The function does not return anything. You can a queryDef to verify that the source schema was properly created</li>
|
|
289
|
+
<li>By convention, the schema name is <i>singular</i>, in camel case, starting with a lower case character</li>
|
|
290
|
+
<li>The label is the human friendly name and is plural, whereas labelSingular is for ... singular</li>
|
|
291
|
+
<li>It's important to set the mapping type to SQL, indicating that we want a SQL table created</li>
|
|
292
|
+
<li>Create a root element with the <i>same name</i> as the schema</li>
|
|
293
|
+
<li>Although it's not mandatory to have a primary key, it's a best practice. Create a <i>key</i> element</li>
|
|
294
|
+
</ul>
|
|
295
|
+
</p>
|
|
296
|
+
|
|
297
|
+
<p>
|
|
298
|
+
Now, build the schema. This operation may take a few seconds, adjust the timeout accordingly.
|
|
299
|
+
</p>
|
|
300
|
+
|
|
301
|
+
<pre class="code">
|
|
302
|
+
await client.NLWS.pushDown({ timeout: 60000 }).xtkBuilder.BuildSchemaFromId("cus:foo");
|
|
303
|
+
</pre>
|
|
304
|
+
<p class="warning">
|
|
305
|
+
Do not forget to call one of the <b>xtk:builder#BuildSchema</b>
|
|
306
|
+
</p>
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
<h1>Deleting a schema</h1>
|
|
311
|
+
|
|
312
|
+
<p>
|
|
313
|
+
Before you can delete a source schema you need to get it's <b>@extendedSchema</b> attribute. The following will
|
|
314
|
+
return the id of the parent schema if cus:foo is an extension schema, or undefined if cus:foo is not an extension schema.
|
|
315
|
+
</p>
|
|
316
|
+
|
|
317
|
+
<pre class="code">
|
|
318
|
+
const queryDef = {
|
|
319
|
+
schema: "xtk:srcSchema",
|
|
320
|
+
operation: "get",
|
|
321
|
+
select: {
|
|
322
|
+
node: [
|
|
323
|
+
{ expr: "@extendedSchema" },
|
|
324
|
+
]
|
|
325
|
+
},
|
|
326
|
+
where: {
|
|
327
|
+
condition: [
|
|
328
|
+
{ expr:`@namespace = 'cus' and @name='foo'` },
|
|
329
|
+
]
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
const query = client.NLWS.xtkQueryDef.create(queryDef);
|
|
333
|
+
const srcSchema = await query.executeQuery();
|
|
334
|
+
const extendedSchema = srcSchema.extendedSchema;
|
|
335
|
+
</pre>
|
|
336
|
+
|
|
337
|
+
<p>
|
|
338
|
+
To remove a schema, a writer to delete the source schema entities you want to delete. Make sure to pass the extendedSchema if there is one.
|
|
339
|
+
</p>
|
|
340
|
+
|
|
341
|
+
<pre class="code">
|
|
342
|
+
await client.NLWS.xtkSession.writeCollection({
|
|
343
|
+
xtkschema: "xtk:srcSchema",
|
|
344
|
+
srcSchema: [
|
|
345
|
+
{
|
|
346
|
+
_operation: "delete",
|
|
347
|
+
extendedSchema: extendedSchema,
|
|
348
|
+
namespace: "cus",
|
|
349
|
+
name: "foo"
|
|
350
|
+
}
|
|
351
|
+
]
|
|
352
|
+
});
|
|
353
|
+
</pre>
|
|
354
|
+
|
|
355
|
+
<p>
|
|
356
|
+
Now, call the <b>xtk:builder#RemoveSchemaLinkRef</b> method to remove the schema and reverse links. Make sure to pass the extendedSchema if there is one.
|
|
357
|
+
</p>
|
|
358
|
+
<pre class="code">
|
|
359
|
+
await client.NLWS.xtkBuilder.RemoveSchemaLinkRef("cus:foo", extendedSchema);
|
|
360
|
+
</pre>
|
|
361
|
+
|
|
362
|
+
<p>
|
|
363
|
+
If the schema you want to delete has extension schema
|
|
364
|
+
</p>
|