Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(mirage): implement additional mock route handlers #1092

Merged
merged 6 commits into from
Aug 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/mirage/factories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const targetFactory: FactoryDefinition<any> = Factory.extend({
jvmId: '1234',
annotations: {
platform: { 'io.cryostat.demo': 'this-is-not-real' },
cryostat: { hello: 'world' },
cryostat: { hello: 'world', REALM: 'Some Realm' },
},
});

Expand Down
153 changes: 118 additions & 35 deletions src/mirage/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,16 @@ export const startMirage = ({ environment = 'development' } = {}) => {
() => new Response(400, {}, 'Resource downloads are not supported in this demo')
);
this.post('api/v2/targets', (schema, request) => {
const attrs = JSON.parse(request.requestBody);
const attrs = request.requestBody as any;
const target = schema.create(Resource.TARGET, {
jvmId: `${Math.floor(1000 * Math.random())}`,
jvmId: `${Date.now().toString(16)}`,
alias: attrs.get('alias'),
connectUrl: attrs.get('connectUrl'),
annotations: {
platform: {},
cryostat: {},
cryostat: {
REALM: 'Custom Targets',
},
},
});
websocket.send(
Expand All @@ -126,31 +128,37 @@ export const startMirage = ({ environment = 'development' } = {}) => {
};
});
this.get('api/v1/targets', (schema) => schema.all(Resource.TARGET).models);
this.get('api/v2.1/discovery', (schema) => ({
meta: {
status: 'OK',
type: 'application/json',
},
data: {
result: {
name: 'Universe',
nodeType: 'Universe',
labels: {},
children: [
{
name: 'KubernetesApi',
this.get('api/v2.1/discovery', (schema) => {
const models = schema.all(Resource.TARGET).models;
const realmTypes = models.map((t) => t.annotations.cryostat['REALM']);
return {
meta: {
status: 'OK',
type: 'application/json',
},
data: {
result: {
name: 'Universe',
nodeType: 'Universe',
labels: {},
children: realmTypes.map((r: string) => ({
name: r,
nodeType: 'Realm',
labels: {},
children: schema.all(Resource.TARGET).models.map((t) => ({
name: t.alias,
nodeType: 'JVM',
target: t,
})),
},
],
id: r,
children: models
.filter((t) => t.annotations.cryostat['REALM'] === r)
.map((t) => ({
id: t.alias,
name: t.alias,
nodeType: r === 'Custom Targets' ? 'CustomTarget' : 'JVM',
target: t,
})),
})),
},
},
},
}));
};
});
this.get('api/v1/recordings', (schema) => schema.all(Resource.ARCHIVE).models);
this.get('api/beta/fs/recordings', (schema) => {
const target = schema.first(Resource.TARGET);
Expand All @@ -167,8 +175,13 @@ export const startMirage = ({ environment = 'development' } = {}) => {
});
this.delete('api/beta/recordings/:targetId/:recordingName', (schema, request) => {
const recordingName = request.params.recordingName;
const recording = schema.where(Resource.ARCHIVE, { name: recordingName });
schema.findBy(Resource.ARCHIVE, { name: recordingName })?.destroy();
const recording = schema.findBy(Resource.ARCHIVE, { name: recordingName });

if (!recording) {
return new Response(404);
}
recording.destroy();

const msg = {
meta: {
category: 'ArchivedRecordingDeleted',
Expand All @@ -177,7 +190,7 @@ export const startMirage = ({ environment = 'development' } = {}) => {
},
message: {
recording: {
...recording.models[0].attrs,
...recording.attrs,
},
target: request.params['targetId'],
},
Expand All @@ -186,7 +199,9 @@ export const startMirage = ({ environment = 'development' } = {}) => {
return new Response(200);
});
this.post('api/v1/targets/:targetId/recordings', (schema, request) => {
const attrs = JSON.parse(request.requestBody);
// Note: MirageJS will fake serialize FormData (i.e. FormData object is returned when accessing request.requestBody)
const attrs = request.requestBody as any;

const recording = schema.create(Resource.RECORDING, {
// id will generated by Mirage (i.e. increment intergers)
downloadUrl: '',
Expand All @@ -205,7 +220,7 @@ export const startMirage = ({ environment = 'development' } = {}) => {
labels: {
...(attrs.labels || {}),
'template.type': 'TARGET',
'template.name': 'Demo Template',
'template.name': 'Demo_Template',
},
},
});
Expand All @@ -227,8 +242,13 @@ export const startMirage = ({ environment = 'development' } = {}) => {
this.get('api/v1/targets/:targetId/recordings', (schema) => schema.all(Resource.RECORDING).models);
this.delete('api/v1/targets/:targetId/recordings/:recordingName', (schema, request) => {
const recordingName = request.params.recordingName;
const recording = schema.where(Resource.RECORDING, { name: recordingName });
schema.findBy(Resource.RECORDING, { name: recordingName })?.destroy();
const recording = schema.findBy(Resource.RECORDING, { name: recordingName });

if (!recording) {
return new Response(404);
}
recording.destroy();

const msg = {
meta: {
category: 'ActiveRecordingDeleted',
Expand All @@ -237,7 +257,7 @@ export const startMirage = ({ environment = 'development' } = {}) => {
},
message: {
recording: {
...recording.models[0].attrs,
...recording.attrs,
},
target: request.params.targetId,
},
Expand All @@ -246,7 +266,7 @@ export const startMirage = ({ environment = 'development' } = {}) => {
return new Response(200);
});
this.patch('api/v1/targets/:targetId/recordings/:recordingName', (schema, request) => {
const body = JSON.parse(request.requestBody);
const body = request.requestBody;
const recordingName = request.params.recordingName;
const target = schema.findBy(Resource.TARGET, { connectUrl: request.params.targetId });
const recording = schema.findBy(Resource.RECORDING, { name: recordingName });
Expand Down Expand Up @@ -386,17 +406,80 @@ export const startMirage = ({ environment = 'development' } = {}) => {
},
]);
this.get('api/v2/probes', () => []);
this.post('/api/beta/matchExpressions', (_, request) => {
const attr = JSON.parse(request.requestBody);
if (!attr.matchExpression || !attr.targets) {
return new Response(400);
}
return {
data: {
result: {
targets: attr.targets,
},
},
};
});
this.post('api/v2/rules', (schema, request) => {
const attrs = JSON.parse(request.requestBody);
const rule = schema.create(Resource.RULE, attrs);
const msg = {
meta: {
category: 'RuleCreated',
type: { type: 'application', subType: 'json' },
serverTime: +Date.now(),
},
message: rule,
};
websocket.send(JSON.stringify(msg));
return {
data: {
result: schema.create(Resource.RULE, attrs),
result: rule,
},
};
});
this.get('api/v2/rules', (schema) => ({
data: { result: schema.all(Resource.RULE).models },
}));
this.patch('api/v2/rules/:ruleName', (schema, request) => {
const ruleName = request.params.ruleName;
const patch = JSON.parse(request.requestBody);
const rule = schema.findBy(Resource.RULE, { name: ruleName });

if (!rule) {
return new Response(404);
}
rule.update(patch);
const msg = {
meta: {
category: 'RuleUpdated',
type: { type: 'application', subType: 'json' },
serverTime: +Date.now(),
},
message: rule,
};
websocket.send(JSON.stringify(msg));
return new Response(200);
});
this.delete('api/v2/rules/:ruleName', (schema, request) => {
const ruleName = request.params.ruleName;
const rule = schema.findBy(Resource.RULE, { name: ruleName });

if (!rule) {
return new Response(404);
}
rule.destroy();

const msg = {
meta: {
category: 'RuleDeleted',
type: { type: 'application', subType: 'json' },
serverTime: +Date.now(),
},
message: rule,
};
websocket.send(JSON.stringify(msg));
return new Response(200);
});
this.get('api/v2.2/credentials', () => ({ data: { result: [] } }));
this.post('api/v2.2/graphql', (schema, request) => {
const body = JSON.parse(request.requestBody);
Expand Down