-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
301 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
package client | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/emicklei/go-restful/v3" | ||
restfulspec "github.com/polarismesh/go-restful-openapi/v2" | ||
|
||
"github.com/polaris-contrib/polaris-server-remote-plugin-common/log" | ||
) | ||
|
||
// Resource plugin client resources handler. | ||
type Resource struct { | ||
} | ||
|
||
// NewResource returns a new Resource | ||
func NewResource() *Resource { | ||
return &Resource{} | ||
} | ||
|
||
// Plugin plugin model | ||
type Plugin struct { | ||
Name string `json:"name"` | ||
Path string `json:"path"` | ||
Config *Config `json:"config"` | ||
} | ||
|
||
// WebService return restful web service | ||
func (resource *Resource) WebService() *restful.WebService { | ||
ws := new(restful.WebService) | ||
ws.Path("/admin/plugins").Consumes(restful.MIME_JSON).Produces(restful.MIME_JSON) | ||
tags := []string{"plugin"} | ||
|
||
ws.Route( | ||
ws.GET("").To(resource.findAll). | ||
Doc("get all plugin"). | ||
Metadata(restfulspec.KeyOpenAPITags, tags). | ||
Writes([]Plugin{}). | ||
Returns(200, "OK", []Plugin{}). | ||
DefaultReturns("OK", []Plugin{}), | ||
) | ||
|
||
ws.Route( | ||
ws.PUT("{name}/disable").To(resource.disable). | ||
Doc("disable the given name plugin"). | ||
Metadata(restfulspec.KeyOpenAPITags, tags). | ||
Returns(200, "OK", nil). | ||
DefaultReturns("OK", nil), | ||
) | ||
|
||
ws.Route( | ||
ws.PUT("{name}/enable").To(resource.disable). | ||
Doc("enable the given name plugin"). | ||
Metadata(restfulspec.KeyOpenAPITags, tags). | ||
Returns(200, "OK", nil). | ||
DefaultReturns("OK", nil), | ||
) | ||
|
||
return ws | ||
} | ||
|
||
// findAll find and return all plugins | ||
// | ||
// GET http://localhost:9050/admin/plugins | ||
func (resource *Resource) findAll(_ *restful.Request, res *restful.Response) { | ||
var plugins []Plugin | ||
for name, plugin := range factory.pluginSet { | ||
plugins = append(plugins, Plugin{ | ||
Name: name, | ||
Path: plugin.pluginPath, | ||
Config: plugin.config, | ||
}) | ||
} | ||
_ = res.WriteEntity(plugins) | ||
} | ||
|
||
// disable disable one plugin by plugin name. | ||
// | ||
// PUT http://localhost:9050/admin/plugins/{name}/disable | ||
func (resource *Resource) disable(req *restful.Request, res *restful.Response) { | ||
name := req.PathParameter("name") | ||
if name == "" { | ||
responseError(res, 400, fmt.Errorf("plugin name is required")) | ||
return | ||
} | ||
|
||
plugin := factory.Get(name) | ||
if plugin == nil { | ||
responseError(res, 404, fmt.Errorf("plugin with name %s is not exists", name)) | ||
return | ||
} | ||
|
||
err := plugin.Disable() | ||
if err != nil { | ||
responseError(res, 500, fmt.Errorf("fail to disable plugin: %w", err)) | ||
return | ||
} | ||
|
||
_ = res.WriteEntity(map[string]interface{}{"success": "true"}) | ||
return | ||
} | ||
|
||
// enable enable one plugin by plugin name. | ||
// | ||
// PUT http://localhost:9050/admin/plugins/{name}/enable | ||
func (resource *Resource) enable(req *restful.Request, res *restful.Response) { | ||
name := req.PathParameter("name") | ||
if name == "" { | ||
responseError(res, 400, fmt.Errorf("plugin name is required")) | ||
return | ||
} | ||
|
||
plugin := factory.Get(name) | ||
if plugin == nil { | ||
responseError(res, 404, fmt.Errorf("plugin with name %s is not exists", name)) | ||
return | ||
} | ||
|
||
err := plugin.Open() | ||
if err != nil { | ||
responseError(res, 500, fmt.Errorf("fail to enable plugin: %w", err)) | ||
return | ||
} | ||
_ = res.WriteEntity(map[string]interface{}{"success": "true"}) | ||
return | ||
} | ||
|
||
// ResError error response | ||
type ResError struct { | ||
Err error `json:"err"` | ||
} | ||
|
||
func responseError(res *restful.Response, code int, err error) { | ||
log.Error("admin api returns a error response", "error_response", err) | ||
_ = res.WriteHeaderAndJson(code, map[string]interface{}{"error": err.Error()}, restful.MIME_JSON) | ||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
package client | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
"os" | ||
"os/exec" | ||
"testing" | ||
|
||
"github.com/emicklei/go-restful/v3" | ||
|
||
"github.com/polaris-contrib/polaris-server-remote-plugin-common/log" | ||
) | ||
|
||
func TestMain(m *testing.M) { | ||
cmd := &exec.Cmd{ | ||
Path: "/usr/bin/make", | ||
Args: append([]string{"/usr/bin/make"}, "build"), | ||
Dir: "../", | ||
} | ||
|
||
err := cmd.Run() | ||
if err != nil { | ||
log.Fatal("got error", "error", err.Error()) | ||
os.Exit(-1) | ||
} | ||
|
||
m.Run() | ||
} | ||
|
||
// TestAdminAPI 测试 API server | ||
func TestAdminAPI(t *testing.T) { | ||
if _, err := Register( | ||
&Config{ | ||
Name: "remote-rate-limit-server-v1", | ||
Mode: RumModelLocal, | ||
Local: LocalConfig{ | ||
MaxProcs: 1, | ||
Path: "../remote-rate-limit-server-v1", | ||
}, | ||
}, | ||
); err != nil { | ||
log.Fatal("server-v1 register failed", "error", err.Error()) | ||
return | ||
} | ||
|
||
if _, err := Register( | ||
&Config{ | ||
Name: "remote-rate-limit-server-v2", | ||
Mode: RumModelLocal, | ||
Local: LocalConfig{ | ||
Path: "../remote-rate-limit-server-v2", | ||
}, | ||
}, | ||
); err != nil { | ||
log.Fatal("server-v2 register failed", "error", err.Error()) | ||
} | ||
|
||
restful.DefaultContainer.Add(NewResource().WebService()) | ||
adminPort := 9050 | ||
|
||
log.Info(fmt.Sprintf("request the admin api using http://localhost:%d", adminPort)) | ||
if err := http.ListenAndServe(fmt.Sprintf(":%d", adminPort), nil); err != nil { | ||
log.Fatal("plugin admin serve error", "error", err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.