github.com/whiteboxio/flow@v0.0.3-0.20190918184116-508d75d68a2c/pkg/cast/types.go (about)

     1  package cast
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  	"strings"
     7  
     8  	"github.com/awesome-flow/flow/pkg/types"
     9  )
    10  
    11  // CfgMapper is the root-level system config encorporating the primary config
    12  // blocks, as: system, components and pipeline.
    13  type CfgMapper struct{}
    14  
    15  var _ Mapper = (*CfgMapper)(nil)
    16  
    17  func errUnknownValType(castType string, kv *types.KeyValue) error {
    18  	return fmt.Errorf("%s cast failed for key: %q, val: %#v: unknown value type", castType, kv.Key, kv.Value)
    19  }
    20  
    21  func errUnknownKeys(castType string, kv *types.KeyValue, unknown map[string]struct{}) error {
    22  	unknownArr := make([]string, 0, len(unknown))
    23  	for k := range unknown {
    24  		unknownArr = append(unknownArr, k)
    25  	}
    26  	sort.Strings(unknownArr)
    27  	return fmt.Errorf("%s cast failed for key: %q: unknown attributes: [%s]", castType, kv.Key, strings.Join(unknownArr, ", "))
    28  }
    29  
    30  // Map converts map[string]Value to types.Cfg{} structure.
    31  // Lookup keys are:
    32  // * components
    33  // * pipeline
    34  // * system
    35  // No extra keys are allowed under this section.
    36  func (*CfgMapper) Map(kv *types.KeyValue) (*types.KeyValue, error) {
    37  	var resKV *types.KeyValue
    38  	var err error
    39  	if vmap, ok := kv.Value.(map[string]types.Value); ok {
    40  		res := types.Cfg{}
    41  		keys := make(map[string]struct{})
    42  		for k := range vmap {
    43  			keys[k] = struct{}{}
    44  		}
    45  		if components, ok := vmap["actors"]; ok {
    46  			delete(keys, "actors")
    47  			res.Actors = components.(map[string]types.CfgBlockActor)
    48  		}
    49  		if pipeline, ok := vmap["pipeline"]; ok {
    50  			delete(keys, "pipeline")
    51  			res.Pipeline = pipeline.(map[string]types.CfgBlockPipeline)
    52  		}
    53  		if system, ok := vmap["system"]; ok {
    54  			delete(keys, "system")
    55  			res.System = system.(types.CfgBlockSystem)
    56  		}
    57  		if len(keys) > 0 {
    58  			err = errUnknownKeys("Cfg", kv, keys)
    59  		} else {
    60  			resKV = &types.KeyValue{Key: kv.Key, Value: res}
    61  		}
    62  	} else {
    63  		err = errUnknownValType("Cfg", kv)
    64  	}
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  	return resKV, nil
    69  }
    70  
    71  //============================================================================//
    72  
    73  // CfgBlockSystemMapper represents the system config section.
    74  type CfgBlockSystemMapper struct{}
    75  
    76  var _ Mapper = (*CfgBlockSystemMapper)(nil)
    77  
    78  // Map converts map[string]Value to types.CfgBlockSystem{} structure.
    79  // Lookup keys are:
    80  // * maxprocs
    81  // * admin
    82  // * metrics
    83  // No extra keys are allowed under this section.
    84  func (*CfgBlockSystemMapper) Map(kv *types.KeyValue) (*types.KeyValue, error) {
    85  	var resKV *types.KeyValue
    86  	var err error
    87  	if vmap, ok := kv.Value.(map[string]types.Value); ok {
    88  		res := types.CfgBlockSystem{}
    89  		keys := make(map[string]struct{})
    90  		for k := range vmap {
    91  			keys[k] = struct{}{}
    92  		}
    93  		if maxprocs, ok := vmap["maxprocs"]; ok {
    94  			delete(keys, "maxprocs")
    95  			res.Maxprocs = maxprocs.(int)
    96  		}
    97  		if admin, ok := vmap["admin"]; ok {
    98  			delete(keys, "admin")
    99  			res.Admin = admin.(types.CfgBlockSystemAdmin)
   100  		}
   101  		if metrics, ok := vmap["metrics"]; ok {
   102  			delete(keys, "metrics")
   103  			res.Metrics = metrics.(types.CfgBlockSystemMetrics)
   104  		}
   105  		if len(keys) > 0 {
   106  			err = errUnknownKeys("CfgBlockSystem", kv, keys)
   107  		} else {
   108  			resKV = &types.KeyValue{Key: kv.Key, Value: res}
   109  		}
   110  	} else {
   111  		err = errUnknownValType("CfgBlockSystem", kv)
   112  	}
   113  	if err != nil {
   114  		return nil, err
   115  	}
   116  	return resKV, nil
   117  }
   118  
   119  //============================================================================//
   120  
   121  // CfgBlockSystemAdminMapper represents a mapper for system.admin config section.
   122  type CfgBlockSystemAdminMapper struct{}
   123  
   124  var _ Mapper = (*CfgBlockSystemAdminMapper)(nil)
   125  
   126  // Map converts map[string]Value to types.CfgBlockSystemAdmin{} structure.
   127  // Lookup keys are:
   128  // * enabled
   129  // * bind_addr
   130  // No extra keys are allowed under this section.
   131  func (*CfgBlockSystemAdminMapper) Map(kv *types.KeyValue) (*types.KeyValue, error) {
   132  	var resKV *types.KeyValue
   133  	var err error
   134  	if vmap, ok := kv.Value.(map[string]types.Value); ok {
   135  		res := types.CfgBlockSystemAdmin{}
   136  		keys := make(map[string]struct{})
   137  		for k := range vmap {
   138  			keys[k] = struct{}{}
   139  		}
   140  		if enabled, ok := vmap["enabled"]; ok {
   141  			delete(keys, "enabled")
   142  			res.Enabled = enabled.(bool)
   143  		}
   144  		if bind, ok := vmap["bind"]; ok {
   145  			delete(keys, "bind")
   146  			res.Bind = bind.(string)
   147  		}
   148  		if len(keys) > 0 {
   149  			err = errUnknownKeys("CfgBlockSystemAdmin", kv, keys)
   150  		} else {
   151  			resKV = &types.KeyValue{Key: kv.Key, Value: res}
   152  		}
   153  	} else {
   154  		err = errUnknownValType("CfgBlockSystemAdmin", kv)
   155  	}
   156  	if err != nil {
   157  		return nil, err
   158  	}
   159  	return resKV, nil
   160  }
   161  
   162  //============================================================================//
   163  
   164  // CfgBlockSystemMetricsMapper represents a mapper for system.metrics section.
   165  type CfgBlockSystemMetricsMapper struct{}
   166  
   167  var _ Mapper = (*CfgBlockSystemMetricsMapper)(nil)
   168  
   169  // Map converts map[string]Value to types.CfgBlockSystemMetrics{} structure.
   170  // Lookup keys are:
   171  // * enabled
   172  // * interval
   173  // * receiver
   174  // No extra keys are allowed in this section.
   175  func (*CfgBlockSystemMetricsMapper) Map(kv *types.KeyValue) (*types.KeyValue, error) {
   176  	var resKV *types.KeyValue
   177  	var err error
   178  	if vmap, ok := kv.Value.(map[string]types.Value); ok {
   179  		res := types.CfgBlockSystemMetrics{}
   180  		keys := make(map[string]struct{})
   181  		for k := range vmap {
   182  			keys[k] = struct{}{}
   183  		}
   184  		if enabled, ok := vmap["enabled"]; ok {
   185  			delete(keys, "enabled")
   186  			res.Enabled = enabled.(bool)
   187  		}
   188  		if interval, ok := vmap["interval"]; ok {
   189  			delete(keys, "interval")
   190  			res.Interval = interval.(int)
   191  		}
   192  		if receiver, ok := vmap["receiver"]; ok {
   193  			delete(keys, "receiver")
   194  			res.Receiver = receiver.(types.CfgBlockSystemMetricsReceiver)
   195  		}
   196  		if len(keys) > 0 {
   197  			err = errUnknownKeys("CfgBlockSystemMetrics", kv, keys)
   198  		} else {
   199  			resKV = &types.KeyValue{Key: kv.Key, Value: res}
   200  		}
   201  	} else {
   202  		err = errUnknownValType("CfgBlockSystemMetrics", kv)
   203  	}
   204  	if err != nil {
   205  		return nil, err
   206  	}
   207  	return resKV, nil
   208  }
   209  
   210  //============================================================================//
   211  
   212  // CfgBlockSystemMetricsReceiverMapper represents a mapper for
   213  // system.metrics.receiver section.
   214  type CfgBlockSystemMetricsReceiverMapper struct{}
   215  
   216  var _ Mapper = (*CfgBlockSystemMetricsReceiverMapper)(nil)
   217  
   218  // Map convers map[string]Value to types.CfgBlockSystemMetricsReceiver{} structure.
   219  // Lookup keys are:
   220  // * type
   221  // * params
   222  // No extra keys are allowed in this section.
   223  func (*CfgBlockSystemMetricsReceiverMapper) Map(kv *types.KeyValue) (*types.KeyValue, error) {
   224  	var resKV *types.KeyValue
   225  	var err error
   226  	if vmap, ok := kv.Value.(map[string]types.Value); ok {
   227  		res := types.CfgBlockSystemMetricsReceiver{}
   228  		keys := make(map[string]struct{})
   229  		for k := range vmap {
   230  			keys[k] = struct{}{}
   231  		}
   232  		if tp, ok := vmap["type"]; ok {
   233  			delete(keys, "type")
   234  			res.Type = tp.(string)
   235  		}
   236  		if params, ok := vmap["params"]; ok {
   237  			delete(keys, "params")
   238  			res.Params = params.(map[string]types.Value)
   239  		}
   240  		if len(keys) > 0 {
   241  			err = errUnknownKeys("CfgBlockSystemMetricsReceiver", kv, keys)
   242  		} else {
   243  			resKV = &types.KeyValue{Key: kv.Key, Value: res}
   244  		}
   245  	} else {
   246  		err = errUnknownValType("CfgBlockSystemMetricsReceiver", kv)
   247  	}
   248  	if err != nil {
   249  		return nil, err
   250  	}
   251  	return resKV, nil
   252  }
   253  
   254  //============================================================================//
   255  
   256  // MapCfgBlockActorMapper represents a mapper for components config section.
   257  type MapCfgBlockActorMapper struct{}
   258  
   259  var _ Mapper = (*MapCfgBlockActorMapper)(nil)
   260  
   261  // Map converts map[string]Value to map[string]types.CfgBlockActor.
   262  // All keys from the original map will be kept in the resulting structure.
   263  func (*MapCfgBlockActorMapper) Map(kv *types.KeyValue) (*types.KeyValue, error) {
   264  	if vmap, ok := kv.Value.(map[string]types.Value); ok {
   265  		res := make(map[string]types.CfgBlockActor)
   266  		for k, v := range vmap {
   267  			res[k] = v.(types.CfgBlockActor)
   268  		}
   269  		return &types.KeyValue{Key: kv.Key, Value: res}, nil
   270  	}
   271  	return nil, errUnknownValType("map[string]CfgBlockActor", kv)
   272  }
   273  
   274  //============================================================================//
   275  
   276  // CfgBlockActorMapper represents a mapper for components.* config section.
   277  type CfgBlockActorMapper struct{}
   278  
   279  var _ Mapper = (*CfgBlockActorMapper)(nil)
   280  
   281  // Map converts map[string]Value to types.CfgBlockActor{}.
   282  // Lookup keys are:
   283  // * constructor
   284  // * module
   285  // * params
   286  // No extra keys are allowed in this section.
   287  func (*CfgBlockActorMapper) Map(kv *types.KeyValue) (*types.KeyValue, error) {
   288  	var resKV *types.KeyValue
   289  	var err error
   290  	if vmap, ok := kv.Value.(map[string]types.Value); ok {
   291  		res := types.CfgBlockActor{}
   292  		keys := make(map[string]struct{})
   293  		for k := range vmap {
   294  			keys[k] = struct{}{}
   295  		}
   296  		if builder, ok := vmap["builder"]; ok {
   297  			delete(keys, "builder")
   298  			res.Builder = builder.(string)
   299  		}
   300  		if module, ok := vmap["module"]; ok {
   301  			delete(keys, "module")
   302  			res.Module = module.(string)
   303  		}
   304  		if params, ok := vmap["params"]; ok {
   305  			delete(keys, "params")
   306  			res.Params = params.(map[string]types.Value)
   307  		}
   308  		if len(keys) > 0 {
   309  			err = errUnknownKeys("CfgBlockActor", kv, keys)
   310  		} else {
   311  			resKV = &types.KeyValue{Key: kv.Key, Value: res}
   312  		}
   313  	} else {
   314  		err = errUnknownValType("CfgBlockActor", kv)
   315  	}
   316  	if err != nil {
   317  		return nil, err
   318  	}
   319  	return resKV, nil
   320  }
   321  
   322  //============================================================================//
   323  
   324  // MapCfgBlockPipelineMapper represents a mapper for pipeline config section.
   325  type MapCfgBlockPipelineMapper struct{}
   326  
   327  var _ Mapper = (*MapCfgBlockActorMapper)(nil)
   328  
   329  // Map converts map[string]Value to map[string]types.CfgBlockPipeline.
   330  // All keys from the original map will be kept in the resulting map.
   331  func (*MapCfgBlockPipelineMapper) Map(kv *types.KeyValue) (*types.KeyValue, error) {
   332  	if vmap, ok := kv.Value.(map[string]types.Value); ok {
   333  		res := make(map[string]types.CfgBlockPipeline)
   334  		for k, v := range vmap {
   335  			res[k] = v.(types.CfgBlockPipeline)
   336  		}
   337  		return &types.KeyValue{Key: kv.Key, Value: res}, nil
   338  	}
   339  	return nil, errUnknownValType("map[string]CfgBlockPipeline", kv)
   340  }
   341  
   342  //============================================================================//
   343  
   344  // CfgBlockPipelineMapper represents a mapper for pipeline.* config section.
   345  type CfgBlockPipelineMapper struct{}
   346  
   347  var _ Mapper = (*CfgBlockPipelineMapper)(nil)
   348  
   349  // Map converts map[string]Value to types.CfgBlockPipeline structure.
   350  // Lookup keys are:
   351  // * connect
   352  // * links
   353  // * routes
   354  // No extra keys are allowed in this section.
   355  func (*CfgBlockPipelineMapper) Map(kv *types.KeyValue) (*types.KeyValue, error) {
   356  	var resKV *types.KeyValue
   357  	var err error
   358  	if vmap, ok := kv.Value.(map[string]types.Value); ok {
   359  		res := types.CfgBlockPipeline{}
   360  		keys := make(map[string]struct{})
   361  		for k := range vmap {
   362  			keys[k] = struct{}{}
   363  		}
   364  		if connect, ok := vmap["connect"]; ok {
   365  			delete(keys, "connect")
   366  			res.Connect = connect.([]string)
   367  		}
   368  		if len(keys) > 0 {
   369  			err = errUnknownKeys("CfgBlockPipeline", kv, keys)
   370  		} else {
   371  			resKV = &types.KeyValue{Key: kv.Key, Value: res}
   372  		}
   373  	} else {
   374  		err = errUnknownValType("CfgBlockPipeline", kv)
   375  	}
   376  	if err != nil {
   377  		return nil, err
   378  	}
   379  	return resKV, nil
   380  }
   381  
   382  //============================================================================//
   383  
   384  // ArrStrMapper represents a mapper for string arrays.
   385  type ArrStrMapper struct{}
   386  
   387  var _ Mapper = (*ArrStrMapper)(nil)
   388  
   389  // Map converts string or []interface{} to []string.
   390  func (*ArrStrMapper) Map(kv *types.KeyValue) (*types.KeyValue, error) {
   391  	// []interface{}, not []Value because factual arguments are not being
   392  	// type casted
   393  	if sv, ok := kv.Value.(string); ok {
   394  		return &types.KeyValue{Key: kv.Key, Value: []string{sv}}, nil
   395  	}
   396  	if arr, ok := kv.Value.([]interface{}); ok {
   397  		res := make([]string, 0, len(arr))
   398  		for _, v := range arr {
   399  			res = append(res, v.(string))
   400  		}
   401  		return &types.KeyValue{Key: kv.Key, Value: res}, nil
   402  	}
   403  	return nil, errUnknownValType("[]string", kv)
   404  }
   405  
   406  //============================================================================//
   407  
   408  // MapStrToStrMapper represents a mapper for map[string]string maps.
   409  type MapStrToStrMapper struct{}
   410  
   411  var _ Mapper = (*MapStrToStrMapper)(nil)
   412  
   413  // Map converts from map[string]types.Value to map[string]string.
   414  func (*MapStrToStrMapper) Map(kv *types.KeyValue) (*types.KeyValue, error) {
   415  	if mp, ok := kv.Value.(map[string]types.Value); ok {
   416  		res := make(map[string]string)
   417  		for k, v := range mp {
   418  			res[k] = v.(string)
   419  		}
   420  		return &types.KeyValue{Key: kv.Key, Value: res}, nil
   421  	}
   422  	return nil, errUnknownValType("map[string]string", kv)
   423  }