From d78864feaebb1094880f12102e31cbd2d3a8ea0e Mon Sep 17 00:00:00 2001 From: zhulijian Date: Sun, 8 Mar 2020 22:56:11 +0800 Subject: [PATCH] remove kie client --- README.md | 2 +- client/client.go | 279 ------------------------------------------ client/client_test.go | 122 ------------------ client/options.go | 96 --------------- 4 files changed, 1 insertion(+), 498 deletions(-) delete mode 100644 client/client.go delete mode 100644 client/client_test.go delete mode 100644 client/options.go diff --git a/README.md b/README.md index 321e15b4..d6b9f336 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ by setting different labels to a key. it includes 5 components - server: rest api service to manage kv -- client: restful client for go +- [kieclient](https://github.com/go-chassis/go-archaius/tree/master/pkg/kieclient): go clients for talking to a kie server - kie-template: agent can be deployed in your k8s pod or VM, it connects to server and writes kv into config file based on template language diff --git a/client/client.go b/client/client.go deleted file mode 100644 index 422a5373..00000000 --- a/client/client.go +++ /dev/null @@ -1,279 +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. - */ - -package client - -import ( - "context" - "crypto/tls" - "encoding/json" - "errors" - "fmt" - "net/http" - "net/url" - "strconv" - "strings" - - "github.com/apache/servicecomb-kie/pkg/common" - "github.com/apache/servicecomb-kie/pkg/model" - "github.com/go-chassis/foundation/httpclient" - "github.com/go-chassis/foundation/security" - "github.com/go-chassis/go-chassis/pkg/util/httputil" - "github.com/go-mesh/openlogging" -) - -//const -const ( - version = "v1" - APIPathKV = "kie/kv" - - HeaderContentType = "Content-Type" - MsgGetFailed = "get failed" - FmtGetFailed = "get %s failed,http status [%s], body [%s]" -) - -//client errors -var ( - ErrKeyNotExist = errors.New("can not find value") - ErrNoChanges = errors.New("kv has not been changed since last polling") -) - -//Client is the servicecomb kie rest client. -//it is concurrency safe -type Client struct { - opts Config - cipher security.Cipher - c *httpclient.Requests - currentRevision int -} - -//Config is the config of client -type Config struct { - Endpoint string - DefaultLabels map[string]string - VerifyPeer bool //TODO make it works, now just keep it false -} - -//New create a client -func New(config Config) (*Client, error) { - u, err := url.Parse(config.Endpoint) - if err != nil { - return nil, err - } - httpOpts := &httpclient.Options{} - if u.Scheme == "https" { - // #nosec - httpOpts.TLSConfig = &tls.Config{ - InsecureSkipVerify: !config.VerifyPeer, - } - } - c, err := httpclient.New(httpOpts) - if err != nil { - return nil, err - } - return &Client{ - opts: config, - c: c, - }, nil -} - -//Put create value of a key -func (c *Client) Put(ctx context.Context, kv model.KVRequest, opts ...OpOption) (*model.KVDoc, error) { - options := OpOptions{} - for _, o := range opts { - o(&options) - } - if options.Project == "" { - options.Project = defaultProject - } - url := fmt.Sprintf("%s/%s/%s/%s/%s", c.opts.Endpoint, version, options.Project, APIPathKV, kv.Key) - h := http.Header{} - h.Set(HeaderContentType, common.ContentTypeJSON) - body, _ := json.Marshal(kv) - resp, err := c.c.Do(ctx, http.MethodPut, url, h, body) - if err != nil { - return nil, err - } - b := httputil.ReadBody(resp) - if resp.StatusCode != http.StatusOK { - openlogging.Error(MsgGetFailed, openlogging.WithTags(openlogging.Tags{ - "k": kv.Key, - "status": resp.Status, - "body": b, - })) - return nil, fmt.Errorf(FmtGetFailed, kv.Key, resp.Status, b) - } - - kvs := &model.KVDoc{} - err = json.Unmarshal(b, kvs) - if err != nil { - openlogging.Error("unmarshal kv failed:" + err.Error()) - return nil, err - } - return kvs, nil -} - -//Get get value of a key -func (c *Client) Get(ctx context.Context, opts ...GetOption) (*model.KVResponse, int, error) { - options := GetOptions{} - for _, o := range opts { - o(&options) - } - if options.Project == "" { - options.Project = defaultProject - } - if options.Revision == "" { - options.Revision = strconv.Itoa(c.currentRevision) - } - var url string - if options.Key != "" { - url = fmt.Sprintf("%s/%s/%s/%s/%s?revision=%s", c.opts.Endpoint, version, options.Project, APIPathKV, options.Key, options.Revision) - } else { - url = fmt.Sprintf("%s/%s/%s/%s?revision=%s", c.opts.Endpoint, version, options.Project, APIPathKV, options.Revision) - } - if options.Wait != "" { - url = url + "&wait=" + options.Wait - } - if options.Exact { - url = url + "&" + common.QueryParamMatch + "=exact" - } - labels := "" - if len(options.Labels) != 0 { - for k, v := range options.Labels[0] { - labels = labels + "&label=" + k + ":" + v - } - url = url + labels - } - h := http.Header{} - resp, err := c.c.Do(ctx, http.MethodGet, url, h, nil) - if err != nil { - return nil, -1, err - } - responseRevision, err := strconv.Atoi(resp.Header.Get(common.HeaderRevision)) - if err != nil { - responseRevision = -1 - } - b := httputil.ReadBody(resp) - if resp.StatusCode != http.StatusOK { - if resp.StatusCode == http.StatusNotFound { - return nil, responseRevision, ErrKeyNotExist - } - if resp.StatusCode == http.StatusNotModified { - return nil, responseRevision, ErrNoChanges - } - openlogging.Error(MsgGetFailed, openlogging.WithTags(openlogging.Tags{ - "k": options.Key, - "status": resp.Status, - "body": b, - })) - return nil, responseRevision, fmt.Errorf(FmtGetFailed, options.Key, resp.Status, b) - } else if err != nil { - msg := fmt.Sprintf("get revision from response header failed when the request status is OK: %v", err) - openlogging.Error(msg) - return nil, responseRevision, fmt.Errorf(msg) - } - var kvs *model.KVResponse - err = json.Unmarshal(b, &kvs) - if err != nil { - openlogging.Error("unmarshal kv failed:" + err.Error()) - return nil, responseRevision, err - } - c.currentRevision = responseRevision - return kvs, responseRevision, nil -} - -//Summary get value by labels -func (c *Client) Summary(ctx context.Context, opts ...GetOption) ([]*model.KVResponse, error) { - options := GetOptions{} - for _, o := range opts { - o(&options) - } - if options.Project == "" { - options.Project = defaultProject - } - labelParams := "" - for _, labels := range options.Labels { - labelParams += common.QueryParamQ + "=" - for labelKey, labelValue := range labels { - labelParams += labelKey + ":" + labelValue + "+" - } - if labels != nil && len(labels) > 0 { - labelParams = strings.TrimRight(labelParams, "+") - } - labelParams += common.QueryByLabelsCon - } - if options.Labels != nil && len(options.Labels) > 0 { - labelParams = strings.TrimRight(labelParams, common.QueryByLabelsCon) - } - url := fmt.Sprintf("%s/%s/%s/%s?%s", c.opts.Endpoint, version, options.Project, "kie/summary", labelParams) - h := http.Header{} - resp, err := c.c.Do(ctx, http.MethodGet, url, h, nil) - if err != nil { - return nil, err - } - b := httputil.ReadBody(resp) - if resp.StatusCode != http.StatusOK { - if resp.StatusCode == http.StatusNotFound { - return nil, ErrKeyNotExist - } - openlogging.Error(MsgGetFailed, openlogging.WithTags(openlogging.Tags{ - "p": options.Project, - "status": resp.Status, - "body": b, - })) - return nil, fmt.Errorf("search %s failed,http status [%s], body [%s]", labelParams, resp.Status, b) - } - var kvs []*model.KVResponse - err = json.Unmarshal(b, &kvs) - if err != nil { - openlogging.Error("unmarshal kv failed:" + err.Error()) - return nil, err - } - return kvs, nil -} - -//Delete remove kv -func (c *Client) Delete(ctx context.Context, kvID, labelID string, opts ...OpOption) error { - options := OpOptions{} - for _, o := range opts { - o(&options) - } - if options.Project == "" { - options.Project = defaultProject - } - url := fmt.Sprintf("%s/%s/%s/%s/?%s=%s", c.opts.Endpoint, version, options.Project, APIPathKV, - common.QueryParamKeyID, kvID) - if labelID != "" { - url = fmt.Sprintf("%s?labelID=%s", url, labelID) - } - h := http.Header{} - h.Set(HeaderContentType, common.ContentTypeJSON) - resp, err := c.c.Do(ctx, http.MethodDelete, url, h, nil) - if err != nil { - return err - } - b := httputil.ReadBody(resp) - if resp.StatusCode != http.StatusNoContent { - return fmt.Errorf("delete %s failed,http status [%s], body [%s]", kvID, resp.Status, b) - } - return nil -} - -//CurrentRevision return the current revision of kie, which is updated on the last get request -func (c *Client) CurrentRevision() int { - return c.currentRevision -} diff --git a/client/client_test.go b/client/client_test.go deleted file mode 100644 index 7c8fcd0b..00000000 --- a/client/client_test.go +++ /dev/null @@ -1,122 +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. - */ - -package client_test - -import ( - "context" - "github.com/stretchr/testify/assert" - "os" - "testing" - - . "github.com/apache/servicecomb-kie/client" - "github.com/apache/servicecomb-kie/pkg/model" -) - -func TestClient_Put(t *testing.T) { - os.Setenv("HTTP_DEBUG", "1") - c, _ := New(Config{ - Endpoint: "http://127.0.0.1:30110", - }) - kv := model.KVRequest{ - Key: "app.properties", - Labels: map[string]string{"service": "client"}, - Value: "timeout: 1s", - } - _, err := c.Put(context.TODO(), kv, WithProject("client_test")) - assert.NoError(t, err) - - kvs, responseRevision, _ := c.Get(context.TODO(), - WithKey("app.properties"), - WithGetProject("client_test"), - WithLabels(map[string]string{"service": "client"})) - assert.GreaterOrEqual(t, len(kvs.Data), 1) - - _, _, err = c.Get(context.TODO(), - WithGetProject("client_test"), - WithLabels(map[string]string{"service": "client"}), - WithRevision(responseRevision)) - assert.Equal(t, ErrNoChanges, err) - - _, _, err = c.Get(context.TODO(), - WithGetProject("client_test"), - WithLabels(map[string]string{"service": "client"})) - assert.Error(t, err) - - _, _, err = c.Get(context.TODO(), - WithGetProject("client_test"), - WithLabels(map[string]string{"service": "client"}), - WithRevision(c.CurrentRevision()-1)) - assert.NoError(t, err) - - t.Run("long polling,wait 10s,change value,should return result", func(t *testing.T) { - go func() { - kvs, _, err = c.Get(context.TODO(), - WithLabels(map[string]string{"service": "client"}), - WithGetProject("client_test"), - WithWait("10s")) - assert.NoError(t, err) - assert.Equal(t, "timeout: 2s", kvs.Data[0].Value) - }() - kv := model.KVRequest{ - Key: "app.properties", - Labels: map[string]string{"service": "client"}, - Value: "timeout: 2s", - } - _, err := c.Put(context.TODO(), kv, WithProject("client_test")) - assert.NoError(t, err) - }) - t.Run("exact match", func(t *testing.T) { - kv := model.KVRequest{ - Key: "app.properties", - Labels: map[string]string{"service": "client", "version": "1.0"}, - Value: "timeout: 2s", - } - _, err := c.Put(context.TODO(), kv, WithProject("client_test")) - assert.NoError(t, err) - t.Log(c.CurrentRevision()) - kvs, _, err = c.Get(context.TODO(), - WithGetProject("client_test"), - WithLabels(map[string]string{"service": "client"}), - WithExact()) - assert.NoError(t, err) - assert.Equal(t, 1, len(kvs.Data)) - }) - -} -func TestClient_Delete(t *testing.T) { - c, err := New(Config{ - Endpoint: "http://127.0.0.1:30110", - }) - - kvBody := model.KVRequest{} - kvBody.Key = "time" - kvBody.Value = "100s" - kvBody.ValueType = "text" - kvBody.Labels = make(map[string]string) - kvBody.Labels["env"] = "client_test" - kv, err := c.Put(context.TODO(), kvBody, WithProject("client_test")) - assert.NoError(t, err) - kvs, _, err := c.Get(context.TODO(), - WithKey("time"), - WithGetProject("client_test"), - WithLabels(map[string]string{"env": "client_test"})) - assert.NoError(t, err) - assert.NotNil(t, kvs) - err = c.Delete(context.TODO(), kv.ID, "", WithProject("client_test")) - assert.NoError(t, err) -} diff --git a/client/options.go b/client/options.go deleted file mode 100644 index f450e33c..00000000 --- a/client/options.go +++ /dev/null @@ -1,96 +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. - */ - -package client - -import "strconv" - -const ( - defaultProject = "default" -) - -//GetOption is the functional option of client func -type GetOption func(*GetOptions) - -//OpOption is the functional option of client func -type OpOption func(*OpOptions) - -//GetOptions is the options of client func -type GetOptions struct { - Labels []map[string]string - Project string - Key string - Wait string - Exact bool - Revision string -} - -//OpOptions is the options of client func -type OpOptions struct { - Project string -} - -//WithLabels query kv by labels -func WithLabels(l ...map[string]string) GetOption { - return func(options *GetOptions) { - for _, labels := range l { - options.Labels = append(options.Labels, labels) - } - } -} - -//WithGetProject query keys with certain project -func WithGetProject(project string) GetOption { - return func(options *GetOptions) { - options.Project = project - } -} - -//WithExact means label exact match -func WithExact() GetOption { - return func(options *GetOptions) { - options.Exact = true - } -} - -//WithWait is for long polling,format is 1s,2m -func WithWait(duration string) GetOption { - return func(options *GetOptions) { - options.Wait = duration - } -} - -//WithKey query keys with certain key -func WithKey(k string) GetOption { - return func(options *GetOptions) { - options.Key = k - } -} - -//WithRevision query keys with certain revision -func WithRevision(revision int) GetOption { - return func(options *GetOptions) { - options.Revision = strconv.Itoa(revision) - } -} - -//WithProject set project to param -func WithProject(project string) OpOption { - return func(options *OpOptions) { - options.Project = project - } -}