diff --git a/.asf.yaml b/.asf.yaml deleted file mode 100644 index ec35b205..00000000 --- a/.asf.yaml +++ /dev/null @@ -1,47 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -github: - description: EventMesh dashboard - features: - # Enable issue management - issues: true - # Enable wiki - wiki: true - homepage: https://eventmesh.apache.org/ - labels: - - pubsub - enabled_merge_buttons: - squash: true - merge: true - rebase: false - protected_branches: - main: - required_status_checks: - strict: true - required_pull_request_reviews: - dismiss_stale_reviews: true - required_approving_review_count: 1 -notifications: - commits: commits@eventmesh.apache.org - # Send all issue emails (new, closed, comments) to issues@ - issues: issues@eventmesh.apache.org - # Send new/closed PR notifications to dev@ - pullrequests_status: dev@eventmesh.apache.org - # Send individual PR comments/reviews to issues@ - pullrequests_comment: issues@eventmesh.apache.org - jira_options: link label worklog diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 252089de..00000000 --- a/.dockerignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/ -out/ \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7415ebb1..b1f31d2b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,131 +1,122 @@ -# https://github.com/github/gitignore/blob/main/Node.gitignore -# Logs -logs +.settings/ +.project +.classpath +.target +./**/.settings/ +./**/.project +./**/.classpath +./**/target/ + + +#gitignore文件的内容 +.factorypath +.DS_Store +.project +*.prefs +.classpath +.setting/h +.settings/ +.idea/ +*.iml +*.ipr +*.iws +logs/ + +#忽略eclipse相关 +org.eclipse.core.resources.prefs +org.eclipse.jdt.core.prefs +org.eclipse.m2e.core.prefs +org.eclipse.wst.common.component +org.eclipse.wst.common.project.facet.core.xml + +#忽略java相关的文件 +*.class +*.trc +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +#忽略maven相关的文件 +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties + +# Built application files +*.apk +*.ap_ + + +#忽略andriod相关的文件 +# Files for the Dalvik VM +*.dex +# Generated files +bin/ +gen/ +# Gradle files +.gradle/ +build/ +*/build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ +# Log Files *.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* -.pnpm-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# Snowpack dependency directory (https://snowpack.dev/) -web_modules/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional stylelint cache -.stylelintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local - -# parcel-bundler cache (https://parceljs.org/) -.cache -.parcel-cache - -# Next.js build output -.next -out - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and not Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# vuepress v2.x temp and cache directory -.temp -.cache - -# Docusaurus cache and generated files -.docusaurus - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -# Stores VSCode versions used for testing VSCode extensions -.vscode-test - -# yarn v2 -.yarn/cache -.yarn/unplugged -.yarn/build-state.yml -.yarn/install-state.gz -.pnp.* \ No newline at end of file +# Android Studio Navigation editor temp files +.navigation/ +# Android Studio captures folder +captures/ + +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index c6d90a59..1d3574c3 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,24 @@ -This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). -## Getting Started -First, run the development server: +## 介绍 -```bash -npm run dev -# or -yarn dev -``` -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. +## 业务架构 -You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file. -[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`. +## 技术架构 -The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages. -## Getting Started with Docker +### 模块依赖图 -Pull the image and run the container by following commands: +### 模块介绍 -``` -docker pull apache/eventmesh-dashboard:latest -``` +1. eventmesh-dashboard-console 业务模块的代码 +2. eventmesh-dashboard-observe 监控模块的代码 +3. eventmesh-dashboard-core 对eventmesh以及相关组件的代码 +4. eventmesh-dashboard-service 公用接口 +5. eventmesh-dashboard-common 公共模块的代码 +6. eventmesh-dashboard-view 前端代码 -``` -docker run -d --name eventmesh-dashboard -p 8080:80 -t apache/eventmesh-dashboard:latest -``` -Open [http://localhost:8080](http://localhost:8080) in your browser to see the result. - -You can also build a mirror of your own by executing the following command in the root of your git repository: - -``` -docker build -t /eventmesh-dashboard:latest -f docker/Dockerfile . -``` - -## Learn More - -To learn more about Next.js, take a look at the following resources: - -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - -You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! - -## Deploy on Vercel - -The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. - -Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. +### eventmesh-dashboard-core 介绍 diff --git a/components/client/GrpcClientTable.tsx b/components/client/GrpcClientTable.tsx deleted file mode 100644 index 1ffdfeaa..00000000 --- a/components/client/GrpcClientTable.tsx +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { - HStack, - Select, - Input, - Table, - Thead, - Tbody, - Tr, - Th, - Td, - TableContainer, - useToast, - Box, - Button, -} from '@chakra-ui/react'; -import axios from 'axios'; -import { useContext, useEffect, useState } from 'react'; -import { AppContext } from '../../context/context'; - -interface GrpcClient { - env: string, - subsystem: string, - url: string, - pid: number, - host: string, - port: number, - version: string, - idc: string, - group: string, - purpose: string, - protocol: string, -} - -interface GrpcClientProps { - url: string, - group: string, -} - -interface RemoveGrpcClientRequest { - url: string, -} - -const GrpcClientRow = ({ - url, group, -}: GrpcClientProps) => { - const { state } = useContext(AppContext); - - const toast = useToast(); - const [loading, setLoading] = useState(false); - const onRemoveClick = async () => { - try { - setLoading(true); - await axios.delete(`${state.endpoint}/client/grpc`, { - data: { - url, - }, - }); - setLoading(false); - } catch (error) { - if (axios.isAxiosError(error)) { - toast({ - title: 'Failed to remove the gRPC Client', - description: error.message, - status: 'error', - duration: 3000, - isClosable: true, - }); - } - } - }; - - return ( - - {url} - {group} - - - - - - - ); -}; - -const GrpcClientTable = () => { - const { state } = useContext(AppContext); - - const [searchInput, setSearchInput] = useState(''); - const handleSearchInputChange = (event: React.FormEvent) => { - setSearchInput(event.currentTarget.value); - }; - - const [groupSet, setGroupSet] = useState>(new Set()); - const [groupFilter, setGroupFilter] = useState(''); - const handleGroupSelectChange = (event: React.FormEvent) => { - setGroupFilter(event.currentTarget.value); - }; - - const [GrpcClientList, setGrpcClientList] = useState([]); - const toast = useToast(); - useEffect(() => { - const fetch = async () => { - try { - const { data } = await axios.get(`${state.endpoint}/client/grpc`); - setGrpcClientList(data); - - const nextGroupSet = new Set(); - data.forEach(({ group }) => { - nextGroupSet.add(group); - }); - setGroupSet(nextGroupSet); - } catch (error) { - if (axios.isAxiosError(error)) { - toast({ - title: 'Failed to fetch the list of gRPC Clients', - description: 'Unable to connect to the EventMesh daemon', - status: 'error', - duration: 3000, - isClosable: true, - }); - setGrpcClientList([]); - } - } - }; - - fetch(); - }, []); - - return ( - - - - - - - - - - - - - - - - - {GrpcClientList && GrpcClientList.filter(({ - url, group, - }) => { - if (searchInput && !url.includes(searchInput)) { - return false; - } - if (groupFilter && groupFilter !== group) { - return false; - } - return true; - }).map(({ - url, group, - }) => ( - - ))} - -
URLGroupAction
-
-
- ); -}; - -export default GrpcClientTable; diff --git a/components/client/HTTPClientTable.tsx b/components/client/HTTPClientTable.tsx deleted file mode 100644 index 832ea91b..00000000 --- a/components/client/HTTPClientTable.tsx +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { - HStack, - Select, - Input, - Table, - Thead, - Tbody, - Tr, - Th, - Td, - TableContainer, - useToast, - Box, - Button, -} from '@chakra-ui/react'; -import axios from 'axios'; -import { useContext, useEffect, useState } from 'react'; -import { AppContext } from '../../context/context'; - -interface HTTPClient { - env: string, - subsystem: string, - url: string, - pid: number, - host: string, - port: number, - version: string, - idc: string, - group: string, - purpose: string, - protocol: string, -} - -interface HTTPClientProps { - url: string, - group: string, -} - -interface RemoveHTTPClientRequest { - url: string, -} - -const HTTPClientRow = ({ - url, group, -}: HTTPClientProps) => { - const { state } = useContext(AppContext); - - const toast = useToast(); - const [loading, setLoading] = useState(false); - const onRemoveClick = async () => { - try { - setLoading(true); - await axios.delete(`${state.endpoint}/client/http`, { - data: { - url, - }, - }); - setLoading(false); - } catch (error) { - if (axios.isAxiosError(error)) { - toast({ - title: 'Failed to remove the HTTP Client', - description: error.message, - status: 'error', - duration: 3000, - isClosable: true, - }); - } - } - }; - - return ( - - {url} - {group} - - - - - - - ); -}; - -const HTTPClientTable = () => { - const { state } = useContext(AppContext); - - const [searchInput, setSearchInput] = useState(''); - const handleSearchInputChange = (event: React.FormEvent) => { - setSearchInput(event.currentTarget.value); - }; - - const [groupSet, setGroupSet] = useState>(new Set()); - const [groupFilter, setGroupFilter] = useState(''); - const handleGroupSelectChange = (event: React.FormEvent) => { - setGroupFilter(event.currentTarget.value); - }; - - const [HTTPClientList, setHTTPClientList] = useState([]); - const toast = useToast(); - useEffect(() => { - const fetch = async () => { - try { - const { data } = await axios.get(`${state.endpoint}/client/http`); - setHTTPClientList(data); - - const nextGroupSet = new Set(); - data.forEach(({ group }) => { - nextGroupSet.add(group); - }); - setGroupSet(nextGroupSet); - } catch (error) { - if (axios.isAxiosError(error)) { - toast({ - title: 'Failed to fetch the list of HTTP Clients', - description: 'Unable to connect to the EventMesh daemon', - status: 'error', - duration: 3000, - isClosable: true, - }); - setHTTPClientList([]); - } - } - }; - - fetch(); - }, []); - - return ( - - - - - - - - - - - - - - - - - {HTTPClientList && HTTPClientList.filter(({ - url, group, - }) => { - if (searchInput && !url.includes(searchInput)) { - return false; - } - if (groupFilter && groupFilter !== group) { - return false; - } - return true; - }).map(({ - url, group, - }) => ( - - ))} - -
URLGroupAction
-
-
- ); -}; - -export default HTTPClientTable; diff --git a/components/client/TCPClientTable.tsx b/components/client/TCPClientTable.tsx deleted file mode 100644 index dc245890..00000000 --- a/components/client/TCPClientTable.tsx +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { - HStack, - Select, - Input, - Table, - Thead, - Tbody, - Tr, - Th, - Td, - TableContainer, - useToast, - Box, - Button, -} from '@chakra-ui/react'; -import axios from 'axios'; -import { useContext, useEffect, useState } from 'react'; -import { AppContext } from '../../context/context'; - -interface TCPClient { - env: string, - subsystem: string, - url: string, - pid: number, - host: string, - port: number, - version: string, - idc: string, - group: string, - purpose: string, - protocol: string, -} - -interface TCPClientProps { - host: string, - port: number, - group: string, -} - -interface RemoveTCPClientRequest { - host: string, - port: number, -} - -const TCPClientRow = ({ - host, port, group, -}: TCPClientProps) => { - const { state } = useContext(AppContext); - - const toast = useToast(); - const [loading, setLoading] = useState(false); - const onRemoveClick = async () => { - try { - setLoading(true); - await axios.delete(`${state.endpoint}/client/tcp`, { - data: { - host, - port, - }, - }); - setLoading(false); - } catch (error) { - if (axios.isAxiosError(error)) { - toast({ - title: 'Failed to remove the TCP Client', - description: error.message, - status: 'error', - duration: 3000, - isClosable: true, - }); - } - } - }; - - return ( - - {`${host}:${port}`} - {group} - - - - - - - ); -}; - -const TCPClientTable = () => { - const { state } = useContext(AppContext); - - const [searchInput, setSearchInput] = useState(''); - const handleSearchInputChange = (event: React.FormEvent) => { - setSearchInput(event.currentTarget.value); - }; - - const [groupSet, setGroupSet] = useState>(new Set()); - const [groupFilter, setGroupFilter] = useState(''); - const handleGroupSelectChange = (event: React.FormEvent) => { - setGroupFilter(event.currentTarget.value); - }; - - const [TCPClientList, setTCPClientList] = useState([]); - const toast = useToast(); - useEffect(() => { - const fetch = async () => { - try { - const { data } = await axios.get(`${state.endpoint}/client/tcp`); - setTCPClientList(data); - - const nextGroupSet = new Set(); - data.forEach(({ group }) => { - nextGroupSet.add(group); - }); - setGroupSet(nextGroupSet); - } catch (error) { - if (axios.isAxiosError(error)) { - toast({ - title: 'Failed to fetch the list of TCP Clients', - description: 'Unable to connect to the EventMesh daemon', - status: 'error', - duration: 3000, - isClosable: true, - }); - setTCPClientList([]); - } - } - }; - - fetch(); - }, []); - - return ( - - - - - - - - - - - - - - - - - - {TCPClientList && TCPClientList.filter(({ - host, port, group, - }) => { - const address = `${host}:${port}`; - if (searchInput && !address.includes(searchInput)) { - return false; - } - if (groupFilter && groupFilter !== group) { - return false; - } - return true; - }).map(({ - host, port, group, - }) => ( - - ))} - -
HostHostGroupAction
-
-
- ); -}; - -export default TCPClientTable; diff --git a/components/event/EventTable.tsx b/components/event/EventTable.tsx deleted file mode 100644 index b0d0a13d..00000000 --- a/components/event/EventTable.tsx +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { - HStack, - Input, - Table, - Thead, - Tbody, - Tr, - Th, - Td, - TableContainer, - useToast, - Box, - Button, - Modal, - ModalBody, - ModalCloseButton, - ModalContent, - ModalFooter, - ModalHeader, - ModalOverlay, - useDisclosure, - Select, - VStack, - Textarea, -} from '@chakra-ui/react'; -import axios from 'axios'; -import { useContext, useEffect, useState } from 'react'; -import { CloudEvent } from 'cloudevents'; -import { AppContext } from '../../context/context'; - -interface Topic { - name: string, - messageCount: number, -} - -interface EventProps { - event: CloudEvent, -} - -interface CreateEventRequest { - event: CloudEvent, -} - -const CreateEventModal = () => { - const { state } = useContext(AppContext); - - const { isOpen, onOpen, onClose } = useDisclosure(); - - const [id, setId] = useState(''); - const handleIdChange = (event: React.FormEvent) => { - setId(event.currentTarget.value); - }; - - const [source, setSource] = useState(''); - const handleSourceChange = (event: React.FormEvent) => { - setSource(event.currentTarget.value); - }; - - const [subject, setSubject] = useState(''); - const handleSubjectChange = (event: React.FormEvent) => { - setSubject(event.currentTarget.value); - }; - - const [type, setType] = useState(''); - const handleTypeChange = (event: React.FormEvent) => { - setType(event.currentTarget.value); - }; - - const [data, setData] = useState(''); - const handleDataChange = (event: React.FormEvent) => { - setData(event.currentTarget.value); - }; - - const toast = useToast(); - const [loading, setLoading] = useState(false); - const onCreateClick = async () => { - try { - setLoading(true); - await axios.post(`${state.endpoint}/event`, new CloudEvent({ - source, - subject, - type, - data, - specversion: '1.0', - })); - onClose(); - } catch (error) { - if (axios.isAxiosError(error)) { - toast({ - title: 'Failed to publish the event', - description: error.message, - status: 'error', - duration: 3000, - isClosable: true, - }); - } - } finally { - setLoading(false); - } - }; - - return ( - <> - - - - - Create Event - - - - - - - - - - - - - - - - - - - ); -}; - -const EventRow = ({ - event, -}: EventProps) => { - const { isOpen, onOpen, onClose } = useDisclosure(); - const eventDataBase64 = event.data_base64 || ''; - const eventData = Buffer.from(eventDataBase64, 'base64').toString('utf-8'); - - return ( - <> - - - - Event Data - - - -