fix: address review comments

Signed-off-by: Isaiah Thiessen <isaiah.thiessen@telus.com>
This commit is contained in:
Isaiah Thiessen
2022-06-02 13:01:35 -07:00
parent 4dcf3d05a5
commit 8bf26df9ad
10 changed files with 50 additions and 28 deletions
+1 -1
View File
@@ -29,7 +29,7 @@
"@backstage/plugin-cloudbuild": "^0.3.6-next.1",
"@backstage/plugin-code-coverage": "^0.1.33-next.1",
"@backstage/plugin-cost-insights": "^0.11.28-next.1",
"@backstage/plugin-dynatrace": "^0.1.0",
"@backstage/plugin-dynatrace": "^0.0.0",
"@backstage/plugin-explore": "^0.3.37-next.1",
"@backstage/plugin-gcalendar": "^0.3.2-next.1",
"@backstage/plugin-gcp-projects": "^0.3.25-next.1",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@backstage/plugin-dynatrace",
"version": "0.1.0",
"version": "0.0.0",
"main": "src/index.ts",
"types": "src/index.ts",
"license": "Apache-2.0",
+6 -4
View File
@@ -23,7 +23,7 @@ export type DynatraceEntity = {
name: string;
};
export type Problem = {
export type DynatraceProblem = {
problemId: string;
impactLevel: string;
status: string;
@@ -35,8 +35,8 @@ export type Problem = {
affectedEntities: Array<DynatraceEntity>;
};
export interface Problems {
problems: Array<Problem>;
export interface DynatraceProblems {
problems: Array<DynatraceProblem>;
}
export const dynatraceApiRef = createApiRef<DynatraceApi>({
@@ -44,5 +44,7 @@ export const dynatraceApiRef = createApiRef<DynatraceApi>({
});
export type DynatraceApi = {
getProblems(dynatraceEntityId: string): Promise<Problems | undefined>;
getDynatraceProblems(
dynatraceEntityId: string,
): Promise<DynatraceProblems | undefined>;
};
+14 -5
View File
@@ -13,23 +13,30 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import fetch from 'cross-fetch';
import { Problems, DynatraceApi } from './DynatraceApi';
import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api';
import { DynatraceProblems, DynatraceApi } from './DynatraceApi';
import {
DiscoveryApi,
IdentityApi,
FetchApi,
} from '@backstage/core-plugin-api';
export class DynatraceClient implements DynatraceApi {
discoveryApi: DiscoveryApi;
identityApi: IdentityApi;
fetchApi: FetchApi;
constructor({
discoveryApi,
identityApi,
fetchApi,
}: {
discoveryApi: DiscoveryApi;
identityApi: IdentityApi;
fetchApi: FetchApi;
}) {
this.discoveryApi = discoveryApi;
this.identityApi = identityApi;
this.fetchApi = fetchApi;
}
private async callApi<T>(
@@ -39,7 +46,7 @@ export class DynatraceClient implements DynatraceApi {
const { token: idToken } = await this.identityApi.getCredentials();
const apiUrl = `${await this.discoveryApi.getBaseUrl('proxy')}/dynatrace`;
const response = await fetch(
const response = await this.fetchApi.fetch(
`${apiUrl}/${path}?${new URLSearchParams(query).toString()}`,
{
headers: {
@@ -54,7 +61,9 @@ export class DynatraceClient implements DynatraceApi {
return undefined;
}
async getProblems(dynatraceEntityId: string): Promise<Problems | undefined> {
async getDynatraceProblems(
dynatraceEntityId: string,
): Promise<DynatraceProblems | undefined> {
if (!dynatraceEntityId) {
return undefined;
}
+5 -1
View File
@@ -13,6 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export type { Problems, Problem, DynatraceEntity } from './DynatraceApi';
export type {
DynatraceProblems,
DynatraceProblem,
DynatraceEntity,
} from './DynatraceApi';
export { dynatraceApiRef } from './DynatraceApi';
export { DynatraceClient } from './DynatraceClient';
@@ -14,10 +14,10 @@
* limitations under the License.
*/
import React from 'react';
import { Problem } from '../../../api/DynatraceApi';
import { DynatraceProblem } from '../../../api/DynatraceApi';
import { StatusError, StatusOK } from '@backstage/core-components';
export const ProblemStatus = ({ status }: Partial<Problem>) => {
export const ProblemStatus = ({ status }: Partial<DynatraceProblem>) => {
switch (status?.toLocaleLowerCase()) {
case 'open':
return (
@@ -22,7 +22,7 @@ import { ApiProvider, ConfigReader } from '@backstage/core-app-api';
import { configApiRef } from '@backstage/core-plugin-api';
const mockDynatraceApi = {
getProblems: jest.fn(),
getDynatraceProblems: jest.fn(),
};
const apis = TestApiRegistry.from(
[dynatraceApiRef, mockDynatraceApi],
@@ -31,7 +31,9 @@ const apis = TestApiRegistry.from(
describe('ProblemStatus', () => {
it('renders a table with problem data', async () => {
mockDynatraceApi.getProblems = jest.fn().mockResolvedValue({ problems });
mockDynatraceApi.getDynatraceProblems = jest
.fn()
.mockResolvedValue({ problems });
const rendered = await renderInTestApp(
<ApiProvider apis={apis}>
<ProblemsList dynatraceEntityId="example-service-3" />
@@ -40,7 +42,7 @@ describe('ProblemStatus', () => {
expect(await rendered.findByText('example-service')).toBeInTheDocument();
});
it('renders "nothing to report :)" if no problems are found', async () => {
mockDynatraceApi.getProblems = jest.fn().mockResolvedValue({});
mockDynatraceApi.getDynatraceProblems = jest.fn().mockResolvedValue({});
const rendered = await renderInTestApp(
<ApiProvider apis={apis}>
<ProblemsList dynatraceEntityId="example-service-3" />
@@ -29,8 +29,7 @@ export const ProblemsList = (props: ProblemsListProps) => {
const { dynatraceEntityId } = props;
const dynatraceApi = useApi(dynatraceApiRef);
const { value, loading, error } = useAsync(async () => {
const r = await dynatraceApi.getProblems(dynatraceEntityId);
return r;
return dynatraceApi.getDynatraceProblems(dynatraceEntityId);
}, [dynatraceApi, dynatraceEntityId]);
const problems = value?.problems;
@@ -15,14 +15,14 @@
*/
import React from 'react';
import { Table, TableColumn } from '@backstage/core-components';
import { Problem } from '../../../api/DynatraceApi';
import { DynatraceProblem } from '../../../api/DynatraceApi';
import { ProblemStatus } from '../ProblemStatus';
import { configApiRef } from '@backstage/core-plugin-api';
import { useApi } from '@backstage/core-plugin-api';
import { Link } from '@material-ui/core';
type ProblemsTableProps = {
problems: Problem[];
problems: DynatraceProblem[];
};
export const ProblemsTable = ({ problems }: ProblemsTableProps) => {
@@ -32,7 +32,7 @@ export const ProblemsTable = ({ problems }: ProblemsTableProps) => {
{
title: 'Title',
field: 'title',
render: (row: Partial<Problem>) => (
render: (row: Partial<DynatraceProblem>) => (
<Link
href={`${dynatraceBaseUrl}/#problems/problemdetails;pid=${row.problemId}`}
>
@@ -43,29 +43,32 @@ export const ProblemsTable = ({ problems }: ProblemsTableProps) => {
{
title: 'Status',
field: 'status',
render: (row: Partial<Problem>) => <ProblemStatus status={row.status} />,
render: (row: Partial<DynatraceProblem>) => (
<ProblemStatus status={row.status} />
),
},
{ title: 'Severity', field: 'severityLevel' },
{
title: 'Root Cause',
field: 'rootCauseEntity',
render: (row: Partial<Problem>) => row.rootCauseEntity?.name,
render: (row: Partial<DynatraceProblem>) => row.rootCauseEntity?.name,
},
{
title: 'Affected',
field: 'affectedEntities',
render: (row: Partial<Problem>) => row.affectedEntities?.map(e => e.name),
render: (row: Partial<DynatraceProblem>) =>
row.affectedEntities?.map(e => e.name),
},
{
title: 'Start Time',
field: 'startTime',
render: (row: Partial<Problem>) =>
render: (row: Partial<DynatraceProblem>) =>
new Date(row.startTime || 0).toString(),
},
{
title: 'End Time',
field: 'endTime',
render: (row: Partial<Problem>) =>
render: (row: Partial<DynatraceProblem>) =>
row.endTime === -1 ? 'ongoing' : new Date(row.endTime || 0).toString(),
},
];
+4 -1
View File
@@ -19,6 +19,7 @@ import {
createPlugin,
discoveryApiRef,
identityApiRef,
fetchApiRef,
createRoutableExtension,
} from '@backstage/core-plugin-api';
@@ -38,11 +39,13 @@ export const dynatracePlugin = createPlugin({
deps: {
discoveryApi: discoveryApiRef,
identityApi: identityApiRef,
fetchApi: fetchApiRef,
},
factory: ({ discoveryApi, identityApi }) =>
factory: ({ discoveryApi, identityApi, fetchApi }) =>
new DynatraceClient({
discoveryApi,
identityApi,
fetchApi,
}),
}),
],