Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 26 additions & 54 deletions api/mesh/v1alpha1/service.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 11 additions & 15 deletions api/mesh/v1alpha1/service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,19 @@ option go_package = "github.com/apache/dubbo-admin/api/mesh/v1alpha1";
import "api/mesh/options.proto";


message Service{
option (dubbo.mesh.resource).name = "Service";
option (dubbo.mesh.resource).plural_name = "Services";
option (dubbo.mesh.resource).package = "mesh";
option (dubbo.mesh.resource).is_experimental = true;
message Service{
option (dubbo.mesh.resource).name = "Service";
option (dubbo.mesh.resource).plural_name = "Services";
option (dubbo.mesh.resource).package = "mesh";
option (dubbo.mesh.resource).is_experimental = true;

string name = 1;

string group = 2;

string version = 3;

string language = 4;

repeated string providers = 5;

repeated string consumers = 6;

map<string, string> features = 99;
}
string version = 3;

string language = 4;

repeated string methods = 5;
}
17 changes: 17 additions & 0 deletions pkg/console/handler/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,23 @@ func ApplicationSearch(ctx consolectx.Context) gin.HandlerFunc {
}
}

func GetApplicationGraph(ctx consolectx.Context) gin.HandlerFunc {
return func(c *gin.Context) {
req := model.NewApplicationGraphReq()
if err := c.ShouldBindQuery(req); err != nil {
util.HandleArgumentError(c, err)
return
}

resp, err := service.GraphApplications(ctx, req)
if err != nil {
util.HandleServiceError(c, err)
return
}
c.JSON(http.StatusOK, model.NewSuccessResp(resp))
}
}

func ApplicationConfigAccessLogPut(ctx consolectx.Context) gin.HandlerFunc {
return func(c *gin.Context) {
appName := c.Query("appName")
Expand Down
58 changes: 58 additions & 0 deletions pkg/console/handler/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,3 +306,61 @@ func ServiceConfigArgumentRoutePUT(ctx consolectx.Context) gin.HandlerFunc {
c.JSON(http.StatusOK, model.NewSuccessResp(nil))
}
}

// GetServiceGraph returns the service graph as graph data (nodes and edges) for visualization
func GetServiceGraph(ctx consolectx.Context) gin.HandlerFunc {
return func(c *gin.Context) {
req := &model.ServiceGraphReq{}
if err := c.ShouldBindQuery(req); err != nil {
c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error()))
return
}

resp, err := service.GraphServices(ctx, req)
if err != nil {
util.HandleServiceError(c, err)
return
}

c.JSON(http.StatusOK, model.NewSuccessResp(resp))
}
}

// GetServiceDetail returns service detail information
func GetServiceDetail(ctx consolectx.Context) gin.HandlerFunc {
return func(c *gin.Context) {
req := &model.ServiceDetailReq{}
if err := c.ShouldBindQuery(req); err != nil {
c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error()))
return
}

resp, err := service.GetServiceDetail(ctx, req)
if err != nil {
util.HandleServiceError(c, err)
return
}

c.JSON(http.StatusOK, model.NewSuccessResp(resp))
}
}

// GetServiceInterfaces returns service interfaces information
func GetServiceInterfaces(ctx consolectx.Context) gin.HandlerFunc {
// return func(c *gin.Context) {
// req := &model.ServiceInterfacesReq{}
// if err := c.ShouldBindQuery(req); err != nil {
// c.JSON(http.StatusBadRequest, model.NewErrorResp(err.Error()))
// return
// }

// resp, err := service.GetServiceInterfaces(ctx, req)
// if err != nil {
// util.HandleServiceError(c, err)
// return
// }

// c.JSON(http.StatusOK, model.NewSuccessResp(resp))
// }
return nil
}
17 changes: 17 additions & 0 deletions pkg/console/model/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,23 @@ func NewApplicationSearchReq() *ApplicationSearchReq {
}
}

type ApplicationGraphReq struct {
coremodel.PageReq

AppName string `form:"appName" json:"appName"`
Keywords string `form:"keywords" json:"keywords"`
Mesh string `form:"mesh" json:"mesh"`
}

func NewApplicationGraphReq() *ApplicationGraphReq {
return &ApplicationGraphReq{
PageReq: coremodel.PageReq{
PageOffset: 0,
PageSize: 15,
},
}
}

type ApplicationSearchResp struct {
AppName string `json:"appName"`
DeployClusters []string `json:"deployClusters"`
Expand Down
73 changes: 73 additions & 0 deletions pkg/console/model/graph.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* 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.
*/

package model

import (
meshresource "github.com/apache/dubbo-admin/pkg/core/resource/apis/mesh/v1alpha1"

"github.com/apache/dubbo-admin/pkg/common/constants"
)

// GraphNode represents a node in the graph for AntV G6
type GraphNode struct {
ID string `json:"id"`
Label string `json:"label"`
Type string `json:"type"` // "application" or "service"
Rule string `json:"rule"` // "provider", "consumer", or ""
Data interface{} `json:"data,omitempty"`
}

// GraphEdge represents an edge in the graph for AntV G6
type GraphEdge struct {
Source string `json:"source"`
Target string `json:"target"`
Data map[string]interface{} `json:"data,omitempty"` // Additional data for the edge
}

// GraphData represents the complete graph structure for AntV G6
type GraphData struct {
Nodes []GraphNode `json:"nodes"`
Edges []GraphEdge `json:"edges"`
}

// CrossNode represents a node in the cross-linked list structure
type CrossNode struct {
Instance *meshresource.InstanceResource
Next *CrossNode // pointer to next node in the same row
Down *CrossNode // pointer to next node in the same column
}

// CrossLinkedListGraph represents the cross-linked list structure as a directed graph
type CrossLinkedListGraph struct {
Head *CrossNode
Rows int // number of rows
Cols int // number of columns
}

// ServiceGraphReq represents the request parameters for fetching the service graph
type ServiceGraphReq struct {
Mesh string `json:"mesh" form:"mesh" binding:"required"`
ServiceName string `json:"serviceName" form:"serviceName" binding:"required"`
Version string `json:"version" form:"version"`
Group string `json:"group" form:"group"`
}

// ServiceKey returns the unique service identifier
func (s *ServiceGraphReq) ServiceKey() string {
return s.ServiceName + constants.ColonSeparator + s.Version + constants.ColonSeparator + s.Group
}
9 changes: 4 additions & 5 deletions pkg/console/model/observability.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,10 @@ type InstanceDashboardReq struct {
}

type ServiceDashboardReq struct {
ServiceName string `form:"serviceName"`
Version string `form:"version"`
Group string `form:"group"`
ProviderAppName string `form:"providerAppName"`
Mesh string `form:"mesh"`
ServiceName string `form:"serviceName"`
Version string `form:"version"`
Group string `form:"group"`
Mesh string `form:"mesh"`
}

type DashboardResp struct {
Expand Down
Loading
Loading