Skip to content

Commit

Permalink
feat(mirage): implement additional mock route handlers (backport #1092)…
Browse files Browse the repository at this point in the history
… (#1100)

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

(cherry picked from commit c185969)

* fixup

---------

Co-authored-by: Thuan Vo <thvo@redhat.com>
Co-authored-by: Andrew Azores <aazores@redhat.com>
  • Loading branch information
3 people authored Aug 31, 2023
1 parent b7df7ce commit e6c4aaa
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 37 deletions.
1 change: 1 addition & 0 deletions license-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
},
"ignore": [
".git",
".build_cache",
"tags",
"coverage",
"stories",
Expand Down
2 changes: 1 addition & 1 deletion src/mirage/factories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,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
154 changes: 118 additions & 36 deletions src/mirage/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

import build from '@app/build.json';
import { createServer, Response } from 'miragejs';
import { Server as WSServer, Client } from 'mock-socket';
Expand Down Expand Up @@ -121,14 +120,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 @@ -148,31 +149,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 @@ -189,8 +196,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 @@ -199,7 +211,7 @@ export const startMirage = ({ environment = 'development' } = {}) => {
},
message: {
recording: {
...recording.models[0].attrs,
...recording.attrs,
},
target: request.params['targetId'],
},
Expand All @@ -208,7 +220,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 @@ -227,7 +241,7 @@ export const startMirage = ({ environment = 'development' } = {}) => {
labels: {
...(attrs.labels || {}),
'template.type': 'TARGET',
'template.name': 'Demo Template',
'template.name': 'Demo_Template',
},
},
});
Expand All @@ -249,8 +263,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 @@ -259,7 +278,7 @@ export const startMirage = ({ environment = 'development' } = {}) => {
},
message: {
recording: {
...recording.models[0].attrs,
...recording.attrs,
},
target: request.params.targetId,
},
Expand All @@ -268,7 +287,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 as any;
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 @@ -408,17 +427,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

0 comments on commit e6c4aaa

Please sign in to comment.