...

Source file src/github.com/chaos-mesh/chaos-mesh/api/v1alpha1/jvmchaos_webhook.go

Documentation: github.com/chaos-mesh/chaos-mesh/api/v1alpha1

     1  // Copyright 2020 Chaos Mesh Authors.
     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  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package v1alpha1
    15  
    16  import (
    17  	"fmt"
    18  	"strconv"
    19  
    20  	"k8s.io/apimachinery/pkg/runtime"
    21  	"k8s.io/apimachinery/pkg/util/validation/field"
    22  	logf "sigs.k8s.io/controller-runtime/pkg/log"
    23  	"sigs.k8s.io/controller-runtime/pkg/webhook"
    24  )
    25  
    26  // log is for logging in this package.
    27  var jvmchaoslog = logf.Log.WithName("jvmchaos-resource")
    28  
    29  // +kubebuilder:webhook:path=/mutate-chaos-mesh-org-v1alpha1-jvmchaos,mutating=true,failurePolicy=fail,groups=chaos-mesh.org,resources=jvmchaos,verbs=create;update,versions=v1alpha1,name=mjvmchaos.kb.io
    30  
    31  var _ webhook.Defaulter = &JVMChaos{}
    32  
    33  // Default implements webhook.Defaulter so a webhook will be registered for the type
    34  func (in *JVMChaos) Default() {
    35  	jvmchaoslog.Info("default", "name", in.Name)
    36  
    37  	in.Spec.Selector.DefaultNamespace(in.GetNamespace())
    38  }
    39  
    40  // +kubebuilder:webhook:verbs=create;update,path=/validate-chaos-mesh-org-v1alpha1-jvmchaos,mutating=false,failurePolicy=fail,groups=chaos-mesh.org,resources=jvmchaos,versions=v1alpha1,name=vjvmchaos.kb.io
    41  
    42  var _ ChaosValidator = &JVMChaos{}
    43  
    44  // ValidateCreate implements webhook.Validator so a webhook will be registered for the type
    45  func (in *JVMChaos) ValidateCreate() error {
    46  	jvmchaoslog.Info("validate create", "name", in.Name)
    47  
    48  	return in.Validate()
    49  }
    50  
    51  // ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
    52  func (in *JVMChaos) ValidateUpdate(old runtime.Object) error {
    53  	jvmchaoslog.Info("validate update", "name", in.Name)
    54  
    55  	return in.Validate()
    56  }
    57  
    58  // ValidateDelete implements webhook.Validator so a webhook will be registered for the type
    59  func (in *JVMChaos) ValidateDelete() error {
    60  	jvmchaoslog.Info("validate delete", "name", in.Name)
    61  
    62  	// Nothing to do?
    63  	return nil
    64  }
    65  
    66  // Validate validates chaos object
    67  func (in *JVMChaos) Validate() error {
    68  	specField := field.NewPath("spec")
    69  	allErrs := in.ValidateScheduler(specField)
    70  	allErrs = append(allErrs, in.ValidatePodMode(specField)...)
    71  	allErrs = append(allErrs, in.validateJvmChaos(specField)...)
    72  	if len(allErrs) > 0 {
    73  		return fmt.Errorf(allErrs.ToAggregate().Error())
    74  	}
    75  
    76  	return nil
    77  }
    78  
    79  // ValidateScheduler validates the scheduler and duration
    80  func (in *JVMChaos) ValidateScheduler(spec *field.Path) field.ErrorList {
    81  	return ValidateScheduler(in, spec)
    82  }
    83  
    84  // ValidatePodMode validates the value with podmode
    85  func (in *JVMChaos) ValidatePodMode(spec *field.Path) field.ErrorList {
    86  	return ValidatePodMode(in.Spec.Value, in.Spec.Mode, spec.Child("value"))
    87  }
    88  
    89  // SelectSpec returns the selector config for authority validate
    90  func (in *JVMChaos) GetSelectSpec() []SelectSpec {
    91  	return []SelectSpec{&in.Spec}
    92  }
    93  
    94  func (in *JVMChaos) validateJvmChaos(spec *field.Path) field.ErrorList {
    95  	allErrs := field.ErrorList{}
    96  	targetField := spec.Child("target")
    97  	actionField := spec.Child("action")
    98  	flagsField := spec.Child("flags")
    99  	matcherField := spec.Child("matcher")
   100  	if actions, ok := JvmSpec[in.Spec.Target]; ok {
   101  
   102  		if actionPR, actionOK := actions[in.Spec.Action]; actionOK {
   103  			if actionPR.Flags != nil {
   104  				allErrs = append(allErrs, in.validateParameterRules(in.Spec.Flags, actionPR.Flags, flagsField, targetField, actionField)...)
   105  			}
   106  
   107  			if actionPR.Matchers != nil {
   108  				allErrs = append(allErrs, in.validateParameterRules(in.Spec.Matchers, actionPR.Matchers, matcherField, targetField, actionField)...)
   109  			}
   110  
   111  		} else {
   112  			supportActions := make([]JVMChaosAction, 0)
   113  			for k := range actions {
   114  				supportActions = append(supportActions, k)
   115  			}
   116  
   117  			notSupportedError := field.NotSupported(actionField, in.Spec.Action, toString(supportActions))
   118  			errorMsg := fmt.Sprintf("target: %s does not match action: %s, action detail error: %s",
   119  				in.Spec.Target, in.Spec.Action, notSupportedError)
   120  			allErrs = append(allErrs, field.Invalid(targetField, in.Spec.Target, errorMsg))
   121  		}
   122  	} else {
   123  		allErrs = append(allErrs, field.Invalid(targetField, in.Spec.Target, "unknown JVM chaos target"))
   124  	}
   125  
   126  	return allErrs
   127  }
   128  
   129  func toString(actions []JVMChaosAction) []string {
   130  	ret := make([]string, 0)
   131  	for _, act := range actions {
   132  		ret = append(ret, string(act))
   133  	}
   134  	return ret
   135  }
   136  
   137  func (in *JVMChaos) validateParameterRules(parameters map[string]string, rules []ParameterRules, parent *field.Path, target *field.Path, action *field.Path) field.ErrorList {
   138  	allErrs := field.ErrorList{}
   139  	for _, rule := range rules {
   140  		innerField := parent.Child(rule.Name)
   141  
   142  		var value = ""
   143  		var exist = false
   144  		if parameters != nil {
   145  			value, exist = parameters[rule.Name]
   146  		}
   147  		if rule.Required && !exist {
   148  			errorMsg := fmt.Sprintf("with %s: %s, %s: %s", target, in.Spec.Target, action, in.Spec.Action)
   149  			allErrs = append(allErrs, field.Required(innerField, errorMsg))
   150  		}
   151  
   152  		if exist && rule.Required && rule.ParameterType == StringType {
   153  			if len(value) == 0 {
   154  				errorMsg := fmt.Sprintf("%s:%s cannot be empty", innerField, value)
   155  				allErrs = append(allErrs, field.Invalid(innerField, value, errorMsg))
   156  			}
   157  		}
   158  
   159  		if exist && rule.ParameterType == IntType {
   160  			_, err := strconv.Atoi(value)
   161  			if err != nil {
   162  				errorMsg := fmt.Sprintf("%s:%s cannot parse as Int", innerField, value)
   163  				allErrs = append(allErrs, field.Invalid(innerField, value, errorMsg))
   164  			}
   165  		}
   166  
   167  		if exist && rule.ParameterType == BoolType {
   168  			_, err := strconv.ParseBool(value)
   169  			if err != nil {
   170  				errorMsg := fmt.Sprintf("%s:%s cannot parse as boolean", innerField, value)
   171  				allErrs = append(allErrs, field.Invalid(innerField, value, errorMsg))
   172  			}
   173  		}
   174  	}
   175  	return allErrs
   176  }
   177  
   178  // +kubebuilder:object:generate=false
   179  
   180  // JvmSpec from chaosblade-jvm-spec.yaml
   181  // chaosblade-jvm-spec.yaml file generated by
   182  // https://github.com/chaosblade-io/chaosblade-exec-jvm/blob/master/chaosblade-exec-service/src/main/java/com/alibaba/chaosblade/exec/service/build/SpecMain.java
   183  var JvmSpec = map[JVMChaosTarget]map[JVMChaosAction]ActionParameterRules{
   184  	SERVLET: {
   185  		JVMDelayAction: ActionParameterRules{
   186  			Flags: []ParameterRules{
   187  				{Name: "time", ParameterType: IntType, Required: true},
   188  				{Name: "offset", ParameterType: IntType},
   189  			},
   190  			Matchers: []ParameterRules{
   191  				{Name: "effect-count", ParameterType: IntType},
   192  				{Name: "effect-percent", ParameterType: IntType},
   193  				{Name: "method"},
   194  				{Name: "querystring"},
   195  				{Name: "requestpath"},
   196  			},
   197  		},
   198  		JVMExceptionAction: ActionParameterRules{
   199  			Flags: []ParameterRules{
   200  				{Name: "exception", Required: true},
   201  				{Name: "exception-message"},
   202  			},
   203  			Matchers: []ParameterRules{
   204  				{Name: "effect-count", ParameterType: IntType},
   205  				{Name: "effect-percent", ParameterType: IntType},
   206  				{Name: "method"},
   207  				{Name: "querystring"},
   208  				{Name: "requestpath"},
   209  			},
   210  		},
   211  	},
   212  	PSQL: {
   213  		JVMDelayAction: ActionParameterRules{
   214  			Flags: []ParameterRules{
   215  				{Name: "time", ParameterType: IntType, Required: true},
   216  				{Name: "offset", ParameterType: IntType},
   217  			},
   218  			Matchers: []ParameterRules{
   219  				{Name: "effect-count", ParameterType: IntType},
   220  				{Name: "effect-percent", ParameterType: IntType},
   221  				{Name: "sqltype"},
   222  				{Name: "database"},
   223  				{Name: "port", ParameterType: IntType},
   224  				{Name: "host"},
   225  				{Name: "table"},
   226  			},
   227  		},
   228  		JVMExceptionAction: ActionParameterRules{
   229  			Flags: []ParameterRules{
   230  				{Name: "exception", Required: true},
   231  				{Name: "exception-message"},
   232  			},
   233  			Matchers: []ParameterRules{
   234  				{Name: "effect-count", ParameterType: IntType},
   235  				{Name: "effect-percent", ParameterType: IntType},
   236  				{Name: "sqltype"},
   237  				{Name: "database"},
   238  				{Name: "port", ParameterType: IntType},
   239  				{Name: "host"},
   240  				{Name: "table"},
   241  			},
   242  		},
   243  	},
   244  	MYSQL: {
   245  		JVMDelayAction: ActionParameterRules{
   246  			Flags: []ParameterRules{
   247  				{Name: "time", ParameterType: IntType, Required: true},
   248  				{Name: "offset", ParameterType: IntType},
   249  			},
   250  			Matchers: []ParameterRules{
   251  				{Name: "effect-count", ParameterType: IntType},
   252  				{Name: "effect-percent", ParameterType: IntType},
   253  				{Name: "sqltype"},
   254  				{Name: "database"},
   255  				{Name: "port", ParameterType: IntType},
   256  				{Name: "host"},
   257  				{Name: "table"},
   258  			},
   259  		},
   260  		JVMExceptionAction: ActionParameterRules{
   261  			Flags: []ParameterRules{
   262  				{Name: "exception", Required: true},
   263  				{Name: "exception-message"},
   264  			},
   265  			Matchers: []ParameterRules{
   266  				{Name: "effect-count", ParameterType: IntType},
   267  				{Name: "effect-percent", ParameterType: IntType},
   268  				{Name: "sqltype"},
   269  				{Name: "database"},
   270  				{Name: "port", ParameterType: IntType},
   271  				{Name: "host"},
   272  				{Name: "table"},
   273  			},
   274  		},
   275  	},
   276  	JEDIS: {
   277  		JVMDelayAction: ActionParameterRules{
   278  			Flags: []ParameterRules{
   279  				{Name: "time", ParameterType: IntType, Required: true},
   280  				{Name: "offset", ParameterType: IntType},
   281  			},
   282  			Matchers: []ParameterRules{
   283  				{Name: "effect-count", ParameterType: IntType},
   284  				{Name: "effect-percent", ParameterType: IntType},
   285  				{Name: "cmd"},
   286  				{Name: "key"},
   287  			},
   288  		},
   289  		JVMExceptionAction: ActionParameterRules{
   290  			Flags: []ParameterRules{
   291  				{Name: "exception", Required: true},
   292  				{Name: "exception-message"},
   293  			},
   294  			Matchers: []ParameterRules{
   295  				{Name: "effect-count", ParameterType: IntType},
   296  				{Name: "effect-percent", ParameterType: IntType},
   297  				{Name: "cmd"},
   298  				{Name: "key"},
   299  			},
   300  		},
   301  	},
   302  	HTTP: {
   303  		JVMDelayAction: ActionParameterRules{
   304  			Flags: []ParameterRules{
   305  				{Name: "time", ParameterType: IntType, Required: true},
   306  				{Name: "offset", ParameterType: IntType},
   307  			},
   308  			Matchers: []ParameterRules{
   309  				{Name: "effect-count", ParameterType: IntType},
   310  				{Name: "effect-percent", ParameterType: IntType},
   311  				{Name: "httpclient4", ParameterType: BoolType},
   312  				{Name: "rest", ParameterType: BoolType},
   313  				{Name: "httpclient3", ParameterType: BoolType},
   314  				{Name: "okhttp3", ParameterType: BoolType},
   315  				{Name: "uri", Required: true},
   316  			},
   317  		},
   318  		JVMExceptionAction: ActionParameterRules{
   319  			Flags: []ParameterRules{
   320  				{Name: "exception", Required: true},
   321  				{Name: "exception-message"},
   322  			},
   323  			Matchers: []ParameterRules{
   324  				{Name: "effect-count", ParameterType: IntType},
   325  				{Name: "effect-percent", ParameterType: IntType},
   326  				{Name: "httpclient4", ParameterType: BoolType},
   327  				{Name: "rest", ParameterType: BoolType},
   328  				{Name: "httpclient3", ParameterType: BoolType},
   329  				{Name: "okhttp3", ParameterType: BoolType},
   330  				{Name: "uri", Required: true},
   331  			},
   332  		},
   333  	},
   334  	RABBITMQ: {
   335  		JVMDelayAction: ActionParameterRules{
   336  			Flags: []ParameterRules{
   337  				{Name: "time", ParameterType: IntType, Required: true},
   338  				{Name: "offset", ParameterType: IntType},
   339  			},
   340  			Matchers: []ParameterRules{
   341  				{Name: "effect-count", ParameterType: IntType},
   342  				{Name: "effect-percent", ParameterType: IntType},
   343  				{Name: "routingkey"},
   344  				{Name: "producer", ParameterType: BoolType},
   345  				{Name: "topic"},
   346  				{Name: "exchange"},
   347  				{Name: "consumer", ParameterType: BoolType},
   348  			},
   349  		},
   350  		JVMExceptionAction: ActionParameterRules{
   351  			Flags: []ParameterRules{
   352  				{Name: "exception", Required: true},
   353  				{Name: "exception-message"},
   354  			},
   355  			Matchers: []ParameterRules{
   356  				{Name: "effect-count", ParameterType: IntType},
   357  				{Name: "effect-percent", ParameterType: IntType},
   358  				{Name: "routingkey"},
   359  				{Name: "producer", ParameterType: BoolType},
   360  				{Name: "topic"},
   361  				{Name: "exchange"},
   362  				{Name: "consumer", ParameterType: BoolType},
   363  			},
   364  		},
   365  	},
   366  	TARS: {
   367  		JVMDelayAction: ActionParameterRules{
   368  			Flags: []ParameterRules{
   369  				{Name: "time", ParameterType: IntType, Required: true},
   370  				{Name: "offset", ParameterType: IntType},
   371  			},
   372  			Matchers: []ParameterRules{
   373  				{Name: "effect-count", ParameterType: IntType},
   374  				{Name: "effect-percent", ParameterType: IntType},
   375  				{Name: "servant", ParameterType: BoolType},
   376  				{Name: "functionname"},
   377  				{Name: "client", ParameterType: BoolType},
   378  				{Name: "servantname", Required: true},
   379  			},
   380  		},
   381  		JVMExceptionAction: ActionParameterRules{
   382  			Flags: []ParameterRules{
   383  				{Name: "exception", Required: true},
   384  				{Name: "exception-message"},
   385  			},
   386  			Matchers: []ParameterRules{
   387  				{Name: "effect-count", ParameterType: IntType},
   388  				{Name: "effect-percent", ParameterType: IntType},
   389  				{Name: "servant", ParameterType: BoolType},
   390  				{Name: "functionname"},
   391  				{Name: "client", ParameterType: BoolType},
   392  				{Name: "servantname", Required: true},
   393  			},
   394  		},
   395  	},
   396  	DUBBO: {
   397  		JVMDelayAction: ActionParameterRules{
   398  			Flags: []ParameterRules{
   399  				{Name: "time", ParameterType: IntType, Required: true},
   400  				{Name: "offset", ParameterType: IntType},
   401  			},
   402  			Matchers: []ParameterRules{
   403  				{Name: "effect-count", ParameterType: IntType},
   404  				{Name: "effect-percent", ParameterType: IntType},
   405  				{Name: "appname"},
   406  				{Name: "provider", ParameterType: BoolType},
   407  				{Name: "service"},
   408  				{Name: "version"},
   409  				{Name: "consumer", ParameterType: BoolType},
   410  				{Name: "methodname"},
   411  				{Name: "group"},
   412  			},
   413  		},
   414  		JVMExceptionAction: ActionParameterRules{
   415  			Flags: []ParameterRules{
   416  				{Name: "exception", Required: true},
   417  				{Name: "exception-message"},
   418  			},
   419  			Matchers: []ParameterRules{
   420  				{Name: "effect-count", ParameterType: IntType},
   421  				{Name: "effect-percent", ParameterType: IntType},
   422  				{Name: "appname"},
   423  				{Name: "provider", ParameterType: BoolType},
   424  				{Name: "service"},
   425  				{Name: "version"},
   426  				{Name: "consumer", ParameterType: BoolType},
   427  				{Name: "methodname"},
   428  				{Name: "group"},
   429  			},
   430  		},
   431  		JVMThreadPoolFullAction: ActionParameterRules{
   432  			Matchers: []ParameterRules{
   433  				{Name: "effect-count", ParameterType: IntType},
   434  				{Name: "effect-percent", ParameterType: IntType},
   435  				{Name: "provider", ParameterType: BoolType},
   436  			},
   437  		},
   438  	},
   439  	JVM: {
   440  		JVMDelayAction: ActionParameterRules{
   441  			Flags: []ParameterRules{
   442  				{Name: "time", ParameterType: IntType, Required: true},
   443  				{Name: "offset", ParameterType: IntType},
   444  			},
   445  			Matchers: []ParameterRules{
   446  				{Name: "effect-count", ParameterType: IntType},
   447  				{Name: "effect-percent", ParameterType: IntType},
   448  				{Name: "classname", Required: true},
   449  				{Name: "after", ParameterType: BoolType},
   450  				{Name: "methodname", Required: true},
   451  			},
   452  		},
   453  		JVMExceptionAction: ActionParameterRules{
   454  			Flags: []ParameterRules{
   455  				{Name: "exception", Required: true},
   456  				{Name: "exception-message"},
   457  			},
   458  			Matchers: []ParameterRules{
   459  				{Name: "effect-count", ParameterType: IntType},
   460  				{Name: "effect-percent", ParameterType: IntType},
   461  				{Name: "classname", Required: true},
   462  				{Name: "after", ParameterType: BoolType},
   463  				{Name: "methodname", Required: true},
   464  			},
   465  		},
   466  		JVMCodeCacheFillingAction: ActionParameterRules{},
   467  		JVMCpuFullloadAction: ActionParameterRules{
   468  			Flags: []ParameterRules{
   469  				{Name: "cpu-count", ParameterType: IntType},
   470  			},
   471  		},
   472  		JVMThrowDeclaredExceptionAction: ActionParameterRules{
   473  			Matchers: []ParameterRules{
   474  				{Name: "effect-count", ParameterType: IntType},
   475  				{Name: "effect-percent", ParameterType: IntType},
   476  				{Name: "classname", Required: true},
   477  				{Name: "after", ParameterType: BoolType},
   478  				{Name: "methodname", Required: true},
   479  			},
   480  		},
   481  		JVMReturnAction: ActionParameterRules{
   482  			Flags: []ParameterRules{
   483  				{Name: "value", Required: true},
   484  			},
   485  			Matchers: []ParameterRules{
   486  				{Name: "effect-count", ParameterType: IntType},
   487  				{Name: "effect-percent", ParameterType: IntType},
   488  				{Name: "classname", Required: true},
   489  				{Name: "after", ParameterType: BoolType},
   490  				{Name: "methodname", Required: true},
   491  			},
   492  		},
   493  		JVMScriptAction: ActionParameterRules{
   494  			Flags: []ParameterRules{
   495  				{Name: "script-file"},
   496  				{Name: "script-type"},
   497  				{Name: "script-content"},
   498  				{Name: "script-name"},
   499  				{Name: "external-jar"},
   500  				{Name: "external-jar-path"},
   501  			},
   502  			Matchers: []ParameterRules{
   503  				{Name: "effect-count", ParameterType: IntType},
   504  				{Name: "effect-percent", ParameterType: IntType},
   505  				{Name: "classname", Required: true},
   506  				{Name: "after", ParameterType: BoolType},
   507  				{Name: "methodname", Required: true},
   508  			},
   509  		},
   510  		JVMOOMAction: ActionParameterRules{
   511  			Flags: []ParameterRules{
   512  				{Name: "area", Required: true},
   513  				{Name: "wild-mode", ParameterType: BoolType},
   514  				{Name: "interval", ParameterType: IntType},
   515  				{Name: "block", ParameterType: IntType},
   516  			},
   517  		},
   518  	},
   519  	DRUID: {
   520  		JVMConnectionPoolFullAction: ActionParameterRules{
   521  			Matchers: []ParameterRules{
   522  				{Name: "effect-count", ParameterType: IntType},
   523  				{Name: "effect-percent", ParameterType: IntType},
   524  			},
   525  		},
   526  	},
   527  	REDISSON: {
   528  		JVMDelayAction: ActionParameterRules{
   529  			Flags: []ParameterRules{
   530  				{Name: "time", ParameterType: IntType, Required: true},
   531  				{Name: "offset", ParameterType: IntType},
   532  			},
   533  			Matchers: []ParameterRules{
   534  				{Name: "effect-count", ParameterType: IntType},
   535  				{Name: "effect-percent", ParameterType: IntType},
   536  				{Name: "cmd"},
   537  				{Name: "key"},
   538  			},
   539  		},
   540  		JVMExceptionAction: ActionParameterRules{
   541  			Flags: []ParameterRules{
   542  				{Name: "exception", Required: true},
   543  				{Name: "exception-message"},
   544  			},
   545  			Matchers: []ParameterRules{
   546  				{Name: "effect-count", ParameterType: IntType},
   547  				{Name: "effect-percent", ParameterType: IntType},
   548  				{Name: "cmd"},
   549  				{Name: "key"},
   550  			},
   551  		},
   552  	},
   553  	ROCKETMQ: {
   554  		JVMDelayAction: ActionParameterRules{
   555  			Flags: []ParameterRules{
   556  				{Name: "time", ParameterType: IntType, Required: true},
   557  				{Name: "offset", ParameterType: IntType},
   558  			},
   559  			Matchers: []ParameterRules{
   560  				{Name: "effect-count", ParameterType: IntType},
   561  				{Name: "effect-percent", ParameterType: IntType},
   562  				{Name: "producerGroup"},
   563  				{Name: "producer"},
   564  				{Name: "topic", Required: true},
   565  				{Name: "consumerGroup"},
   566  			},
   567  		},
   568  		JVMExceptionAction: ActionParameterRules{
   569  			Flags: []ParameterRules{
   570  				{Name: "exception", Required: true},
   571  				{Name: "exception-message"},
   572  			},
   573  			Matchers: []ParameterRules{
   574  				{Name: "effect-count", ParameterType: IntType},
   575  				{Name: "effect-percent", ParameterType: IntType},
   576  				{Name: "producerGroup"},
   577  				{Name: "producer"},
   578  				{Name: "topic", Required: true},
   579  				{Name: "consumerGroup"},
   580  			},
   581  		},
   582  	},
   583  	MONGODB: {
   584  		JVMDelayAction: ActionParameterRules{
   585  			Flags: []ParameterRules{
   586  				{Name: "time", ParameterType: IntType, Required: true},
   587  				{Name: "offset", ParameterType: IntType},
   588  			},
   589  			Matchers: []ParameterRules{
   590  				{Name: "effect-count", ParameterType: IntType},
   591  				{Name: "effect-percent", ParameterType: IntType},
   592  				{Name: "sqltype"},
   593  				{Name: "database"},
   594  				{Name: "false"},
   595  			},
   596  		},
   597  		JVMExceptionAction: ActionParameterRules{
   598  			Flags: []ParameterRules{
   599  				{Name: "exception", Required: true},
   600  				{Name: "exception-message"},
   601  			},
   602  			Matchers: []ParameterRules{
   603  				{Name: "effect-count", ParameterType: IntType},
   604  				{Name: "effect-percent", ParameterType: IntType},
   605  				{Name: "sqltype"},
   606  				{Name: "database"},
   607  				{Name: "false"},
   608  			},
   609  		},
   610  	},
   611  }
   612  
   613  // ActionParameterRules defines the parameter validation rules for action
   614  type ActionParameterRules struct {
   615  	// Flags represents the parameter validation rules for flags
   616  	Flags []ParameterRules
   617  
   618  	// Matchers represents the parameter validation rules for Matcher
   619  	Matchers []ParameterRules
   620  }
   621  
   622  // ParameterType defines the parameter type
   623  type ParameterType string
   624  
   625  const (
   626  	// IntType a int type parameter
   627  	IntType ParameterType = "int"
   628  
   629  	// BoolType a boolean type parameter
   630  	BoolType ParameterType = "bool"
   631  
   632  	// StringType a string type parameter
   633  	StringType ParameterType = "string"
   634  )
   635  
   636  // ParameterRules defines the parameter validation rules
   637  type ParameterRules struct {
   638  	// Name represents the name of parameter
   639  	Name string
   640  
   641  	// ParameterType represents the parameter type
   642  	ParameterType ParameterType
   643  
   644  	// Required defines whether it is a required parameter
   645  	Required bool
   646  }
   647