6565 ("timeStarted" , Resource ),
6666 ("solutionVersionArn" , SolutionVersion ),
6767)
68-
68+ RESOURCE_TYPES = [
69+ "datasetGroup" ,
70+ "datasetImport" ,
71+ "dataset" ,
72+ "eventTracker" ,
73+ "solution" ,
74+ "solutionVersion" ,
75+ "filter" ,
76+ "recommender" ,
77+ "campaign" ,
78+ "batchJob" ,
79+ "segmentJob"
80+ ]
6981
7082def get_duplicates (items ):
7183 if isinstance (items , str ):
@@ -714,71 +726,60 @@ def _validate_filters(self, path="filters[].serviceConfig"):
714726 self ._fill_default_vals ("filter" , _filter )
715727
716728 def _validate_type (self , var , typ , err : str ):
717- validates = isinstance (var , typ )
729+ validates = isinstance (var , typ ) and var is not None
730+
718731 if not validates :
719732 self ._configuration_errors .append (err )
733+
720734 return validates
721735
722- def _validate_solutions (self , path = "solutions[]" ):
736+ def _validate_solutions (self , path = "solutions[]" ):
723737 solutions = jmespath .search (path , self .config_dict ) or {}
724- for idx , _solution in enumerate (solutions ):
725- campaigns = _solution .get ("campaigns" , [])
726- if self ._validate_type (campaigns , list , f"solutions[{ idx } ].campaigns must be a list" ):
727- self ._validate_campaigns (f"solutions[{ idx } ].campaigns" , campaigns )
728-
729- batch_inference_jobs = _solution .get ("batchInferenceJobs" , [])
730- if batch_inference_jobs and self ._validate_type (
731- batch_inference_jobs ,
732- list ,
733- f"solutions[{ idx } ].batchInferenceJobs must be a list" ,
734- ):
735- self ._validate_batch_inference_jobs (
736- path = f"solutions[{ idx } ].batchInferenceJobs" ,
737- solution_name = _solution .get ("serviceConfig" , {}).get ("name" , "" ),
738- batch_inference_jobs = batch_inference_jobs ,
739- )
740738
741- batch_segment_jobs = _solution .get ("batchSegmentJobs" , [])
742- if batch_segment_jobs and self ._validate_type (
743- batch_segment_jobs ,
744- list ,
745- f"solutions[{ idx } ].batchSegmentJobs must be a list" ,
746- ):
747- self ._validate_batch_segment_jobs (
748- path = f"solutions[{ idx } ].batchSegmentJobs" ,
749- solution_name = _solution .get ("serviceConfig" , {}).get ("name" , "" ),
750- batch_segment_jobs = batch_segment_jobs ,
751- )
739+ for idx , _solution in enumerate (solutions ):
740+ # Validate campaigns and batch jobs
741+ self ._validate_campaigns (f"solutions[{ idx } ].campaigns" , _solution .get ("campaigns" , []))
742+ self ._validate_batch_inference_jobs (
743+ path = f"solutions[{ idx } ].batchInferenceJobs" ,
744+ solution_name = _solution .get ("serviceConfig" , {}).get ("name" , "" ),
745+ batch_inference_jobs = _solution .get ("batchInferenceJobs" , []),
746+ )
747+ self ._validate_batch_segment_jobs (
748+ path = f"solutions[{ idx } ].batchSegmentJobs" ,
749+ solution_name = _solution .get ("serviceConfig" , {}).get ("name" , "" ),
750+ batch_segment_jobs = _solution .get ("batchSegmentJobs" , []),
751+ )
752752
753- _solution = _solution .get ("serviceConfig" )
753+ # Validate service configuration
754+ _service_config = _solution .get ("serviceConfig" )
754755
755- if not self ._validate_type (_solution , dict , f"solutions[{ idx } ].serviceConfig must be an object" ):
756+ if not self ._validate_type (_service_config , dict , f"solutions[{ idx } ].serviceConfig must be an object" ):
756757 continue
757758
758759 # `performAutoML` is currently returned from InputValidator.validate() as a valid field
759760 # Once the botocore Stubber is updated to not have this param anymore in `create_solution` call,
760761 # this check can be deleted.
761- if "performAutoML" in _solution :
762- del _solution ["performAutoML" ]
762+ if "performAutoML" in _service_config :
763+ del _service_config ["performAutoML" ]
763764 logger .error (
764765 "performAutoML is not a valid configuration parameter - proceeding to create the "
765766 "solution without this feature. For more details, refer to the Maintaining Personalized Experiences "
766767 "Github project's README.md file."
767768 )
768769
769- _solution ["datasetGroupArn" ] = DatasetGroup ().arn ("validation" )
770- if "solutionVersion" in _solution :
771- # To pass solution through InputValidator
772- solution_version_config = _solution ["solutionVersion" ]
773- del _solution ["solutionVersion" ]
774- self ._validate_resource (Solution (), _solution )
775- _solution ["solutionVersion" ] = solution_version_config
770+ _service_config ["datasetGroupArn" ] = DatasetGroup ().arn ("validation" )
776771
772+ if "solutionVersion" in _service_config :
773+ # To pass solution through InputValidator
774+ solution_version_config = _service_config ["solutionVersion" ]
775+ del _service_config ["solutionVersion" ]
776+ self ._validate_resource (Solution (), _service_config )
777+ _service_config ["solutionVersion" ] = solution_version_config
777778 else :
778- self ._validate_resource (Solution (), _solution )
779+ self ._validate_resource (Solution (), _service_config )
779780
780- self ._fill_default_vals ("solution" , _solution )
781- self ._validate_solution_version (_solution )
781+ self ._fill_default_vals ("solution" , _service_config )
782+ self ._validate_solution_version (_service_config )
782783
783784 def _validate_solution_version (self , solution_config ):
784785 allowed_sol_version_keys = ["trainingMode" , "tags" ]
@@ -819,6 +820,8 @@ def _validate_solution_update(self):
819820 )
820821
821822 def _validate_campaigns (self , path , campaigns : List [Dict ]):
823+ self ._validate_type (campaigns , list , f"{ path } must be a list" )
824+
822825 for idx , campaign_config in enumerate (campaigns ):
823826 current_path = f"{ path } .campaigns[{ idx } ]"
824827
@@ -832,6 +835,12 @@ def _validate_campaigns(self, path, campaigns: List[Dict]):
832835 self ._fill_default_vals ("campaign" , campaign )
833836
834837 def _validate_batch_inference_jobs (self , path , solution_name , batch_inference_jobs : List [Dict ]):
838+ self ._validate_type (
839+ batch_inference_jobs ,
840+ list ,
841+ f"solutions[{ path } must be a list" ,
842+ )
843+
835844 for idx , batch_job_config in enumerate (batch_inference_jobs ):
836845 current_path = f"{ path } .batchInferenceJobs[{ idx } ]"
837846
@@ -860,6 +869,12 @@ def _validate_batch_inference_jobs(self, path, solution_name, batch_inference_jo
860869 self ._fill_default_vals ("batchJob" , batch_job )
861870
862871 def _validate_batch_segment_jobs (self , path , solution_name , batch_segment_jobs : List [Dict ]):
872+ self ._validate_type (
873+ batch_segment_jobs ,
874+ list ,
875+ f"solutions[{ path } must be a list" ,
876+ )
877+
863878 for idx , batch_job_config in enumerate (batch_segment_jobs ):
864879 current_path = f"{ path } .batchSegmentJobs[{ idx } ]"
865880
@@ -1108,42 +1123,23 @@ def _validate_naming(self):
11081123 self ._validate_no_duplicates (name = "campaign names" , path = "solutions[].campaigns[].serviceConfig.name" )
11091124 self ._validate_no_duplicates (name = "solution names" , path = "solutions[].serviceConfig.name" )
11101125
1111- def _fill_default_vals (self , resource_type , resource_dict ):
1112- """Insert default values for tags and other fields whenever not supplied"""
1113-
1114- if (
1115- resource_type
1116- in [
1117- "datasetGroup" ,
1118- "datasetImport" ,
1119- "dataset" ,
1120- "eventTracker" ,
1121- "solution" ,
1122- "solutionVersion" ,
1123- "filter" ,
1124- "recommender" ,
1125- "campaign" ,
1126- "batchJob" ,
1127- "segmentJob" ,
1128- ]
1129- and "tags" not in resource_dict
1130- ):
1126+ def _fill_resource_dict_tags (self , resource_type , resource_dict ):
1127+ if resource_type in RESOURCE_TYPES and "tags" not in resource_dict :
11311128 if self .pass_root_tags :
11321129 resource_dict ["tags" ] = self .config_dict ["tags" ]
11331130 else :
11341131 resource_dict ["tags" ] = []
11351132
1133+ def _fill_default_vals (self , resource_type , resource_dict ):
1134+ """Insert default values for tags and other fields whenever not supplied"""
1135+ self ._fill_resource_dict_tags (resource_type , resource_dict )
1136+
11361137 if resource_type == "datasetImport" :
11371138 if "importMode" not in resource_dict :
11381139 resource_dict ["importMode" ] = "FULL"
1140+
11391141 if "publishAttributionMetricsToS3" not in resource_dict :
11401142 resource_dict ["publishAttributionMetricsToS3" ] = False
11411143
1142- if resource_type == "solutionVersion" :
1143- if "tags" not in resource_dict :
1144- if self .pass_root_tags :
1145- resource_dict ["tags" ] = self .config_dict ["tags" ]
1146- else :
1147- resource_dict ["tags" ] = []
1148- if "trainingMode" not in resource_dict :
1149- resource_dict ["trainingMode" ] = "FULL"
1144+ if resource_type == "solutionVersion" and "trainingMode" not in resource_dict :
1145+ resource_dict ["trainingMode" ] = "FULL"
0 commit comments