Skip to content

Commit 7768efd

Browse files
authored
Support for locally created files resulting in new Entry creation
* Support create entry in kcmd push command
1 parent 18b97eb commit 7768efd

6 files changed

Lines changed: 114 additions & 2 deletions

File tree

toolbox/mdcode/package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

toolbox/mdcode/src/libts/gcp/dataplex.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,34 @@ export class CatalogClient extends api.ApiClient {
177177
} while (pageToken);
178178
}
179179

180+
async createEntry(project: string, location: string, entryGroup: string,
181+
entryId: string, entry?: Entry): Promise<api.ApiResult<Entry>> {
182+
const parent = catalogContainer(project, location, entryGroup);
183+
const resourceName = `${parent}/entries`;
184+
185+
const params: Record<string, any> = { entryId };
186+
187+
const res = await this._post<Entry>(resourceName, entry, params);
188+
189+
if (res.status == 200 && res.result) {
190+
await _fixEntry(res.result, this.context);
191+
}
192+
193+
return res;
194+
}
195+
196+
async createEntryGroup(project: string, location: string,
197+
entryGroupId: string, entryGroup?: EntryGroup): Promise<api.ApiResult<EntryGroup>> {
198+
const parent = catalogContainer(project, location);
199+
const resourceName = `${parent}/entryGroups`;
200+
201+
const params: Record<string, any> = { entryGroupId };
202+
203+
const res = await this._post<EntryGroup>(resourceName, entryGroup, params);
204+
205+
return res;
206+
}
207+
180208
}
181209

182210

toolbox/mdcode/src/libts/sync.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ export class CatalogSync {
4444
const nameParts = entry.name.split('/');
4545
const res = await this._catalog.lookupEntry(nameParts[1], nameParts[3], entry.name,
4646
[...this._snapshot.aspectTypes.keys()]);
47+
// The server will respond with 403 permission denied for both resource not exist or
48+
// insufficient permission. We cannot tell if a resource not exist or user does not
49+
// have the access. Thus using 200 for an ensured result.
4750
if (res.status != 200 || !res.result) {
4851
continue;
4952
}
@@ -76,6 +79,20 @@ export class CatalogSync {
7679
const project = nameParts[1];
7780
const location = nameParts[3];
7881

82+
const exist = await this._catalog.lookupEntry(project, location, entry.name);
83+
if (exist.status != 200 || !exist.result) {
84+
console.log(`entry ${name} does not exist, will try to create the entry.`);
85+
86+
const entryGroup = nameParts[5];
87+
const entryId = nameParts[7];
88+
const createEntryRes = await this._catalog.createEntry(project, location, entryGroup, entryId, entry);
89+
if (createEntryRes.status != 200 || !createEntryRes.result) {
90+
console.log(`Failed to push entry ${entry.name}: Failed to create new entry.`);
91+
}
92+
console.log(`Successfully created and pushed entry ${entry.name}`);
93+
continue;
94+
}
95+
7996
const updateMask = [];
8097
const aspectKeys = Object.keys(entry.aspects || {});
8198
if (aspectKeys.length) {

toolbox/mdcode/tests/libts/mocks.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,15 @@ export class CatalogClientMock extends gcp.CatalogClient {
130130
}
131131
return { status: 404, message: 'Not found' };
132132
}
133+
134+
async createEntry(project: string, location: string, entryGroup: string, entryId: string, entry?: gcp.Entry): Promise<gcp.ApiResult<gcp.Entry>> {
135+
const fakeEntry = entry;
136+
if (fakeEntry) {
137+
this.mockEntries.push(fakeEntry);
138+
return { status: 200, result: entry };
139+
}
140+
return {status: 404, message: 'Not found' };
141+
}
133142
}
134143

135144

toolbox/mdcode/tests/libts/scenarios.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ function runScenario(scenario: any) {
145145

146146
// Assert expectations - Catalog Service
147147
if (scenario.assert?.catalog?.entries) {
148-
expect(catalog.mockEntries).toEqual(scenario.assert.catalog.entries);
148+
expect(JSON.parse(JSON.stringify(catalog.mockEntries))).toEqual(JSON.parse(JSON.stringify(scenario.assert.catalog.entries)));
149149
}
150150
});
151151
});
@@ -236,6 +236,15 @@ function main() {
236236
}
237237
);
238238

239+
spyOn(gcp.CatalogClient.prototype, 'createEntry').mockImplementation(
240+
async function(project: string, location: string, entryGroup: string, entryId: string, entry?: gcp.Entry) {
241+
if (currentCatalogMock) {
242+
return await currentCatalogMock.createEntry(project, location, entryGroup, entryId, entry);
243+
}
244+
return { status: 404, message: 'Not found' };
245+
}
246+
);
247+
239248
spyOn(bq.BigQueryClient.prototype, 'getDataset').mockImplementation(
240249
async function(project: string, dataset: string) {
241250
if (currentBigQueryMock) {
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: push_new_entry
2+
description: Push Custom entry modifications
3+
setup:
4+
catalog:
5+
entryGroups:
6+
- name: projects/p/locations/us/entryGroups/custom-group
7+
entryTypes:
8+
- name: projects/p/locations/global/entryTypes/custom-type
9+
entries:
10+
- name: projects/p/locations/us/entryGroups/custom-group/entries/existing-entry
11+
entryType: projects/p/locations/global/entryTypes/custom-type
12+
entrySource:
13+
description: Old custom description
14+
15+
fileSystem:
16+
catalog.yaml: |
17+
scope: entryGroup.p.us.custom-group
18+
snapshot:
19+
entries:
20+
- p.global.custom-type
21+
22+
23+
actions:
24+
- action: pull
25+
- action: createEntry
26+
name: custom-entry
27+
entry:
28+
name: custom-entry
29+
type: p.global.custom-type
30+
resource:
31+
description: Hello world
32+
- action: push
33+
34+
assert:
35+
fileSystem:
36+
catalog/custom-entry.yaml:
37+
- contains: "name: custom-entry"
38+
- contains: "description: Hello world"
39+
catalog:
40+
entries:
41+
- name: projects/p/locations/us/entryGroups/custom-group/entries/existing-entry
42+
entryType: projects/p/locations/global/entryTypes/custom-type
43+
entrySource:
44+
description: Old custom description
45+
- name: projects/p/locations/us/entryGroups/custom-group/entries/custom-entry
46+
entryType: projects/p/locations/global/entryTypes/custom-type
47+
entrySource:
48+
description: "Hello world"
49+
aspects: {}

0 commit comments

Comments
 (0)