From 10b054065bca9f21b6320d8c7d46c8041cb60cd4 Mon Sep 17 00:00:00 2001
From: Hugo Guerrero <1001939+hguerrero@users.noreply.github.com>
Date: Sun, 19 Nov 2023 21:52:49 -0500
Subject: [PATCH 01/11] add import dialog
---
client/src/App.tsx | 25 ++++----
client/src/components/ImportDialog.tsx | 80 ++++++++++++++++++++++++++
client/src/components/Services.tsx | 18 ++++--
client/src/components/Settings.tsx | 6 +-
4 files changed, 108 insertions(+), 21 deletions(-)
create mode 100644 client/src/components/ImportDialog.tsx
diff --git a/client/src/App.tsx b/client/src/App.tsx
index 15acb88..e6b094c 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -16,7 +16,6 @@
* specific language governing permissions and limitations
* under the License.
*/
-import { createDockerDesktopClient } from '@docker/extension-api-client';
import React, { useEffect, useState } from 'react';
import DoneOutlinedIcon from '@mui/icons-material/DoneOutlined';
@@ -25,6 +24,7 @@ import SettingsIcon from '@mui/icons-material/Settings';
import Backdrop from '@mui/material/Backdrop';
import IconButton from '@mui/material/IconButton';
+import OpenInNewIcon from '@mui/icons-material/OpenInNew';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
import Chip from '@mui/material/Chip';
@@ -35,8 +35,9 @@ import Paper from '@mui/material/Paper';
import Stack from '@mui/material/Stack';
import Tooltip from '@mui/material/Tooltip';
import Typography from '@mui/material/Typography';
-import OpenInNewIcon from '@mui/icons-material/OpenInNew';
+import { ExecStreamOptions } from '@docker/extension-api-client-types/dist/v1';
+import './App.css';
import {
getExtensionConfig,
getHome,
@@ -48,25 +49,23 @@ import { getContainerInfo } from './api/containers';
import { sendMetric } from './api/metrics';
import { ensureNetworkExists } from './api/network';
import { ensureVolumeExists } from './api/volume';
-import './App.css';
+import AlertDialog from './components/AlertDialog';
+import ClipboardCopy from './components/ClipboardCopy';
import DeleteDialog from './components/DeleteDialog';
import Footer from './components/Footer';
-import Settings from './components/Settings';
+import ImportDialog from './components/ImportDialog';
+import Services from './components/Services';
+import SettingsDialog from './components/Settings';
import { ContainerStatus } from './types/ContainerStatus';
import { ExtensionConfig } from './types/ExtensionConfig';
import {
APP_CONTAINER,
ASYNC_MINION_CONTAINER,
EXTENSION_NETWORK,
- EXTENSION_VOLUME,
KAFKA_CONTAINER,
- POSTMAN_CONTAINER,
+ POSTMAN_CONTAINER
} from './utils/constants';
-import Services from './components/Services';
import { useDockerDesktopClient } from './utils/ddclient';
-import { ExecStreamOptions } from '@docker/extension-api-client-types/dist/v1';
-import AlertDialog from './components/AlertDialog';
-import ClipboardCopy from './components/ClipboardCopy';
const isWindows = () => {
const platform = useDockerDesktopClient().host.platform;
@@ -725,7 +724,7 @@ const App = () => {
setIsSettingsDialog(true);
};
- const handleCloseSettings = async (
+ const handleCloseSettingsDialog = async (
config: ExtensionConfig | undefined | null,
) => {
setIsSettingsDialog(!isSettingsDialog);
@@ -961,11 +960,11 @@ const App = () => {
)}
-
void;
+}> = ({ isDialogOpen, closeHandler }) => {
+ const [file, setFile] = useState();
+ const [isSecondary, setIsSecondary] = useState(false);
+
+ const handleClose = () => {
+ closeHandler();
+ };
+
+ const handleInputChange = (event: React.ChangeEvent) => {
+ setFile(event.target.files?.[0]);
+ };
+
+ const handleCheckboxChange = (event: React.ChangeEvent) => {
+ setIsSecondary(event.target.checked);
+ };
+
+ return (
+
+ );
+};
+
+export default ImportDialog;
diff --git a/client/src/components/Services.tsx b/client/src/components/Services.tsx
index 1d8c974..36e2f81 100644
--- a/client/src/components/Services.tsx
+++ b/client/src/components/Services.tsx
@@ -42,11 +42,12 @@ import MockURLRow from './MockURLRow';
import ServiceTypeLabel from './ServiceTypeLabel';
import { Operation, Service } from '../types/Service';
import ServiceRow from './ServiceRow';
+import UploadIcon from '@mui/icons-material/Upload';
+import ImportDialog from './ImportDialog';
-const Services = (props: { config: ExtensionConfig }) => {
+const Services = ({config}: { config: ExtensionConfig }) => {
const [services, setServices] = useState([]);
-
- const { config } = props;
+ const [isImportDialog, setIsImportDialog] = useState(false)
const ddClient = useDockerDesktopClient();
@@ -71,12 +72,17 @@ const Services = (props: { config: ExtensionConfig }) => {
retrieveServices();
}, []);
+ const handleOpenImport = () => {setIsImportDialog(true)};
+
+ const handleCloseImportDialog = () => {setIsImportDialog(false)};
+
return (
+ <>
Services
-
@@ -97,6 +103,8 @@ const Services = (props: { config: ExtensionConfig }) => {
+
+ >
);
};
diff --git a/client/src/components/Settings.tsx b/client/src/components/Settings.tsx
index 3d4a9b2..3588b0b 100644
--- a/client/src/components/Settings.tsx
+++ b/client/src/components/Settings.tsx
@@ -37,13 +37,13 @@ type Props = {
config: ExtensionConfig;
isRunning?: boolean;
isDialogOpen: boolean;
- handleCloseDialog: (newConfig: ExtensionConfig | undefined | null) => void;
+ closeHandler: (newConfig: ExtensionConfig | undefined | null) => void;
};
const Settings: React.FC = ({
isDialogOpen,
isRunning = true,
- handleCloseDialog,
+ closeHandler,
config,
}) => {
const [{ portOffset, asyncEnabled, postmanEnabled, aicopilotEnabled, openAiApiKey }, setLocalConfig] = useState(config);
@@ -63,7 +63,7 @@ const Settings: React.FC = ({
};
const handleClose = (newConfig: ExtensionConfig | undefined | null) => {
- handleCloseDialog(newConfig);
+ closeHandler(newConfig);
if (!newConfig) {
setLocalConfig(config);
}
From 307699533cdb62877bc3716f55940353191cd76a Mon Sep 17 00:00:00 2001
From: Hugo Guerrero <1001939+hguerrero@users.noreply.github.com>
Date: Sun, 19 Nov 2023 22:38:44 -0500
Subject: [PATCH 02/11] use functions
---
client/src/api/metrics.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/client/src/api/metrics.ts b/client/src/api/metrics.ts
index 1e79755..e957a00 100644
--- a/client/src/api/metrics.ts
+++ b/client/src/api/metrics.ts
@@ -20,7 +20,7 @@ import { createDockerDesktopClient } from '@docker/extension-api-client';
var clientID = "";
-function send(eventName: string, clientID: string, payload: Object) {
+const send = (eventName: string, clientID: string, payload: Object) => {
fetch(`https://microcks-dde-metrics-oafcwlgvlq-ew.a.run.app/collect`, {
method: "POST",
body: JSON.stringify({
@@ -36,7 +36,7 @@ function send(eventName: string, clientID: string, payload: Object) {
});
}
-export function sendMetric(eventName: string, payload: Object) {
+export const sendMetric = (eventName: string, payload: Object) => {
if (clientID !== "") {
send(eventName, clientID, payload);
} else {
From e839142d52aa2d02256b329a6ba4e5747526f260 Mon Sep 17 00:00:00 2001
From: Hugo Guerrero <1001939+hguerrero@users.noreply.github.com>
Date: Sun, 19 Nov 2023 22:38:54 -0500
Subject: [PATCH 03/11] fix imports
---
client/src/components/Services.tsx | 22 +++++-----------------
1 file changed, 5 insertions(+), 17 deletions(-)
diff --git a/client/src/components/Services.tsx b/client/src/components/Services.tsx
index 36e2f81..e0b9f15 100644
--- a/client/src/components/Services.tsx
+++ b/client/src/components/Services.tsx
@@ -16,34 +16,22 @@
* specific language governing permissions and limitations
* under the License.
*/
-import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
-import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';
-import WarningAmberIcon from '@mui/icons-material/WarningAmber';
import Box from '@mui/material/Box';
import Button from '@mui/material/Button';
-import Collapse from '@mui/material/Collapse';
-import IconButton from '@mui/material/IconButton';
-import List from '@mui/material/List';
-import ListItem from '@mui/material/ListItem';
import Stack from '@mui/material/Stack';
import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
-import TableCell from '@mui/material/TableCell';
import TableContainer from '@mui/material/TableContainer';
-import TableHead from '@mui/material/TableHead';
-import TableRow from '@mui/material/TableRow';
import Typography from '@mui/material/Typography';
-import React, { useEffect, useState } from 'react';
+import { useEffect, useState } from 'react';
import { APP_CONTAINER } from '../utils/constants';
import { useDockerDesktopClient } from '../utils/ddclient';
-import { ExtensionConfig } from '../types/ExtensionConfig';
-import MockURLRow from './MockURLRow';
-import ServiceTypeLabel from './ServiceTypeLabel';
-import { Operation, Service } from '../types/Service';
-import ServiceRow from './ServiceRow';
import UploadIcon from '@mui/icons-material/Upload';
+import { ExtensionConfig } from '../types/ExtensionConfig';
+import { Service } from '../types/Service';
import ImportDialog from './ImportDialog';
+import ServiceRow from './ServiceRow';
const Services = ({config}: { config: ExtensionConfig }) => {
const [services, setServices] = useState([]);
@@ -103,7 +91,7 @@ const Services = ({config}: { config: ExtensionConfig }) => {
-
+
>
);
};
From 5366496afb48e89ba98587b06131dc63cf98094e Mon Sep 17 00:00:00 2001
From: Hugo Guerrero <1001939+hguerrero@users.noreply.github.com>
Date: Sun, 19 Nov 2023 22:39:09 -0500
Subject: [PATCH 04/11] post file
---
client/src/components/ImportDialog.tsx | 33 ++++++++++++++++++++++----
1 file changed, 28 insertions(+), 5 deletions(-)
diff --git a/client/src/components/ImportDialog.tsx b/client/src/components/ImportDialog.tsx
index fe85d88..0191043 100644
--- a/client/src/components/ImportDialog.tsx
+++ b/client/src/components/ImportDialog.tsx
@@ -9,20 +9,43 @@ import FormGroup from '@mui/material/FormGroup';
import FormControlLabel from '@mui/material/FormControlLabel';
import UploadIcon from '@mui/icons-material/Upload';
import React, { useState } from 'react';
+import { ExtensionConfig } from '../types/ExtensionConfig';
const ImportDialog: React.FC<{
isDialogOpen: boolean;
+ config: ExtensionConfig;
closeHandler: () => void;
-}> = ({ isDialogOpen, closeHandler }) => {
- const [file, setFile] = useState();
+}> = ({ isDialogOpen, config, closeHandler }) => {
+ const [fileToUpload, setFileToUpload] = useState();
const [isSecondary, setIsSecondary] = useState(false);
+ const uploadFile = async (event: React.MouseEvent) => {
+ try {
+ const formData = new FormData();
+ formData.append('file', fileToUpload as File);
+
+ const result = await fetch(
+ `http://localhost:${
+ 8080 + config.portOffset || 8080
+ }/api/artifact/upload`,
+ {
+ method: 'POST',
+ body: formData,
+ },
+ );
+
+ if (result.ok) {
+ closeHandler()
+ }
+ } catch (error) {}
+ };
+
const handleClose = () => {
closeHandler();
};
const handleInputChange = (event: React.ChangeEvent) => {
- setFile(event.target.files?.[0]);
+ setFileToUpload(event.target.files?.[0]);
};
const handleCheckboxChange = (event: React.ChangeEvent) => {
@@ -67,8 +90,8 @@ const ImportDialog: React.FC<{
variant="contained"
color="primary"
size="large"
- onClick={(event) => {}}
- disabled={file === undefined}
+ onClick={uploadFile}
+ disabled={fileToUpload === undefined}
>
Import
From f4c3e22a48f185d649d1f9d0511dd44e069d1690 Mon Sep 17 00:00:00 2001
From: Hugo Guerrero <1001939+hguerrero@users.noreply.github.com>
Date: Sun, 19 Nov 2023 22:43:49 -0500
Subject: [PATCH 05/11] refresh after successful import
---
client/src/components/ImportDialog.tsx | 4 +-
client/src/components/Services.tsx | 72 +++++++++++++++-----------
2 files changed, 45 insertions(+), 31 deletions(-)
diff --git a/client/src/components/ImportDialog.tsx b/client/src/components/ImportDialog.tsx
index 0191043..9798965 100644
--- a/client/src/components/ImportDialog.tsx
+++ b/client/src/components/ImportDialog.tsx
@@ -14,7 +14,7 @@ import { ExtensionConfig } from '../types/ExtensionConfig';
const ImportDialog: React.FC<{
isDialogOpen: boolean;
config: ExtensionConfig;
- closeHandler: () => void;
+ closeHandler: (refresh?:boolean) => void;
}> = ({ isDialogOpen, config, closeHandler }) => {
const [fileToUpload, setFileToUpload] = useState();
const [isSecondary, setIsSecondary] = useState(false);
@@ -35,7 +35,7 @@ const ImportDialog: React.FC<{
);
if (result.ok) {
- closeHandler()
+ closeHandler(true)
}
} catch (error) {}
};
diff --git a/client/src/components/Services.tsx b/client/src/components/Services.tsx
index e0b9f15..75dd146 100644
--- a/client/src/components/Services.tsx
+++ b/client/src/components/Services.tsx
@@ -33,9 +33,9 @@ import { Service } from '../types/Service';
import ImportDialog from './ImportDialog';
import ServiceRow from './ServiceRow';
-const Services = ({config}: { config: ExtensionConfig }) => {
+const Services = ({ config }: { config: ExtensionConfig }) => {
const [services, setServices] = useState([]);
- const [isImportDialog, setIsImportDialog] = useState(false)
+ const [isImportDialog, setIsImportDialog] = useState(false);
const ddClient = useDockerDesktopClient();
@@ -60,38 +60,52 @@ const Services = ({config}: { config: ExtensionConfig }) => {
retrieveServices();
}, []);
- const handleOpenImport = () => {setIsImportDialog(true)};
+ const handleOpenImport = () => {
+ setIsImportDialog(true);
+ };
- const handleCloseImportDialog = () => {setIsImportDialog(false)};
+ const handleCloseImportDialog = (refresh?: boolean) => {
+ if (refresh) retrieveServices();
+ setIsImportDialog(false);
+ };
return (
<>
-
-
- Services
- } variant="contained" size="large" onClick={handleOpenImport}>
- Import Service
-
-
-
-
-
-
-
- {services.map((service) => (
-
- ))}
-
-
-
-
+
+
+ Services
+ }
+ variant="contained"
+ size="large"
+ onClick={handleOpenImport}
+ >
+ Import Service
+
+
+
+
+
+
+
+ {services.map((service) => (
+
+ ))}
+
+
+
+
+
-
-
+
>
);
};
From 619d2507cb30c8feb7bdadb1e93a10ce4f8f49bc Mon Sep 17 00:00:00 2001
From: Hugo Guerrero <1001939+hguerrero@users.noreply.github.com>
Date: Thu, 23 Nov 2023 00:05:50 -0500
Subject: [PATCH 06/11] import services with secondary artifacts
---
client/src/components/ImportDialog.tsx | 16 ++-
client/src/components/ServiceRow.tsx | 157 +++++++++++++++++--------
client/src/components/Services.tsx | 32 ++---
client/src/types/Service.ts | 18 ++-
4 files changed, 153 insertions(+), 70 deletions(-)
diff --git a/client/src/components/ImportDialog.tsx b/client/src/components/ImportDialog.tsx
index 9798965..a9ace6f 100644
--- a/client/src/components/ImportDialog.tsx
+++ b/client/src/components/ImportDialog.tsx
@@ -10,6 +10,7 @@ import FormControlLabel from '@mui/material/FormControlLabel';
import UploadIcon from '@mui/icons-material/Upload';
import React, { useState } from 'react';
import { ExtensionConfig } from '../types/ExtensionConfig';
+import { throwErrorAsString } from '../api/utils';
const ImportDialog: React.FC<{
isDialogOpen: boolean;
@@ -23,8 +24,9 @@ const ImportDialog: React.FC<{
try {
const formData = new FormData();
formData.append('file', fileToUpload as File);
+ formData.append('mainArtifact', isSecondary ? "false" : "true");
- const result = await fetch(
+ const response = await fetch(
`http://localhost:${
8080 + config.portOffset || 8080
}/api/artifact/upload`,
@@ -34,10 +36,16 @@ const ImportDialog: React.FC<{
},
);
- if (result.ok) {
- closeHandler(true)
+ if (!response.ok) {
+ console.error(response.statusText);
+ return;
}
- } catch (error) {}
+
+ closeHandler(true)
+
+ } catch (error) {
+ throwErrorAsString(error);
+ }
};
const handleClose = () => {
diff --git a/client/src/components/ServiceRow.tsx b/client/src/components/ServiceRow.tsx
index 8b97d9d..8e9cbb5 100644
--- a/client/src/components/ServiceRow.tsx
+++ b/client/src/components/ServiceRow.tsx
@@ -16,47 +16,56 @@ import TableContainer from '@mui/material/TableContainer';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
import Typography from '@mui/material/Typography';
-import { Operation, Service } from '../types/Service';
+import {
+ MessagesMap,
+ Operation,
+ ReqRespPair,
+ Service,
+ UnidirEvent,
+} from '../types/Service';
import ServiceTypeLabel from './ServiceTypeLabel';
import { useDockerDesktopClient } from '../utils/ddclient';
import MockURLRow from './MockURLRow';
import { ExtensionConfig } from '../types/ExtensionConfig';
import { APP_CONTAINER } from '../utils/constants';
+import { throwErrorAsString } from '../api/utils';
const ServiceRow = (props: { service: Service; config: ExtensionConfig }) => {
const [open, setOpen] = React.useState(false);
- const [messagesMap, setMessagesMap] = useState<{[key: string]: []}>()
+ const [messagesMap, setMessagesMap] = useState();
const ddClient = useDockerDesktopClient();
const { service, config } = props;
const retrieveServiceDetail = async () => {
- const result = await ddClient.docker.cli.exec('exec', [
- APP_CONTAINER,
- '/bin/curl',
- '-s',
- '-S',
- `localhost:8080/api/services/${service.id}`,
- ]);
- if (result?.stderr) {
- console.error(result.stderr);
- return;
+ try {
+ const response = await fetch(
+ `http://localhost:${8080 + config.portOffset || 8080}/api/services/${
+ service.id
+ }`,
+ );
+
+ if (!response.ok) {
+ console.error(response.statusText);
+ return;
+ }
+
+ const svc = (await response.json()) as Service;
+ console.log(svc);
+ setMessagesMap(svc.messagesMap);
+ } catch (error) {
+ throwErrorAsString(error);
}
- const svc = result?.parseJsonObject() as Service;
- console.log(svc);
- setMessagesMap(svc.messagesMap);
};
- const formatDestinationName = (
- operation: Operation,
- ): string => {
+ const formatDestinationName = (operation: Operation): string => {
const name =
service.name.replace(/\s/g, '').replace(/-/g, '') +
'-' +
service.version +
'-' +
- operation.name.replace(operation.method + " ", '').replace(/\//g, '-');
+ operation.name.replace(operation.method + ' ', '').replace(/\//g, '-');
return name;
};
@@ -66,7 +75,7 @@ const ServiceRow = (props: { service: Service; config: ExtensionConfig }) => {
const formatMockUrl = (
operation: Operation,
- dispatchCriteria?: string,
+ dispatchCriteria?: string | null,
): string => {
var result = `http://localhost:${8080 + config.portOffset}`;
@@ -74,29 +83,40 @@ const ServiceRow = (props: { service: Service; config: ExtensionConfig }) => {
result += '/rest/';
result += encodeUrl(service.name) + '/' + service.version;
- var parts:{[key: string]: string} = {};
+ var parts: { [key: string]: string } = {};
var params = {};
var operationName = operation.name;
-
+
if (dispatchCriteria != null) {
- var partsCriteria = (dispatchCriteria.indexOf('?') == -1 ? dispatchCriteria : dispatchCriteria.substring(0, dispatchCriteria.indexOf('?')));
- var paramsCriteria = (dispatchCriteria.indexOf('?') == -1 ? null : dispatchCriteria.substring(dispatchCriteria.indexOf('?') + 1));
+ var partsCriteria =
+ dispatchCriteria.indexOf('?') == -1
+ ? dispatchCriteria
+ : dispatchCriteria.substring(0, dispatchCriteria.indexOf('?'));
+ var paramsCriteria =
+ dispatchCriteria.indexOf('?') == -1
+ ? null
+ : dispatchCriteria.substring(dispatchCriteria.indexOf('?') + 1);
partsCriteria = encodeUrl(partsCriteria);
partsCriteria.split('/').forEach((element, index, array) => {
- if (element){
+ if (element) {
parts[element.split('=')[0]] = element.split('=')[1];
}
});
-
- operationName = operationName.replace(/{([a-zA-Z0-9-_]+)}/g, (match, p1, string) => {
- return parts[p1];
- });
+ operationName = operationName.replace(
+ /{([a-zA-Z0-9-_]+)}/g,
+ (match, p1, string) => {
+ return parts[p1];
+ },
+ );
// Support also Postman syntax with /:part
- operationName = operationName.replace(/:([a-zA-Z0-9-_]+)/g, (match, p1, string) => {
- return parts[p1];
- });
+ operationName = operationName.replace(
+ /:([a-zA-Z0-9-_]+)/g,
+ (match, p1, string) => {
+ return parts[p1];
+ },
+ );
if (paramsCriteria != null) {
operationName += '?' + paramsCriteria.replace(/\?/g, '&');
}
@@ -111,7 +131,7 @@ const ServiceRow = (props: { service: Service; config: ExtensionConfig }) => {
} else if (service.type === 'GENERIC_REST') {
result += '/dynarest/';
result += encodeUrl(service.name) + '/' + service.version;
- result += operation.name.replace(operation.method + " ", '');
+ result += operation.name.replace(operation.method + ' ', '');
} else if (service.type === 'GRPC') {
result = `http://localhost:${9090 + config.portOffset}`;
} else if (service.type === 'EVENT') {
@@ -228,24 +248,59 @@ const ServiceRow = (props: { service: Service; config: ExtensionConfig }) => {
) : messagesMap ? (
-
- {messagesMap[operation.name].map(
- (value: any, index) => (
-
-
-
- ),
- )}
-
+ messagesMap[operation.name].length ? (
+
+ {messagesMap[operation.name].map(
+ (value: ReqRespPair | UnidirEvent, index) =>
+ value.type === 'reqRespPair' ? (
+
+
+
+ ) : value.type === 'unidirEvent' &&
+ index === 0 ? (
+
+
+
+ ) : (
+ <>>
+ ),
+ )}
+
+ ) : (
+
+
+
+ There are no examples to mock for this
+ operation
+
+
+ )
) : (
)}
diff --git a/client/src/components/Services.tsx b/client/src/components/Services.tsx
index 75dd146..b02ae9b 100644
--- a/client/src/components/Services.tsx
+++ b/client/src/components/Services.tsx
@@ -24,10 +24,10 @@ import TableBody from '@mui/material/TableBody';
import TableContainer from '@mui/material/TableContainer';
import Typography from '@mui/material/Typography';
import { useEffect, useState } from 'react';
-import { APP_CONTAINER } from '../utils/constants';
import { useDockerDesktopClient } from '../utils/ddclient';
import UploadIcon from '@mui/icons-material/Upload';
+import { throwErrorAsString } from '../api/utils';
import { ExtensionConfig } from '../types/ExtensionConfig';
import { Service } from '../types/Service';
import ImportDialog from './ImportDialog';
@@ -40,20 +40,24 @@ const Services = ({ config }: { config: ExtensionConfig }) => {
const ddClient = useDockerDesktopClient();
const retrieveServices = async () => {
- const result = await ddClient.docker.cli.exec('exec', [
- APP_CONTAINER,
- '/bin/curl',
- '-s',
- '-S',
- 'localhost:8080/api/services',
- ]);
- if (result?.stderr) {
- console.error(result.stderr);
- return;
+ try {
+ const response = await fetch(
+ `http://localhost:${
+ 8080 + config.portOffset || 8080
+ }/api/services`
+ );
+
+ if (!response.ok) {
+ console.error(response.statusText);
+ return;
+ }
+
+ const svcs = await response.json() as Service[];
+ console.log(svcs);
+ setServices(svcs);
+ } catch (error) {
+ throwErrorAsString(error);
}
- const svcs = result?.parseJsonObject() as Service[];
- console.log(svcs);
- setServices(svcs);
};
useEffect(() => {
diff --git a/client/src/types/Service.ts b/client/src/types/Service.ts
index ff80c49..2d0f466 100644
--- a/client/src/types/Service.ts
+++ b/client/src/types/Service.ts
@@ -13,7 +13,7 @@ export type Service = {
version: string;
type: ServiceType;
operations: Operation[];
- messagesMap: any;
+ messagesMap: MessagesMap;
};
export type Operation = {
@@ -24,3 +24,19 @@ export type Operation = {
dispatcherRules: string;
resourcePaths: string[];
};
+
+export type BaseMessagesMap = {
+ type: "reqRespPair" | "unidirEvent"
+}
+
+export type ReqRespPair = {
+ request: any;
+ response: any;
+} & BaseMessagesMap
+
+export type UnidirEvent = {
+ eventMessage: any
+} & BaseMessagesMap
+
+export type MessagesMap = {
+ [key: string]: ReqRespPair[] | UnidirEvent[] };
From 07f7a21799ba300900c6512b22ec87783c658315 Mon Sep 17 00:00:00 2001
From: Hugo Guerrero <1001939+hguerrero@users.noreply.github.com>
Date: Thu, 23 Nov 2023 12:17:32 -0500
Subject: [PATCH 07/11] use custom latest tag for extension
---
client/src/App.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/client/src/App.tsx b/client/src/App.tsx
index e6b094c..662ba94 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -296,7 +296,7 @@ const App = () => {
`${9090 + config.portOffset}:9090`,
'--label',
'com.docker.compose.project=microcks_microcks-docker-desktop-extension-desktop-extension',
- 'quay.io/microcks/microcks-uber:latest',
+ 'quay.io/microcks/microcks-uber:latest-extension',
];
if (!appStatus.exists) {
console.log('Creating ', APP_CONTAINER);
From efc4bb9a4fdc9cb7ea2a3adf1b0c66305ce9475a Mon Sep 17 00:00:00 2001
From: Hugo Guerrero <1001939+hguerrero@users.noreply.github.com>
Date: Thu, 23 Nov 2023 13:03:04 -0500
Subject: [PATCH 08/11] use only one mock url for graphql
---
client/src/components/ServiceRow.tsx | 29 +++++++++++++++-------------
1 file changed, 16 insertions(+), 13 deletions(-)
diff --git a/client/src/components/ServiceRow.tsx b/client/src/components/ServiceRow.tsx
index 8e9cbb5..db419e3 100644
--- a/client/src/components/ServiceRow.tsx
+++ b/client/src/components/ServiceRow.tsx
@@ -253,19 +253,22 @@ const ServiceRow = (props: { service: Service; config: ExtensionConfig }) => {
{messagesMap[operation.name].map(
(value: ReqRespPair | UnidirEvent, index) =>
value.type === 'reqRespPair' ? (
-
-
-
+ (!service.type.includes('GRAPHQL') ||
+ index === 0) && (
+
+
+
+ )
) : value.type === 'unidirEvent' &&
index === 0 ? (
From 782df1ab50dcbd23d35a72f43f8bc115251fb596 Mon Sep 17 00:00:00 2001
From: Hugo Guerrero <1001939+hguerrero@users.noreply.github.com>
Date: Sat, 20 Jan 2024 18:00:10 -0500
Subject: [PATCH 09/11] render correctly gRPC
---
client/src/components/ServiceRow.tsx | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/client/src/components/ServiceRow.tsx b/client/src/components/ServiceRow.tsx
index db419e3..84069b1 100644
--- a/client/src/components/ServiceRow.tsx
+++ b/client/src/components/ServiceRow.tsx
@@ -1,4 +1,3 @@
-import React, { useState } from 'react';
import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';
import WarningAmberIcon from '@mui/icons-material/WarningAmber';
@@ -8,7 +7,6 @@ import Collapse from '@mui/material/Collapse';
import IconButton from '@mui/material/IconButton';
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
-import Stack from '@mui/material/Stack';
import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell from '@mui/material/TableCell';
@@ -16,6 +14,9 @@ import TableContainer from '@mui/material/TableContainer';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
import Typography from '@mui/material/Typography';
+import React, { useState } from 'react';
+import { throwErrorAsString } from '../api/utils';
+import { ExtensionConfig } from '../types/ExtensionConfig';
import {
MessagesMap,
Operation,
@@ -23,12 +24,9 @@ import {
Service,
UnidirEvent,
} from '../types/Service';
-import ServiceTypeLabel from './ServiceTypeLabel';
import { useDockerDesktopClient } from '../utils/ddclient';
import MockURLRow from './MockURLRow';
-import { ExtensionConfig } from '../types/ExtensionConfig';
-import { APP_CONTAINER } from '../utils/constants';
-import { throwErrorAsString } from '../api/utils';
+import ServiceTypeLabel from './ServiceTypeLabel';
const ServiceRow = (props: { service: Service; config: ExtensionConfig }) => {
const [open, setOpen] = React.useState(false);
@@ -38,6 +36,8 @@ const ServiceRow = (props: { service: Service; config: ExtensionConfig }) => {
const { service, config } = props;
+ const singleRowTypes = ['GRAPHQL', 'GRPC']
+
const retrieveServiceDetail = async () => {
try {
const response = await fetch(
@@ -253,7 +253,7 @@ const ServiceRow = (props: { service: Service; config: ExtensionConfig }) => {
{messagesMap[operation.name].map(
(value: ReqRespPair | UnidirEvent, index) =>
value.type === 'reqRespPair' ? (
- (!service.type.includes('GRAPHQL') ||
+ (!singleRowTypes.includes(service.type) ||
index === 0) && (
Date: Sat, 20 Jan 2024 18:00:41 -0500
Subject: [PATCH 10/11] Show message for unsupported bindings
---
client/src/components/MockURLRow.tsx | 65 +++++++++++++++++++---------
1 file changed, 44 insertions(+), 21 deletions(-)
diff --git a/client/src/components/MockURLRow.tsx b/client/src/components/MockURLRow.tsx
index 701fd51..131e435 100644
--- a/client/src/components/MockURLRow.tsx
+++ b/client/src/components/MockURLRow.tsx
@@ -1,11 +1,12 @@
import LaunchIcon from '@mui/icons-material/Launch';
+import WarningAmberIcon from '@mui/icons-material/WarningAmber';
+import Box from '@mui/material/Box';
import IconButton from '@mui/material/IconButton';
import Link from '@mui/material/Link';
import Typography from '@mui/material/Typography';
import React from 'react';
import { useDockerDesktopClient } from '../utils/ddclient';
import ClipboardCopy from './ClipboardCopy';
-import { Box } from '@mui/material';
interface MockURLRowProps {
bindings?: any;
@@ -21,26 +22,48 @@ const MockURLRow: React.FC = ({
const ddClient = useDockerDesktopClient();
return bindings ? (
-
- {Object.keys(bindings).map((binding: any) => (
- <>
-
- {bindings[binding].type} endpoint:{' '}
-
- {mockURL}
-
-
-
-
- {bindings[binding].type} destination:{' '}
-
- {destination}
-
-
-
- >
- ))}
-
+ <>
+ {Object.keys(bindings).map((binding: any) =>
+ binding == 'KAFKA' ? (
+
+
+ {bindings[binding].type} endpoint:{' '}
+
+ {mockURL}
+
+
+
+
+ {bindings[binding].type} destination:{' '}
+
+ {destination}
+
+
+
+
+ ) : (
+
+
+
+ This extension does not support the {binding} binding at this time.
+
+
+ ),
+ )}
+ >
) : (
Date: Sat, 20 Jan 2024 18:19:21 -0500
Subject: [PATCH 11/11] reset dialog
---
client/src/components/ImportDialog.tsx | 31 +++++++++++++-------------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/client/src/components/ImportDialog.tsx b/client/src/components/ImportDialog.tsx
index a9ace6f..6dc4cf8 100644
--- a/client/src/components/ImportDialog.tsx
+++ b/client/src/components/ImportDialog.tsx
@@ -1,21 +1,21 @@
-import Dialog from '@mui/material/Dialog';
-import DialogTitle from '@mui/material/DialogTitle';
-import DialogContent from '@mui/material/DialogContent';
-import DialogActions from '@mui/material/DialogActions';
+import UploadIcon from '@mui/icons-material/Upload';
import Button from '@mui/material/Button';
-import TextField from '@mui/material/TextField';
import Checkbox from '@mui/material/Checkbox';
-import FormGroup from '@mui/material/FormGroup';
+import Dialog from '@mui/material/Dialog';
+import DialogActions from '@mui/material/DialogActions';
+import DialogContent from '@mui/material/DialogContent';
+import DialogTitle from '@mui/material/DialogTitle';
import FormControlLabel from '@mui/material/FormControlLabel';
-import UploadIcon from '@mui/icons-material/Upload';
+import FormGroup from '@mui/material/FormGroup';
+import TextField from '@mui/material/TextField';
import React, { useState } from 'react';
-import { ExtensionConfig } from '../types/ExtensionConfig';
import { throwErrorAsString } from '../api/utils';
+import { ExtensionConfig } from '../types/ExtensionConfig';
const ImportDialog: React.FC<{
isDialogOpen: boolean;
config: ExtensionConfig;
- closeHandler: (refresh?:boolean) => void;
+ closeHandler: (refresh?: boolean) => void;
}> = ({ isDialogOpen, config, closeHandler }) => {
const [fileToUpload, setFileToUpload] = useState();
const [isSecondary, setIsSecondary] = useState(false);
@@ -24,7 +24,7 @@ const ImportDialog: React.FC<{
try {
const formData = new FormData();
formData.append('file', fileToUpload as File);
- formData.append('mainArtifact', isSecondary ? "false" : "true");
+ formData.append('mainArtifact', isSecondary ? 'false' : 'true');
const response = await fetch(
`http://localhost:${
@@ -41,15 +41,16 @@ const ImportDialog: React.FC<{
return;
}
- closeHandler(true)
-
+ handleClose(true);
} catch (error) {
throwErrorAsString(error);
}
};
- const handleClose = () => {
- closeHandler();
+ const handleClose = (refresh?: boolean) => {
+ setFileToUpload(undefined);
+ setIsSecondary(false);
+ closeHandler(refresh);
};
const handleInputChange = (event: React.ChangeEvent) => {
@@ -63,7 +64,7 @@ const ImportDialog: React.FC<{
return (