This is an automated email from the ASF dual-hosted git repository. marat pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-karavan.git
commit 90c8fea5eaef5c6bca672ff2106c9c71e2270796 Author: Marat Gubaidullin <ma...@talismancloud.io> AuthorDate: Wed Dec 27 12:53:21 2023 -0500 Fix #936 --- .../camel/karavan/api/InfrastructureResource.java | 12 +++ .../apache/camel/karavan/api/StatusResource.java | 53 +++++++++- .../karavan/infinispan/InfinispanService.java | 12 +++ .../src/main/webui/src/api/KaravanApi.tsx | 17 +++ .../main/webui/src/config/ConfigurationPage.tsx | 117 +++++++++++---------- .../karavan-app/src/main/webui/src/main/Main.tsx | 7 -- .../src/main/webui/src/main/MainRoutes.tsx | 2 + .../src/main/webui/src/main/PageNavigation.tsx | 3 +- 8 files changed, 158 insertions(+), 65 deletions(-) diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/InfrastructureResource.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/InfrastructureResource.java index 0f3c2143..dd78fd78 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/InfrastructureResource.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/InfrastructureResource.java @@ -149,4 +149,16 @@ public class InfrastructureResource { return Response.ok(List.of()).build(); } } + + @PUT + @Produces(MediaType.APPLICATION_JSON) + @Path("/informers") + public Response restartInformers() { + if (ConfigService.inKubernetes()) { + kubernetesService.startInformers(null); + return Response.ok().build(); + } else { + return Response.noContent().build(); + } + } } \ No newline at end of file diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java index e62924e7..ce779e13 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/api/StatusResource.java @@ -17,10 +17,7 @@ package org.apache.camel.karavan.api; import jakarta.inject.Inject; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; +import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import org.apache.camel.karavan.infinispan.InfinispanService; @@ -60,4 +57,52 @@ public class StatusResource { return List.of(); } } + + @DELETE + @Produces(MediaType.APPLICATION_JSON) + @Path("/deployment") + public Response deleteDeploymentStatuses() { + if (infinispanService.isReady()) { + infinispanService.deleteAllDeploymentsStatuses(); + return Response.ok().build(); + } else { + return Response.noContent().build(); + } + } + + @DELETE + @Produces(MediaType.APPLICATION_JSON) + @Path("/container") + public Response deleteContainerStatuses() { + if (infinispanService.isReady()) { + infinispanService.deleteAllContainersStatuses(); + return Response.ok().build(); + } else { + return Response.noContent().build(); + } + } + + @DELETE + @Produces(MediaType.APPLICATION_JSON) + @Path("/camel") + public Response deleteCamelStatuses() { + if (infinispanService.isReady()) { + infinispanService.deleteAllCamelStatuses(); + return Response.ok().build(); + } else { + return Response.noContent().build(); + } + } + + @DELETE + @Produces(MediaType.APPLICATION_JSON) + @Path("/all") + public Response deleteAllStatuses() { + if (infinispanService.isReady()) { + infinispanService.clearAllStatuses(); + return Response.ok().build(); + } else { + return Response.noContent().build(); + } + } } \ No newline at end of file diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/InfinispanService.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/InfinispanService.java index a2f4c6fe..fca6c20e 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/InfinispanService.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/infinispan/InfinispanService.java @@ -218,6 +218,10 @@ public class InfinispanService implements HealthCheck { .execute().list(); } + public void deleteAllDeploymentsStatuses() { + deploymentStatuses.clearAsync(); + } + public void saveServiceStatus(ServiceStatus status) { serviceStatuses.put(GroupedKey.create(status.getProjectId(), status.getEnv(), status.getProjectId()), status); } @@ -285,6 +289,10 @@ public class InfinispanService implements HealthCheck { containerStatuses.remove(GroupedKey.create(status.getProjectId(), status.getEnv(), status.getContainerName())); } + public void deleteAllContainersStatuses() { + containerStatuses.clearAsync(); + } + public void deleteContainerStatus(String projectId, String env, String containerName) { containerStatuses.remove(GroupedKey.create(projectId, env, containerName)); } @@ -339,6 +347,10 @@ public class InfinispanService implements HealthCheck { }); } + public void deleteAllCamelStatuses() { + camelStatuses.clearAsync(); + } + public List<ContainerStatus> getLoadedDevModeStatuses() { QueryFactory queryFactory = Search.getQueryFactory(containerStatuses); return queryFactory.<ContainerStatus>create("FROM karavan.ContainerStatus WHERE type = :type AND codeLoaded = true") diff --git a/karavan-web/karavan-app/src/main/webui/src/api/KaravanApi.tsx b/karavan-web/karavan-app/src/main/webui/src/api/KaravanApi.tsx index 70d34a60..e5d54d05 100644 --- a/karavan-web/karavan-app/src/main/webui/src/api/KaravanApi.tsx +++ b/karavan-web/karavan-app/src/main/webui/src/api/KaravanApi.tsx @@ -566,6 +566,23 @@ export class KaravanApi { }); } + static async deleteAllStatuses(after: (res: AxiosResponse<any>) => void) { + instance.delete('/api/status/all/') + .then(res => { + after(res); + }).catch(err => { + after(err); + }); + } + + static async restartInformers(after: (res: AxiosResponse<any>) => void) { + instance.put('/api/infrastructure/informers/') + .then(res => { + after(res); + }).catch(err => { + after(err); + }); + } static async getKamelets(after: (yaml: string) => void) { instance.get('/api/kamelet', {headers: {'Accept': 'text/plain'}}) diff --git a/karavan-web/karavan-app/src/main/webui/src/config/ConfigurationPage.tsx b/karavan-web/karavan-app/src/main/webui/src/config/ConfigurationPage.tsx index 99482788..aa24a233 100644 --- a/karavan-web/karavan-app/src/main/webui/src/config/ConfigurationPage.tsx +++ b/karavan-web/karavan-app/src/main/webui/src/config/ConfigurationPage.tsx @@ -15,71 +15,82 @@ * limitations under the License. */ -import React from 'react'; -import {Button, PageSection, Tab, Tabs, TabTitleText, Text, TextContent, Toolbar, ToolbarContent, ToolbarItem +import React, {useState} from 'react'; +import { + Button, Flex, FlexItem, + PageSection, Switch, Tab, Tabs, Text, + TextContent, + Toolbar, + ToolbarContent, + ToolbarItem } from '@patternfly/react-core'; import '../designer/karavan.css'; import {MainToolbar} from "../designer/MainToolbar"; -import RefreshIcon from "@patternfly/react-icons/dist/esm/icons/sync-alt-icon"; +import {KaravanApi} from "../api/KaravanApi"; +import {EventBus} from "../designer/utils/EventBus"; interface Props { + dark: boolean, } -interface State { - templates: [], -} - -export class ConfigurationPage extends React.Component<Props, State> { +export const ConfigurationPage = (props: Props) => { - public state: State = { - templates: [] - }; + const [tab, setTab] = useState<string | number>("statuses"); - componentDidMount() { - this.onGetTemplates(); + function tools() { + return (<Toolbar id="toolbar-group-types"> + <ToolbarContent> + {tab === 'statuses' && <ToolbarItem> + <Button onClick={event => { + KaravanApi.deleteAllStatuses(res => { + if (res.status === 200) { + EventBus.sendAlert('Success', 'Statuses deleted', "info"); + KaravanApi.restartInformers(res1 => { + if (res1.status === 200) { + EventBus.sendAlert('Success', 'Informers restarted', "info"); + } + }) + } + }) + }}> + Cleanup statuses + </Button> + </ToolbarItem>} + {tab === 'secrets' && <ToolbarItem> + <Button>Add Secret</Button> + </ToolbarItem>} + {tab === 'configMaps' && <ToolbarItem> + <Button>Add ConfigMap</Button> + </ToolbarItem>} + </ToolbarContent> + </Toolbar>); } - onGetTemplates () { - // KaravanApi.getTemplates((templates: []) => { - // console.log(templates) - // this.setState({templates: templates}) - // }); + function title() { + return (<TextContent> + <Text component="h2">Configuration</Text> + </TextContent>); } - tools = () => (<Toolbar id="toolbar-group-types"> - <ToolbarContent> - <ToolbarItem> - <Button variant="link" icon={<RefreshIcon/>} onClick={e => this.onGetTemplates()}/> - </ToolbarItem> - </ToolbarContent> - </Toolbar>); - - title = () => (<TextContent> - <Text component="h2">Configuration</Text> - </TextContent>); + return ( + <PageSection className="container-page" padding={{default: 'noPadding'}}> + <PageSection className="tools-section" padding={{default: 'noPadding'}}> + <MainToolbar title={title()} tools={tools()}/> + </PageSection> + <PageSection className="tools-section" padding={{default: 'noPadding'}}> + <Flex direction={{default: "column"}} spaceItems={{default: "spaceItemsNone"}}> + <FlexItem className="knowledge-tabs"> + <Tabs activeKey={tab} onSelect={(event, tabIndex) => setTab(tabIndex)}> + <Tab eventKey="statuses" title="Statuses"/> + <Tab eventKey="secrets" title="Secrets" isDisabled/> + <Tab eventKey="configMaps" title="ConfigMaps" isDisabled/> + </Tabs> + </FlexItem> + </Flex> + </PageSection> + <PageSection isFilled className="container-page-section"> - render() { - return ( - <PageSection className="kamelet-section projects-page" padding={{default: 'noPadding'}}> - <PageSection className="tools-section" padding={{default: 'noPadding'}}> - <MainToolbar title={this.title()} tools={this.tools()}/> - </PageSection> - <PageSection isFilled className="kamelets-page"> - <Tabs - // activeKey={activeTabKey} - // onSelect={handleTabClick} - aria-label="Configurations" - role="tabs" - > - <Tab eventKey={0} title={<TabTitleText>Templates</TabTitleText>} aria-label="Templates"> - Templates - </Tab> - <Tab eventKey={11} title={<TabTitleText>Environments</TabTitleText>}> - Environments - </Tab> - </Tabs> - </PageSection> </PageSection> - ); - } -}; \ No newline at end of file + </PageSection> + ) +} \ No newline at end of file diff --git a/karavan-web/karavan-app/src/main/webui/src/main/Main.tsx b/karavan-web/karavan-app/src/main/webui/src/main/Main.tsx index 94060e78..00fc6ff5 100644 --- a/karavan-web/karavan-app/src/main/webui/src/main/Main.tsx +++ b/karavan-web/karavan-app/src/main/webui/src/main/Main.tsx @@ -15,7 +15,6 @@ * limitations under the License. */ -import {Navigate, Route, Routes} from 'react-router-dom'; import React, {useEffect, useRef} from "react"; import {KaravanApi} from "../api/KaravanApi"; import { @@ -23,17 +22,11 @@ import { FlexItem, Page, } from "@patternfly/react-core"; -import {ProjectsPage} from "../projects/ProjectsPage"; -import {ProjectPage} from "../project/ProjectPage"; -import {ServicesPage} from "../services/ServicesPage"; -import {ContainersPage} from "../containers/ContainersPage"; -import {KnowledgebasePage} from "../knowledgebase/KnowledgebasePage"; import {SsoApi} from "../api/SsoApi"; import {useAppConfigStore} from "../api/ProjectStore"; import {shallow} from "zustand/shallow"; import {PageNavigation} from "./PageNavigation"; import {useMainHook} from "./useMainHook"; -import {TemplatesPage} from "../templates/TemplatesPage"; import {Notification} from "../designer/utils/Notification"; import {MainLoader} from "./MainLoader"; import {MainRoutes} from "./MainRoutes"; diff --git a/karavan-web/karavan-app/src/main/webui/src/main/MainRoutes.tsx b/karavan-web/karavan-app/src/main/webui/src/main/MainRoutes.tsx index 5d35d4ef..0434dcef 100644 --- a/karavan-web/karavan-app/src/main/webui/src/main/MainRoutes.tsx +++ b/karavan-web/karavan-app/src/main/webui/src/main/MainRoutes.tsx @@ -23,6 +23,7 @@ import {ServicesPage} from "../services/ServicesPage"; import {ContainersPage} from "../containers/ContainersPage"; import {KnowledgebasePage} from "../knowledgebase/KnowledgebasePage"; import {TemplatesPage} from "../templates/TemplatesPage"; +import {ConfigurationPage} from "../config/ConfigurationPage"; export function MainRoutes() { @@ -34,6 +35,7 @@ export function MainRoutes() { <Route path="/services" element={<ServicesPage key="services"/>}/> <Route path="/containers" element={<ContainersPage key="services"/>}/> <Route path="/knowledgebase" element={<KnowledgebasePage dark={false}/>}/> + <Route path="/configuration" element={<ConfigurationPage dark={false}/>}/> <Route path="*" element={<Navigate to="/projects" replace/>}/> </Routes> ) diff --git a/karavan-web/karavan-app/src/main/webui/src/main/PageNavigation.tsx b/karavan-web/karavan-app/src/main/webui/src/main/PageNavigation.tsx index 8b19524e..fc2adfd8 100644 --- a/karavan-web/karavan-app/src/main/webui/src/main/PageNavigation.tsx +++ b/karavan-web/karavan-app/src/main/webui/src/main/PageNavigation.tsx @@ -31,7 +31,7 @@ import ProjectsIcon from "@patternfly/react-icons/dist/js/icons/repository-icon" import TemplatesIcon from "@patternfly/react-icons/dist/js/icons/blueprint-icon"; import KnowledgebaseIcon from "@patternfly/react-icons/dist/js/icons/book-open-icon"; import ContainersIcon from "@patternfly/react-icons/dist/js/icons/cubes-icon"; -import DashboardIcon from "@patternfly/react-icons/dist/js/icons/tachometer-alt-icon"; +import ConfigIcon from "@patternfly/react-icons/dist/js/icons/cogs-icon"; import ServicesIcon from "@patternfly/react-icons/dist/js/icons/services-icon"; import {useAppConfigStore, useDevModeStore, useFileStore} from "../api/ProjectStore"; import {shallow} from "zustand/shallow"; @@ -71,6 +71,7 @@ export function PageNavigation () { ) } pages.push(new MenuItem("knowledgebase", "Knowledgebase", <KnowledgebaseIcon/>)); + pages.push(new MenuItem("configuration", "Configuration", <ConfigIcon/>)); return pages; }