github.com/erda-project/erda-infra@v1.0.9/providers/component-protocol/protocol/component_wrapper.go (about)

     1  // Copyright (c) 2021 Terminus, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package protocol
    16  
    17  import (
    18  	"context"
    19  	"encoding/json"
    20  	"reflect"
    21  
    22  	"github.com/erda-project/erda-infra/providers/component-protocol/cptype"
    23  )
    24  
    25  func wrapCompRender(cr CompRender, ver string) CompRender {
    26  	// 没版本的原始代码
    27  	if ver == "" {
    28  		return cr
    29  	}
    30  	return &compRenderWrapper{cr: cr}
    31  }
    32  
    33  type compRenderWrapper struct {
    34  	cr CompRender
    35  }
    36  
    37  // Render .
    38  func (w *compRenderWrapper) Render(ctx context.Context, c *cptype.Component, scenario cptype.Scenario, event cptype.ComponentEvent, gs *cptype.GlobalStateData) (err error) {
    39  	if err = unmarshal(&w.cr, c); err != nil {
    40  		return
    41  	}
    42  	defer func() {
    43  		if err != nil {
    44  			// not marshal invoke fail
    45  			return
    46  		}
    47  		err = marshal(&w.cr, c)
    48  	}()
    49  	err = w.cr.Render(ctx, c, scenario, event, gs)
    50  	return
    51  }
    52  
    53  func unmarshal(cr *CompRender, c *cptype.Component) error {
    54  	v, err := json.Marshal(c)
    55  	if err != nil {
    56  		return err
    57  	}
    58  	return json.Unmarshal(v, cr)
    59  }
    60  
    61  func marshal(cr *CompRender, c *cptype.Component) error {
    62  	var tmp cptype.Component
    63  	v, err := json.Marshal(cr)
    64  	if err != nil {
    65  		return err
    66  	}
    67  	err = json.Unmarshal(v, &tmp)
    68  	if err != nil {
    69  		return err
    70  	}
    71  	tr := reflect.TypeOf(*cr).Elem()
    72  	fields := getAllFields(c)
    73  	for _, fieldName := range fields {
    74  		if f, ok := tr.FieldByName(fieldName); ok {
    75  			if tag := f.Tag.Get("json"); tag == "-" {
    76  				continue
    77  			}
    78  			switch fieldName {
    79  			case "Version":
    80  				c.Version = tmp.Version
    81  			case "Type":
    82  				c.Type = tmp.Type
    83  			case "Name":
    84  				c.Name = tmp.Name
    85  			case "Props":
    86  				c.Props = tmp.Props
    87  			case "Data":
    88  				c.Data = tmp.Data
    89  			case "State":
    90  				c.State = tmp.State
    91  			case "Operations":
    92  				c.Operations = tmp.Operations
    93  			}
    94  		}
    95  	}
    96  	return nil
    97  }
    98  
    99  func getAllFields(o interface{}) (f []string) {
   100  	t := reflect.TypeOf(o)
   101  	if t.Kind() == reflect.Ptr {
   102  		t = t.Elem()
   103  	}
   104  	for i := 0; i < t.NumField(); i++ {
   105  		f = append(f, t.Field(i).Name)
   106  	}
   107  	return
   108  }